Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: Source/WebCore/platform/TouchpadFlingPlatformGestureCurve.cpp

Issue 9969140: Merge 113095 - [chromium] Switch touchpad fling curve physics to absolute (not scaled) curve. (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1084/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 15 matching lines...) Expand all
26 26
27 #include "TouchpadFlingPlatformGestureCurve.h" 27 #include "TouchpadFlingPlatformGestureCurve.h"
28 28
29 #include "PlatformGestureCurveTarget.h" 29 #include "PlatformGestureCurveTarget.h"
30 #include <math.h> 30 #include <math.h>
31 31
32 namespace WebCore { 32 namespace WebCore {
33 33
34 using namespace std; 34 using namespace std;
35 35
36 // This curve implementation is based on the notion of a single, absolute curve, which starts at
37 // a large velocity and smoothly decreases to zero. For a given input velocity, we find where on
38 // the curve this velocity occurs, and start the animation at this point---denot ed by (m_timeOffset,
39 // m_positionOffset).
40 //
41 // This has the effect of automatically determining an animation duration that s cales with input
42 // velocity, as faster initial velocities start earlier on the curve and thus ta ke longer to reach the end.
43 // No complicated time scaling is required.
44 //
45 // Since the starting velocity is implicitly determined by our starting point, w e only store the
46 // relative magnitude and direction of both initial x- and y-velocities, and use this to scale the
47 // computed displacement at any point in time. This guarantees that fling trajec tories are straight
48 // lines when viewed in x-y space. Initial velocities that lie outside the max v elocity are constrained
49 // to start at zero (and thus are implicitly scaled).
50 //
51 // The curve is modelled as a 4th order polynomial, starting at t = 0, and endin g at t = m_curveDuration.
52 // Attempts to generate position/velocity estimates outside this range are undef ined.
53
54 const int TouchpadFlingPlatformGestureCurve::m_maxSearchIterations = 40;
55
36 PassOwnPtr<PlatformGestureCurve> TouchpadFlingPlatformGestureCurve::create(const FloatPoint& velocity, IntPoint cumulativeScroll) 56 PassOwnPtr<PlatformGestureCurve> TouchpadFlingPlatformGestureCurve::create(const FloatPoint& velocity, IntPoint cumulativeScroll)
37 { 57 {
38 return create(velocity, 3, FloatPoint(0.3333, 0.6666), FloatPoint(0.6666, 1) , cumulativeScroll); 58 // The default parameters listed below are a matched set, and should not be changed independently of one another.
59 return create(velocity, 1.5395e+01, 2.0466e+04, -2.9899e+04, 2.0577e+04, -5. 4966e+03, 1.128445, cumulativeScroll);
39 } 60 }
40 61
41 PassOwnPtr<PlatformGestureCurve> TouchpadFlingPlatformGestureCurve::create(const FloatPoint& velocity, const float unitTimeScaleLog10, const FloatPoint& bezierP 1, const FloatPoint& bezierP2, IntPoint cumulativeScroll) 62 PassOwnPtr<PlatformGestureCurve> TouchpadFlingPlatformGestureCurve::create(const FloatPoint& velocity, float p0, float p1, float p2, float p3, float p4, float c urveDuration, IntPoint cumulativeScroll)
42 { 63 {
43 return adoptPtr(new TouchpadFlingPlatformGestureCurve(velocity, unitTimeScal eLog10, bezierP1, bezierP2, cumulativeScroll)); 64 return adoptPtr(new TouchpadFlingPlatformGestureCurve(velocity, p0, p1, p2, p3, p4, curveDuration, cumulativeScroll));
44 } 65 }
45 66
46 TouchpadFlingPlatformGestureCurve::TouchpadFlingPlatformGestureCurve(const Float Point& velocity, const float unitTimeScaleLog10, const FloatPoint& bezierP1, con st FloatPoint& bezierP2, const IntPoint& cumulativeScroll) 67 inline double position(double t, float* p)
47 : m_velocity(velocity)
48 , m_timeScaleFactor(unitTimeScaleLog10 / log10(max(10.f, max(fabs(velocity.x ()), fabs(velocity.y())))))
49 , m_cumulativeScroll(cumulativeScroll)
50 , m_flingBezier(bezierP1.x(), bezierP1.y(), bezierP2.x(), bezierP2.y())
51 { 68 {
52 ASSERT(velocity != FloatPoint::zero()); 69 return p[0] + t * (p[1] + t * (p[2] + t * (p[3] + t * p[4])));
70 }
71
72 inline double velocity(double t, float* p)
73 {
74 return p[1] + t * (2 * p[2] + t * (3 * p[3] + t * 4 * p[4]));
75 }
76
77 TouchpadFlingPlatformGestureCurve::TouchpadFlingPlatformGestureCurve(const Float Point& initialVelocity, float p0, float p1, float p2, float p3, float p4, float curveDuration, const IntPoint& cumulativeScroll)
78 : m_cumulativeScroll(cumulativeScroll)
79 , m_curveDuration(curveDuration)
80 {
81 ASSERT(initialVelocity != FloatPoint::zero());
82 m_coeffs[0] = p0;
83 m_coeffs[1] = p1;
84 m_coeffs[2] = p2;
85 m_coeffs[3] = p3;
86 m_coeffs[4] = p4;
87
88 float maxInitialVelocity = max(fabs(initialVelocity.x()), fabs(initialVeloci ty.y()));
89
90 // Force maxInitialVelocity to lie in the range v(0) to v(curveDuration), an d assume that
91 // the curve parameters define a monotonically decreasing velocity, or else bisection search may
92 // fail.
93 if (maxInitialVelocity > m_coeffs[1])
94 maxInitialVelocity = m_coeffs[1];
95
96 if (maxInitialVelocity < velocity(m_curveDuration, m_coeffs))
97 maxInitialVelocity = velocity(m_curveDuration, m_coeffs);
98
99 // We keep track of relative magnitudes and directions of the velocity/displ acement components here.
100 m_displacementRatio = FloatPoint(initialVelocity.x() / maxInitialVelocity, i nitialVelocity.y() / maxInitialVelocity);
101
102 // Use basic bisection to estimate where we should start on the curve.
103 // FIXME: Would Newton's method be better?
104 const double epsilon = 1; // It is probably good enough to get the start poi nt to within 1 pixel/sec.
105 double t0 = 0;
106 double t1 = curveDuration;
107 int numIterations = 0;
108 while (t0 < t1 && numIterations < m_maxSearchIterations) {
109 numIterations++;
110 m_timeOffset = (t0 + t1) * 0.5;
111 double vOffset = velocity(m_timeOffset, m_coeffs);
112 if (fabs(maxInitialVelocity - vOffset) < epsilon)
113 break;
114
115 if (vOffset > maxInitialVelocity)
116 t0 = m_timeOffset;
117 else
118 t1 = m_timeOffset;
119 }
120
121 // Compute curve position at offset time
122 m_positionOffset = position(m_timeOffset, m_coeffs);
53 } 123 }
54 124
55 TouchpadFlingPlatformGestureCurve::~TouchpadFlingPlatformGestureCurve() 125 TouchpadFlingPlatformGestureCurve::~TouchpadFlingPlatformGestureCurve()
56 { 126 {
57 } 127 }
58 128
59 bool TouchpadFlingPlatformGestureCurve::apply(double time, PlatformGestureCurveT arget* target) 129 bool TouchpadFlingPlatformGestureCurve::apply(double time, PlatformGestureCurveT arget* target)
60 { 130 {
61 // Use 2-D Bezier curve with a "stretched-italic-s" curve.
62 // We scale time logarithmically as this (subjectively) feels better.
63 time *= m_timeScaleFactor;
64
65 float displacement; 131 float displacement;
66 if (time < 0) 132 if (time < 0)
67 displacement = 0; 133 displacement = 0;
68 else if (time < 1) { 134 else if (time + m_timeOffset < m_curveDuration)
69 // Below, s is the curve parameter for the 2-D Bezier curve (time(s), di splacement(s)). 135 displacement = position(time + m_timeOffset, m_coeffs) - m_positionOffse t;
70 double s = m_flingBezier.solveCurveX(time, 1.e-3); 136 else
71 displacement = m_flingBezier.sampleCurveY(s); 137 displacement = position(m_curveDuration, m_coeffs) - m_positionOffset;
72 } else
73 displacement = 1;
74 138
75 // Keep track of integer portion of scroll thus far, and prepare increment. 139 // Keep track of integer portion of scroll thus far, and prepare increment.
76 IntPoint scroll(displacement * m_velocity.x(), displacement * m_velocity.y() ); 140 IntPoint scroll(displacement * m_displacementRatio.x(), displacement * m_dis placementRatio.y());
77 IntPoint scrollIncrement(scroll - m_cumulativeScroll); 141 IntPoint scrollIncrement(scroll - m_cumulativeScroll);
78 m_cumulativeScroll = scroll; 142 m_cumulativeScroll = scroll;
79 143
80 if (time < 1 || scrollIncrement != IntPoint::zero()) { 144 if (time + m_timeOffset < m_curveDuration || scrollIncrement != IntPoint::ze ro()) {
81 target->scrollBy(scrollIncrement); 145 target->scrollBy(scrollIncrement);
82 return true; 146 return true;
83 } 147 }
84 148
85 return false; 149 return false;
86 } 150 }
87 151
88 } // namespace WebCore 152 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/WebCore/platform/TouchpadFlingPlatformGestureCurve.h ('k') | Source/WebKit/chromium/ChangeLog » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698