31e10b75d9649fed25afb23bc096c22b03e377f3
[platform/core/uifw/dali-core.git] / dali / internal / update / gestures / scene-graph-pan-gesture.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
20
21 // EXTERNAL INCLUDES
22 #include <cmath>
23
24 // INTERNAL INCLUDES
25 #include <dali/internal/update/gestures/pan-gesture-profiling.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 namespace SceneGraph
34 {
35
36 namespace
37 {
38 const int MAX_GESTURE_AGE = 50;                                     ///< maximum age of a gesture before disallowing its use in algorithm TODO: Possibly make this configurable.
39 const float ACCELERATION_THRESHOLD = 0.1f;                          ///< minimum pan velocity change to trigger dynamic change of prediction amount
40 const unsigned int DEFAULT_PREDICTION_INTERPOLATION = 5;            ///< how much to interpolate pan position and displacement from last vsync time (in milliseconds)
41 const unsigned int DEFAULT_MAX_PREDICTION_INTERPOLATION = 32;       ///< the upper bound of the range to clamp the prediction interpolation
42 const unsigned int DEFAULT_MIN_PREDICTION_INTERPOLATION = 0;        ///< the lower bound of the range to clamp the prediction interpolation
43 const unsigned int DEFAULT_PREDICTION_INTERPOLATION_ADJUSTMENT = 2; ///< the amount of prediction interpolation to adjust (in milliseconds) each time when pan velocity changes
44 const float DEFAULT_SMOOTHING_AMOUNT = 0.25f;                       ///< how much to interpolate pan position and displacement from last vsync time
45 } // unnamed namespace
46
47 const PanGesture::PredictionMode PanGesture::DEFAULT_PREDICTION_MODE = PanGesture::PREDICTION_NONE;
48 const int PanGesture::NUM_PREDICTION_MODES = PanGesture::PREDICTION_1 + 1;
49
50 const PanGesture::SmoothingMode PanGesture::DEFAULT_SMOOTHING_MODE = PanGesture::SMOOTHING_LAST_VALUE;
51 const int PanGesture::NUM_SMOOTHING_MODES = PanGesture::SMOOTHING_LAST_VALUE + 1;
52
53 PanGesture* PanGesture::New()
54 {
55   return new PanGesture();
56 }
57
58 PanGesture::~PanGesture()
59 {
60   delete mProfiling;
61 }
62
63 void PanGesture::AddGesture( const Dali::PanGesture& gesture )
64 {
65   Dali::Mutex::ScopedLock lock( mMutex );
66   mGestures[ mWritePosition ] = gesture;
67
68   // Update our write position.
69   ++mWritePosition;
70   mWritePosition %= PAN_GESTURE_HISTORY;
71 }
72
73 void PanGesture::RemoveOldHistory(PanInfoHistory& panHistory, unsigned int currentTime, unsigned int maxAge, unsigned int minEvents)
74 {
75   PanInfoHistoryConstIter endIter = panHistory.end();
76   PanInfoHistoryIter iter = panHistory.begin();
77   while( iter != endIter && panHistory.size() > minEvents)
78   {
79     PanInfo currentGesture = *iter;
80     if( currentTime < currentGesture.time + maxAge )
81     {
82       break;
83     }
84     iter = panHistory.erase(iter);
85     endIter = panHistory.end();
86   }
87
88   // dont want more than 5 previous predictions for smoothing
89   iter = mPredictionHistory.begin();
90   while( mPredictionHistory.size() > 1 && iter != mPredictionHistory.end() )
91   {
92     iter = mPredictionHistory.erase(iter);
93   }
94 }
95
96 void PanGesture::PredictiveAlgorithm1(int eventsThisFrame, PanInfo& gestureOut, PanInfoHistory& panHistory, unsigned int lastVSyncTime, unsigned int nextVSyncTime)
97 {
98   RemoveOldHistory(panHistory, lastVSyncTime, MAX_GESTURE_AGE, 0);
99   size_t panHistorySize = panHistory.size();
100   if( panHistorySize == 0 )
101   {
102     // cant do any prediction without a history
103     return;
104   }
105
106   PanInfoHistoryConstIter endIter = panHistory.end();
107   PanInfoHistoryIter iter = panHistory.begin();
108   Vector2 screenVelocity = gestureOut.screen.velocity;
109   Vector2 localVelocity = gestureOut.local.velocity;
110   Vector2 screenDisplacement = gestureOut.screen.displacement;
111   Vector2 localDisplacement = gestureOut.local.displacement;
112
113   bool havePreviousAcceleration = false;
114   bool previousVelocity = false;
115   float previousAccel = 0.0f;
116   unsigned int lastTime(0);
117
118   unsigned int interpolationTime = lastVSyncTime + mCurrentPredictionAmount;
119
120   if( interpolationTime > gestureOut.time ) // Guard against the rare case when gestureOut.time > (lastVSyncTime + mCurrentPredictionAmount)
121   {
122     interpolationTime -= gestureOut.time;
123   }
124   else
125   {
126     interpolationTime = 0u;
127   }
128
129   while( iter != endIter )
130   {
131     PanInfo currentGesture = *iter;
132     if( !previousVelocity )
133     {
134       // not yet set a previous velocity
135       screenVelocity = currentGesture.screen.velocity;
136       previousVelocity = true;
137       lastTime = currentGesture.time;
138       ++iter;
139       continue;
140     }
141     float previousValueWeight = (float)(MAX_GESTURE_AGE - (lastVSyncTime - lastTime)) / (float)MAX_GESTURE_AGE;
142     float velMag = currentGesture.screen.velocity.Length();
143     float velDiff = velMag - screenVelocity.Length();
144     float acceleration = 0.0f;
145
146     float time(0.f);
147     if (currentGesture.time > lastTime) // Guard against invalid timestamps
148     {
149       time = static_cast<float>( currentGesture.time - lastTime );
150     }
151     if( time > Math::MACHINE_EPSILON_1 )
152     {
153       acceleration = velDiff / time;
154     }
155
156     float newVelMag = 0.0f;
157     int currentInterpolation = interpolationTime;
158     if( !havePreviousAcceleration )
159     {
160       newVelMag =  velMag;
161       havePreviousAcceleration = true;
162     }
163     else
164     {
165       newVelMag = velMag + (((acceleration * (1.0f - previousValueWeight)) + (previousAccel * previousValueWeight)) * currentInterpolation);
166     }
167     float velMod = 1.0f;
168     if( velMag > Math::MACHINE_EPSILON_1 )
169     {
170       velMod = newVelMag / velMag;
171     }
172     gestureOut.screen.velocity = currentGesture.screen.velocity * velMod;
173     gestureOut.local.velocity = currentGesture.local.velocity * velMod;
174     screenDisplacement = gestureOut.screen.displacement + (gestureOut.screen.velocity * interpolationTime);
175     localDisplacement = gestureOut.local.displacement + (gestureOut.local.velocity * interpolationTime);
176     screenVelocity = currentGesture.screen.velocity;
177     localVelocity = currentGesture.local.velocity;
178     previousAccel = acceleration;
179     ++iter;
180   }
181   // gestureOut's position is currently equal to the last event's position and its displacement is equal to last frame's total displacement
182   // add interpolated distance and position to current
183   // work out interpolated velocity
184   gestureOut.screen.position = (gestureOut.screen.position - gestureOut.screen.displacement) + screenDisplacement;
185   gestureOut.local.position = (gestureOut.local.position - gestureOut.local.displacement) + localDisplacement;
186   gestureOut.screen.displacement = screenDisplacement;
187   gestureOut.local.displacement = localDisplacement;
188   gestureOut.time += interpolationTime;
189 }
190
191 void PanGesture::SmoothingAlgorithm1(bool justStarted, PanInfo& gestureOut, unsigned int lastVSyncTime)
192 {
193   if( justStarted )
194   {
195     gestureOut.screen.displacement = Vector2::ZERO;
196     gestureOut.screen.velocity = Vector2::ZERO;
197     gestureOut.local.displacement = Vector2::ZERO;
198     gestureOut.local.velocity = Vector2::ZERO;
199   }
200   else
201   {
202     gestureOut.screen.position -= (gestureOut.screen.position - mLastGesture.screen.position) * 0.5f * (1.0f - mSmoothingAmount);
203     gestureOut.local.position -= (gestureOut.local.position - mLastGesture.local.position) * 0.5f * (1.0f - mSmoothingAmount);
204     // make current displacement relative to previous update-frame now.
205     gestureOut.screen.displacement = gestureOut.screen.position - mLastGesture.screen.position;
206     gestureOut.local.displacement = gestureOut.local.position - mLastGesture.local.position;
207     // calculate velocity relative to previous update-frame
208     float timeDiff( gestureOut.time - mLastGesture.time );
209     gestureOut.screen.velocity = gestureOut.screen.displacement / timeDiff;
210     gestureOut.local.velocity = gestureOut.local.displacement / timeDiff;
211   }
212 }
213
214 void PanGesture::SmoothingAlgorithm2(bool justStarted, PanInfo& gestureOut, unsigned int lastVSyncTime)
215 {
216   // push back result
217   mPredictionHistory.push_back(gestureOut);
218
219   // now smooth current pan event
220   PanInfoHistoryConstIter endIter = mPredictionHistory.end() - 1;
221   PanInfoHistoryIter iter = mPredictionHistory.begin();
222
223   float distanceMod = 1.0f;
224   float weight = 0.8f;
225   while( iter != endIter )
226   {
227     PanInfo currentGesture = *iter;
228     float newDistanceMod = currentGesture.screen.displacement.Length() / gestureOut.screen.displacement.Length();
229     distanceMod = ((distanceMod * weight) + (newDistanceMod * (1.0f - weight)));
230     weight -= 0.15f;
231     ++iter;
232   }
233   gestureOut.screen.position -= gestureOut.screen.displacement;
234   gestureOut.local.position -= gestureOut.local.displacement;
235   gestureOut.screen.displacement *= distanceMod;
236   gestureOut.local.displacement *= distanceMod;
237   gestureOut.screen.position += gestureOut.screen.displacement;
238   gestureOut.local.position += gestureOut.local.displacement;
239 }
240
241 bool PanGesture::ReadGestures( FrameGestureInfo& info, unsigned int currentTimestamp )
242 {
243   unsigned int previousReadPosition = 0;
244   bool eventFound = false;
245   info.frameGesture = mLastUnmodifiedGesture;
246
247   while( mReadPosition != mWritePosition )
248   {
249     // Copy the gesture first
250     PanInfo currentGesture( mGestures[mReadPosition] );
251
252     if( mProfiling )
253     {
254       mProfiling->mRawData.push_back( PanGestureProfiling::Position( currentGesture.time, currentGesture.screen.position, currentGesture.screen.displacement, currentGesture.screen.velocity, currentGesture.state ) );
255     }
256     info.frameGesture.local.position = currentGesture.local.position;
257     info.frameGesture.local.velocity = currentGesture.local.velocity;
258     info.frameGesture.screen.position = currentGesture.screen.position;
259     info.frameGesture.screen.velocity = currentGesture.screen.velocity;
260
261     if( info.eventsThisFrame > 0 )
262     {
263       info.acceleration = currentGesture.screen.velocity.Length() - mGestures[previousReadPosition].screen.velocity.Length();
264     }
265
266     if( !eventFound )
267     {
268       info.frameGesture.local.displacement = currentGesture.local.displacement;
269       info.frameGesture.screen.displacement = currentGesture.screen.displacement;
270       eventFound = true;
271     }
272     else
273     {
274       info.frameGesture.local.displacement += currentGesture.local.displacement;
275       info.frameGesture.screen.displacement += currentGesture.screen.displacement;
276     }
277     info.frameGesture.time = currentGesture.time;
278
279     // add event to history
280     mPanHistory.push_back( currentGesture );
281     if( currentGesture.state == Gesture::Started )
282     {
283       info.justStarted = true;
284       // clear just finished as we have started new pan
285       info.justFinished = false;
286     }
287     info.justFinished |= ( currentGesture.state == Gesture::Finished || currentGesture.state == Gesture::Cancelled );
288
289     // Update our read position.
290     previousReadPosition = mReadPosition;
291     ++info.eventsThisFrame;
292     ++mReadPosition;
293     mReadPosition %= PAN_GESTURE_HISTORY;
294   }
295   // This code does not determine if the data will be used.
296   return false;
297 }
298
299 bool PanGesture::ReadAndResampleGestures( FrameGestureInfo& info, unsigned int currentTimestamp )
300 {
301   PanInfo lastReadGesture;
302   Dali::Mutex::ScopedLock lock( mMutex );
303   while( mReadPosition != mWritePosition )
304   {
305     // Copy the gesture first
306     lastReadGesture = mGestures[mReadPosition];
307     if( mProfiling )
308     {
309       mProfiling->mRawData.push_back( PanGestureProfiling::Position( lastReadGesture.time, lastReadGesture.screen.position,
310           lastReadGesture.screen.displacement, lastReadGesture.screen.velocity, lastReadGesture.state ) );
311     }
312
313     info.frameGesture.screen.position += lastReadGesture.screen.position;
314     info.frameGesture.local.position += lastReadGesture.local.position;
315     info.frameGesture.screen.velocity += lastReadGesture.screen.velocity;
316     info.frameGesture.local.velocity += lastReadGesture.local.velocity;
317
318     if( lastReadGesture.state == Gesture::Started )
319     {
320       // Clear just finished as we have started new pan.
321       info.justFinished = false;
322       info.justStarted = true;
323     }
324     else
325     {
326       info.justFinished |= ( lastReadGesture.state == Gesture::Finished || lastReadGesture.state == Gesture::Cancelled );
327     }
328
329     // Add event to history
330     mPanHistory.push_back( lastReadGesture );
331
332     // Update our read position.
333     ++info.eventsThisFrame;
334     ++mReadPosition;
335     mReadPosition %= PAN_GESTURE_HISTORY;
336   }
337
338   bool updateProperties = false;
339   if( info.eventsThisFrame > 0 )
340   {
341     // Some events were read this frame.
342     mTargetGesture = lastReadGesture;
343
344     if( info.eventsThisFrame > 1 )
345     {
346       info.frameGesture.screen.position /= info.eventsThisFrame;
347       info.frameGesture.local.position /= info.eventsThisFrame;
348       info.frameGesture.screen.velocity /= info.eventsThisFrame;
349       info.frameGesture.local.velocity /= info.eventsThisFrame;
350
351       info.frameGesture.screen.displacement = info.frameGesture.screen.position - mLastGesture.screen.position;
352       info.frameGesture.local.displacement = info.frameGesture.local.position - mLastGesture.local.position;
353
354       mNotAtTarget = true;
355     }
356     else
357     {
358       info.frameGesture.screen.displacement = lastReadGesture.screen.displacement;
359       info.frameGesture.local.displacement = lastReadGesture.local.displacement;
360     }
361
362     info.frameGesture.time = currentTimestamp;
363
364     updateProperties = true;
365   }
366   else
367   {
368     // 0 Events this frame.
369     if( mNotAtTarget )
370     {
371       mNotAtTarget = false;
372       info.frameGesture = mTargetGesture;
373       updateProperties = true;
374     }
375     else
376     {
377       info.frameGesture = mLastGesture;
378     }
379   }
380
381   return updateProperties;
382 }
383
384 bool PanGesture::UpdateProperties( unsigned int lastVSyncTime, unsigned int nextVSyncTime )
385 {
386   if( !mInGesture )
387   {
388     // clear current pan history
389     mPanHistory.clear();
390     mPredictionHistory.clear();
391   }
392
393   FrameGestureInfo frameInfo;
394   bool updateProperties = false;
395
396   // Read input data.
397   // If we are using a form of prediction, read all the input as-is.
398   if( mPredictionMode != PREDICTION_NONE )
399   {
400     // Read input required for prediction algorithms.
401     updateProperties = ReadGestures( frameInfo, lastVSyncTime );
402   }
403   else
404   {
405     // Read and resample input.
406     updateProperties = ReadAndResampleGestures( frameInfo, lastVSyncTime );
407   }
408
409   PanInfo frameGesture = frameInfo.frameGesture;
410   mLastUnmodifiedGesture = frameGesture;
411
412   // Process input data.
413   mInGesture |= frameInfo.justStarted;
414   if( mInGesture )
415   {
416     // Profiling.
417     if( mProfiling )
418     {
419       mProfiling->mLatestData.push_back( PanGestureProfiling::Position( lastVSyncTime, frameGesture.screen.position,
420           frameGesture.screen.displacement, frameGesture.screen.velocity, frameGesture.state ) );
421     }
422
423     // Perform prediction.
424     switch( mPredictionMode )
425     {
426       case PREDICTION_NONE:
427       {
428         break;
429       }
430       case PREDICTION_1:
431       {
432         // Dynamically change the prediction amount according to the pan velocity acceleration.
433         if( !frameInfo.justStarted )
434         {
435           if( frameInfo.eventsThisFrame <= 1 )
436           {
437             frameInfo.acceleration = frameGesture.screen.velocity.Length() - mLastUnmodifiedGesture.screen.velocity.Length();
438           }
439
440           // Ignore tiny velocity fluctuation to avoid unnecessary prediction amount change
441           if( fabsf( frameInfo.acceleration ) > ACCELERATION_THRESHOLD )
442           {
443             mCurrentPredictionAmount += mPredictionAmountAdjustment * ( frameInfo.acceleration > Math::MACHINE_EPSILON_0 ? 1.0f : -1.0f );
444             if( mCurrentPredictionAmount > mMaxPredictionAmount + mPredictionAmountAdjustment ) // Guard against unsigned int overflow
445             {
446               mCurrentPredictionAmount = 0;
447             }
448           }
449         }
450         else
451         {
452           mCurrentPredictionAmount = mPredictionAmount; // Reset the prediction amount for each new gesture
453         }
454
455         mCurrentPredictionAmount = std::max( mMinPredictionAmount, std::min( mCurrentPredictionAmount, mMaxPredictionAmount ) );
456
457         // Calculate the delta of positions before the prediction
458         Vector2 deltaPosition = frameGesture.screen.position - mLastUnmodifiedGesture.screen.position;
459
460         // Make latest gesture equal to current gesture before interpolation
461         PredictiveAlgorithm1( frameInfo.eventsThisFrame, frameGesture, mPanHistory, lastVSyncTime, nextVSyncTime );
462
463         // Calculate the delta of positions after the prediction.
464         Vector2 deltaPredictedPosition = frameGesture.screen.position - mLastGesture.screen.position;
465
466         // If the change in the prediction has a different sign than the change in the actual position,
467         // there is overshot (i.e. the current prediction is too large). Return the previous prediction
468         // to give the user's finger a chance to catch up with where we have panned to.
469         bool overshotXAxis = false;
470         bool overshotYAxis = false;
471         if( (deltaPosition.x > Math::MACHINE_EPSILON_0 && deltaPredictedPosition.x < Math::MACHINE_EPSILON_0 )
472          || (deltaPosition.x < Math::MACHINE_EPSILON_0 && deltaPredictedPosition.x > Math::MACHINE_EPSILON_0 ) )
473         {
474           overshotXAxis = true;
475           frameGesture.screen.position.x = mLastGesture.screen.position.x;
476         }
477
478         if( (deltaPosition.y > Math::MACHINE_EPSILON_0 && deltaPredictedPosition.y < Math::MACHINE_EPSILON_0 )
479          || (deltaPosition.y < Math::MACHINE_EPSILON_0 && deltaPredictedPosition.y > Math::MACHINE_EPSILON_0 ) )
480         {
481           overshotYAxis = true;
482           frameGesture.screen.position.y = mLastGesture.screen.position.y;
483         }
484
485         // If there is overshot in one axis, reduce the possible overshot in the other axis,
486         // and reduce the prediction amount so that it doesn't overshoot as easily next time.
487         if(overshotXAxis || overshotYAxis)
488         {
489           mCurrentPredictionAmount -= mPredictionAmountAdjustment;
490           if( mCurrentPredictionAmount > mMaxPredictionAmount + mPredictionAmountAdjustment ) // Guard against unsigned int overflow
491           {
492             mCurrentPredictionAmount = 0;
493           }
494           mCurrentPredictionAmount = std::max( mMinPredictionAmount, std::min( mCurrentPredictionAmount, mMaxPredictionAmount ) );
495
496           if( overshotXAxis && !overshotYAxis )
497           {
498             frameGesture.screen.position.y = ( mLastGesture.screen.position.y + frameGesture.screen.position.y ) * 0.5f;
499           }
500
501           if( overshotYAxis && !overshotXAxis )
502           {
503             frameGesture.screen.position.x = ( mLastGesture.screen.position.x + frameGesture.screen.position.x ) * 0.5f;
504           }
505         }
506
507         updateProperties = true;
508         break;
509       }
510     }
511
512     // Perform smoothing.
513     switch( mSmoothingMode )
514     {
515       case SMOOTHING_NONE:
516       {
517         // No smoothing
518         break;
519       }
520       case SMOOTHING_LAST_VALUE:
521       {
522         SmoothingAlgorithm1( frameInfo.justStarted, frameGesture, lastVSyncTime );
523         break;
524       }
525     }
526
527     if( updateProperties )
528     {
529       // only update properties if event received
530       // set latest gesture to raw pan info with unchanged time
531       mPanning.Set( mInGesture & !frameInfo.justFinished );
532       mScreenPosition.Set( frameGesture.screen.position );
533       mScreenDisplacement.Set( frameGesture.screen.displacement );
534       mScreenVelocity.Set( frameGesture.screen.velocity );
535       mLocalPosition.Set( frameGesture.local.position );
536       mLocalDisplacement.Set( frameGesture.local.displacement );
537       mLocalVelocity.Set( frameGesture.local.velocity );
538     }
539
540     if( mProfiling )
541     {
542       mProfiling->mAveragedData.push_back( PanGestureProfiling::Position( frameGesture.time, frameGesture.screen.position,
543           frameGesture.screen.displacement, frameGesture.screen.velocity, frameGesture.state ) );
544     }
545   }
546
547   mLastGesture = frameGesture;
548
549   mInGesture &= ~frameInfo.justFinished;
550   if( mProfiling && frameInfo.justFinished )
551   {
552     mProfiling->PrintData();
553     mProfiling->ClearData();
554   }
555
556   return updateProperties;
557 }
558
559 const GesturePropertyBool& PanGesture::GetPanningProperty() const
560 {
561   return mPanning;
562 }
563
564 const GesturePropertyVector2& PanGesture::GetScreenPositionProperty() const
565 {
566   return mScreenPosition;
567 }
568
569 const GesturePropertyVector2& PanGesture::GetScreenVelocityProperty() const
570 {
571   return mScreenVelocity;
572 }
573
574 const GesturePropertyVector2& PanGesture::GetScreenDisplacementProperty() const
575 {
576   return mScreenDisplacement;
577 }
578
579 const GesturePropertyVector2& PanGesture::GetLocalPositionProperty() const
580 {
581   return mLocalPosition;
582 }
583
584 const GesturePropertyVector2& PanGesture::GetLocalDisplacementProperty() const
585 {
586   return mLocalDisplacement;
587 }
588
589 const GesturePropertyVector2& PanGesture::GetLocalVelocityProperty() const
590 {
591   return mLocalVelocity;
592 }
593
594 void PanGesture::SetPredictionMode(PredictionMode mode)
595 {
596   mPredictionMode = mode;
597 }
598
599 void PanGesture::SetPredictionAmount(unsigned int amount)
600 {
601   mPredictionAmount = amount;
602 }
603
604 void PanGesture::SetMaximumPredictionAmount(unsigned int amount)
605 {
606   mMaxPredictionAmount = amount;
607 }
608
609 void PanGesture::SetMinimumPredictionAmount(unsigned int amount)
610 {
611   mMinPredictionAmount = amount;
612 }
613
614 void PanGesture::SetPredictionAmountAdjustment(unsigned int amount)
615 {
616   mPredictionAmountAdjustment = amount;
617 }
618
619 void PanGesture::SetSmoothingMode(SmoothingMode mode)
620 {
621   mSmoothingMode = mode;
622 }
623
624 void PanGesture::SetSmoothingAmount(float amount)
625 {
626   mSmoothingAmount = amount;
627 }
628
629 void PanGesture::EnableProfiling()
630 {
631   if( !mProfiling )
632   {
633     mProfiling = new PanGestureProfiling();
634   }
635 }
636
637 void PanGesture::ResetDefaultProperties( BufferIndex updateBufferIndex )
638 {
639   mScreenPosition.Reset();
640   mScreenDisplacement.Reset();
641   mLocalPosition.Reset();
642   mLocalDisplacement.Reset();
643   mPanning.Reset();
644 }
645
646 PanGesture::PanGesture()
647 : mGestures(),
648   mWritePosition( 0 ),
649   mReadPosition( 0 ),
650   mNotAtTarget( false ),
651   mInGesture( false ),
652   mPredictionMode( DEFAULT_PREDICTION_MODE ),
653   mPredictionAmount( DEFAULT_PREDICTION_INTERPOLATION ),
654   mCurrentPredictionAmount( DEFAULT_PREDICTION_INTERPOLATION ),
655   mMaxPredictionAmount( DEFAULT_MAX_PREDICTION_INTERPOLATION ),
656   mMinPredictionAmount( DEFAULT_MIN_PREDICTION_INTERPOLATION ),
657   mPredictionAmountAdjustment( DEFAULT_PREDICTION_INTERPOLATION_ADJUSTMENT ),
658   mSmoothingMode( DEFAULT_SMOOTHING_MODE ),
659   mSmoothingAmount( DEFAULT_SMOOTHING_AMOUNT ),
660   mProfiling( NULL )
661 {
662 }
663
664
665 } // namespace SceneGraph
666
667 } // namespace Internal
668
669 } // namespace Dali