1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef UI_EVENTS_GESTURE_DETECTION_VELOCITY_TRACKER_H_ 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define UI_EVENTS_GESTURE_DETECTION_VELOCITY_TRACKER_H_ 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/basictypes.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/time/time.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/events/gesture_detection/bitset_32.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ui { 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class MotionEvent; 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class VelocityTrackerStrategy; 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct Estimator; 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct Position; 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Port of VelocityTracker from Android 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// * platform/frameworks/native/include/input/VelocityTracker.h 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// * Change-Id: I4983db61b53e28479fc90d9211fafff68f7f49a6 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// * Please update the Change-Id as upstream Android changes are pulled. 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class VelocityTracker { 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) enum { 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The maximum number of pointers to use when computing the velocity. 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Note that the supplied MotionEvent may expose more than 16 pointers, but 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // at most |MAX_POINTERS| will be used. 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MAX_POINTERS = 16, 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) enum Strategy { 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 1st order least squares. Quality: POOR. 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Frequently underfits the touch data especially when the finger 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // accelerates or changes direction. Often underestimates velocity. The 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // direction is overly influenced by historical touch points. 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LSQ1, 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 2nd order least squares. Quality: VERY GOOD. 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Pretty much ideal, but can be confused by certain kinds of touch data, 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // particularly if the panel has a tendency to generate delayed, 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // duplicate or jittery touch coordinates when the finger is released. 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LSQ2, 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 3rd order least squares. Quality: UNUSABLE. 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Frequently overfits the touch data yielding wildly divergent estimates 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // of the velocity when the finger is released. 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LSQ3, 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 2nd order weighted least squares, delta weighting. 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Quality: EXPERIMENTAL 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WLSQ2_DELTA, 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 2nd order weighted least squares, central weighting. 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Quality: EXPERIMENTAL 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WLSQ2_CENTRAL, 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 2nd order weighted least squares, recent weighting. 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Quality: EXPERIMENTAL 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WLSQ2_RECENT, 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 1st order integrating filter. Quality: GOOD. 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Not as good as 'lsq2' because it cannot estimate acceleration but it is 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // more tolerant of errors. Like 'lsq1', this strategy tends to 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // underestimate 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the velocity of a fling but this strategy tends to respond to changes in 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // direction more quickly and accurately. 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) INT1, 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 2nd order integrating filter. Quality: EXPERIMENTAL. 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // For comparison purposes only. Unlike 'int1' this strategy can compensate 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // for acceleration but it typically overestimates the effect. 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) INT2, 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) STRATEGY_MAX = INT2, 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The default velocity tracker strategy. 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Although other strategies are available for testing and comparison 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // purposes, this is the strategy that applications will actually use. Be 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // very careful when adjusting the default strategy because it can 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // dramatically affect (often in a bad way) the user experience. 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) STRATEGY_DEFAULT = LSQ2, 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Creates a velocity tracker using the default strategy for the platform. 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VelocityTracker(); 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Creates a velocity tracker using the specified strategy. 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If strategy is NULL, uses the default strategy for the platform. 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) explicit VelocityTracker(Strategy strategy); 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ~VelocityTracker(); 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Resets the velocity tracker state. 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Clear(); 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Adds movement information for all pointers in a MotionEvent, including 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // historical samples. 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void AddMovement(const MotionEvent& event); 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Gets the velocity of the specified pointer id in position units per second. 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Returns false and sets the velocity components to zero if there is 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // insufficient movement information for the pointer. 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool GetVelocity(uint32_t id, float* outVx, float* outVy) const; 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Gets the active pointer id, or -1 if none. 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) inline int32_t GetActivePointerId() const { return active_pointer_id_; } 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Gets a bitset containing all pointer ids from the most recent movement. 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) inline BitSet32 GetCurrentPointerIdBits() const { 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return current_pointer_id_bits_; 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Resets the velocity tracker state for specific pointers. 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Call this method when some pointers have changed and may be reusing 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // an id that was assigned to a different pointer earlier. 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void ClearPointers(BitSet32 id_bits); 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Adds movement information for a set of pointers. 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The id_bits bitfield specifies the pointer ids of the pointers whose 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // positions 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // are included in the movement. 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The positions array contains position information for each pointer in order 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // by 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // increasing id. Its size should be equal to the number of one bits in 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // id_bits. 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void AddMovement(const base::TimeTicks& event_time, 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BitSet32 id_bits, 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const Position* positions); 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Gets an estimator for the recent movements of the specified pointer id. 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Returns false and clears the estimator if there is no information available 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // about the pointer. 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool GetEstimator(uint32_t id, Estimator* out_estimator) const; 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeTicks last_event_time_; 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BitSet32 current_pointer_id_bits_; 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int32_t active_pointer_id_; 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<VelocityTrackerStrategy> strategy_; 144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DISALLOW_COPY_AND_ASSIGN(VelocityTracker); 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace ui 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif // UI_EVENTS_GESTURE_DETECTION_VELOCITY_TRACKER_H_ 151