pan smoothing and prediction
[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 Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
19
20 // EXTERNAL INCLUDES
21
22 // INTERNAL INCLUDES
23
24 namespace Dali
25 {
26
27 namespace Internal
28 {
29
30 namespace SceneGraph
31 {
32
33 namespace
34 {
35 const unsigned int ARRAY_SIZE( 4u );
36 } // unnamed namespace
37
38 PanGesture* PanGesture::New()
39 {
40   return new PanGesture();
41 }
42
43 PanGesture::~PanGesture()
44 {
45 }
46
47 void PanGesture::AddGesture( const Dali::PanGesture& gesture )
48 {
49   mGestures[ mWritePosition ] = gesture;
50
51   // Update our write position (so now this new value can be read)
52   // Note: we want to overwrite oldest gesture information even if it hasn't been read.
53   ++mWritePosition;
54   mWritePosition %= ARRAY_SIZE;
55 }
56
57 void PanGesture::UpdateProperties( unsigned int nextRenderTime )
58 {
59   unsigned int time( 0u );
60   bool justStarted ( false );
61   bool justFinished ( false );
62
63   // If our read position is not same as write position, then there
64   // must be new values on circular buffer to read.
65   while(mReadPosition != mWritePosition)
66   {
67     const PanInfo& currentGesture = mGestures[mReadPosition];
68
69     if ( currentGesture.time > time )
70     {
71       justStarted |= (currentGesture.state == Gesture::Started);
72       justFinished |= (currentGesture.state == Gesture::Finished || currentGesture.state == Gesture::Cancelled);
73
74       // use position values direct from gesture.
75       mLatestGesture.screen.position = currentGesture.screen.position;
76       mLatestGesture.local.position = currentGesture.local.position;
77
78       // change displacement to be relative to initial touch, instead of relative to last touch-frame.
79       if(currentGesture.state == Gesture::Started)
80       {
81         mLatestGesture.screen.displacement = currentGesture.screen.displacement;
82         mLatestGesture.local.displacement = currentGesture.local.displacement;
83       }
84       else
85       {
86         mLatestGesture.screen.displacement += currentGesture.screen.displacement;
87         mLatestGesture.local.displacement += currentGesture.local.displacement;
88       }
89
90       time = currentGesture.time;
91     }
92
93     ++mReadPosition;
94     mReadPosition %= ARRAY_SIZE;
95   }
96
97   mInGesture |= justStarted;
98
99   if ( mInGesture )
100   {
101     PanInfo gesture(mLatestGesture);
102
103     if( !justStarted ) // only use previous frame if this is the continuing.
104     {
105       // If previous gesture exists, then produce position as 50/50 interpolated blend of these two points.
106       gesture.screen.position += mPreviousGesture.screen.position;
107       gesture.local.position += mPreviousGesture.local.position;
108       gesture.screen.position *= 0.5f;
109       gesture.local.position *= 0.5f;
110       // make current displacement relative to previous update-frame now.
111       gesture.screen.displacement -= mPreviousGesture.screen.displacement;
112       gesture.local.displacement -= mPreviousGesture.local.displacement;
113     }
114
115     mPreviousGesture = mLatestGesture;
116
117     mScreenPosition.Set( gesture.screen.position );
118     mScreenDisplacement.Set( gesture.screen.displacement );
119     mLocalPosition.Set( gesture.local.position );
120     mLocalDisplacement.Set( gesture.local.displacement );
121   }
122
123   mInGesture &= ~justFinished;
124 }
125
126 const GesturePropertyVector2& PanGesture::GetScreenPositionProperty() const
127 {
128   return mScreenPosition;
129 }
130
131 const GesturePropertyVector2& PanGesture::GetScreenDisplacementProperty() const
132 {
133   return mScreenDisplacement;
134 }
135
136 const GesturePropertyVector2& PanGesture::GetLocalPositionProperty() const
137 {
138   return mLocalPosition;
139 }
140
141 const GesturePropertyVector2& PanGesture::GetLocalDisplacementProperty() const
142 {
143   return mLocalDisplacement;
144 }
145
146 void PanGesture::ResetDefaultProperties( BufferIndex updateBufferIndex )
147 {
148   mScreenPosition.Reset();
149   mScreenDisplacement.Reset();
150   mLocalPosition.Reset();
151   mLocalDisplacement.Reset();
152 }
153
154 PanGesture::PanGesture()
155 : mGestures(),
156   mWritePosition( 0 ),
157   mReadPosition( 0 ),
158   mInGesture( false )
159 {
160 }
161
162 } // namespace SceneGraph
163
164 } // namespace Internal
165
166 } // namespace Dali