[SRUK] Initial copy from Tizen 2.2 version
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / transition-effects / cube-transition-wave-effect-impl.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 "cube-transition-wave-effect-impl.h"
19
20 namespace Dali
21 {
22
23 namespace Toolkit
24 {
25
26 namespace Internal
27 {
28
29 CubeTransitionWaveEffect::CubeTransitionWaveEffect( unsigned int numRows, unsigned int numColumns, Size viewAreaSize )
30 : CubeTransitionEffect( numRows, numColumns, viewAreaSize)
31 {
32 }
33
34 Toolkit::CubeTransitionWaveEffect CubeTransitionWaveEffect::New(unsigned int numRows, unsigned int numColumns, Size viewAreaSize)
35 {
36   // Create the implementation
37   CubeTransitionWaveEffect* internalCubeTransEffect = new CubeTransitionWaveEffect( numRows, numColumns, viewAreaSize );
38
39   // Pass ownership to CustomActor handle
40   Toolkit::CubeTransitionWaveEffect cubeTransEffect( internalCubeTransEffect );
41
42   //Initialization
43   internalCubeTransEffect->Initialize();
44
45   return cubeTransEffect;
46 }
47
48 void CubeTransitionWaveEffect::OnInitialize()
49 {
50   float offset = -mTileSize.width * 0.5f;
51   unsigned int totalNum = mNumColumns* mNumRows;
52   for( unsigned int idx = 0; idx < totalNum; idx++ )
53   {
54     mTiles[ 0 ][idx].SetZ( -offset );
55     mTiles[ 1 ][idx].SetX( offset );
56   }
57 }
58
59 void CubeTransitionWaveEffect::OnStartTransition( Vector2 panPosition, Vector2 panDisplacement )
60 {
61   float direc = mIsToNextImage ? 1.f : -1.f;
62   CalculateSaddleSurfaceParameters( panPosition, panDisplacement*direc );
63
64   float angle = mRotateIndex * 90.0f ;
65   Vector3 translation = mTiles[mContainerIndex][ 0 ].GetCurrentPosition()*(-2.f);
66
67   unsigned int idx;
68   unsigned int totalNum = mNumColumns* mNumRows;
69   if( mFirstTransition && (!mIsToNextImage) ) // the first transition is transiting to previous image
70   {
71     for( unsigned int idx = 0; idx < totalNum; idx++ )
72     {
73       mTiles[mContainerIndex][idx].SetRotation( Degree( angle),  Vector3::YAXIS );
74     }
75   }
76   else if(!mChangeTurningDirection)  // reset rotation, translation
77   {
78     for( unsigned int idx = 0; idx < totalNum; idx++ )
79     {
80       mTiles[mContainerIndex][idx].MoveBy( translation );
81       mTiles[mContainerIndex][idx].SetRotation( Degree( angle),  Vector3::YAXIS );
82     }
83   }
84
85   float thirdAnimationDuration = mAnimationDuration / 3.f;
86   unsigned int anotherIndex = mContainerIndex^1;
87
88   for( unsigned int y = 0; y < mNumRows; y++ )
89   {
90     for( unsigned int x = 0; x < mNumColumns; x++)
91     {
92       idx = y*mNumColumns + x;
93       // the delay value is within 0.f ~ 2.f*thirdAnimationDuration
94       float delay = thirdAnimationDuration * CalculateDelay(x*mTileSize.width,y*mTileSize.height);
95
96       mAnimation.RotateTo( mBoxes[idx], Degree( -angle ), Vector3::YAXIS,
97                            AlphaFunctions::EaseOutSine, delay, thirdAnimationDuration );
98       mAnimation.MoveBy( mBoxes[idx], Vector3(0.f,0.f,-mCubeDisplacement),
99                          AlphaFunctions::Bounce, delay, thirdAnimationDuration );
100       mAnimation.ColorTo( mTiles[anotherIndex][idx], HALF_BRIGHTNESS,
101                           AlphaFunctions::EaseOut, delay, thirdAnimationDuration );
102       mAnimation.ColorTo( mTiles[mContainerIndex][idx], FULL_BRIGHTNESS,
103                           AlphaFunctions::EaseIn, delay, thirdAnimationDuration );
104     }
105   }
106
107   mAnimation.Play();
108   mIsAnimating = true;
109 }
110
111 void CubeTransitionWaveEffect::OnStopTransition()
112 {
113   float angle = - mRotateIndex * 90.0f ;
114   unsigned int totalNum = mNumRows * mNumColumns;
115   for( unsigned int idx = 0; idx < totalNum; idx++ )
116   {
117     mBoxes[idx].SetRotation( Degree( angle ), Vector3::YAXIS );
118   }
119 }
120
121 void  CubeTransitionWaveEffect::CalculateSaddleSurfaceParameters( Vector2 position, Vector2 displacement )
122 {
123   // the line passes through 'position' and has the direction of 'displacement'
124   float coefA, coefB, coefC; //line equation: Ax+By+C=0;
125   coefA = displacement.y;
126   coefB = -displacement.x;
127   coefC = -displacement.y*position.x + displacement.x*position.y;
128
129   float inversedAABB = 1.f / (coefA*coefA+coefB*coefB);
130   float inversedSqrtAABB = sqrtf(inversedAABB);
131   float saddleA;
132
133   if(displacement.y > 0)
134   {
135     //distance from (0,0) to the line
136     float distanceTopLeft =  fabsf(coefC) * inversedSqrtAABB;
137     //distance from (viewAreaSize.x, viewAreaSize.y) to the line
138     float distanceBottomRight = fabsf(coefA*mViewAreaSize.x+coefB*mViewAreaSize.y+coefC) * inversedSqrtAABB;
139     saddleA = std::max( distanceTopLeft, distanceBottomRight );
140
141     //foot of a perpendicular: (viewAreaSize.x,0) to the line
142     float footX1 = ( coefB*coefB*mViewAreaSize.x - coefA*coefC) * inversedAABB;
143     float footY1 = (-coefA*coefB*mViewAreaSize.x - coefB*coefC) * inversedAABB;
144     //foot of a perpendicular: (0,viewAreaSize.y) to the line
145     float footX2 = (-coefA*coefB*mViewAreaSize.y - coefA*coefC) * inversedAABB;
146     float footY2 = ( coefA*coefA*mViewAreaSize.y - coefB*coefC) * inversedAABB;
147     mSaddleBB = (footX1-footX2)*(footX1-footX2) + (footY1-footY2)*(footY1-footY2);
148     mTranslation = Vector2(-footX2,-footY2);
149   }
150   else
151   {
152     //distance from(viewAreaSize.x,0) to the line
153     float distanceTopRight = fabsf(coefA*mViewAreaSize.x+coefC) * inversedSqrtAABB;
154     //distance from(0,viewAreaSize.y) to the line
155     float distanceBottomLeft = fabsf(coefB*mViewAreaSize.y+coefC) * inversedSqrtAABB;
156     saddleA = std::max( distanceTopRight, distanceBottomLeft );
157     //foot of a perpendicular: (0,0) to the line
158     float footX3 = (-coefA*coefC) * inversedAABB;
159     float footY3 = (-coefB*coefC) * inversedAABB;
160     //foot of a perpendicular: (viewAreaSize.x,viewAreaSize.y) to the line
161     float footX4 = ( coefB*coefB*mViewAreaSize.x - coefA*coefB*mViewAreaSize.y - coefA*coefC) * inversedAABB;
162     float footY4 = (-coefA*coefB*mViewAreaSize.x + coefA*coefA*mViewAreaSize.y - coefB*coefC) * inversedAABB;
163     mSaddleBB = (footX3-footX4)*(footX3-footX4) + (footY3-footY4)*(footY3-footY4);
164     mTranslation = Vector2(-footX3, -footY3);
165   }
166
167   mSaddleB = sqrtf(mSaddleBB);
168   //prevent high curve shape
169   if(mSaddleB > 2.f * saddleA)
170   {
171     saddleA = mSaddleB * 0.5f;
172   }
173   else if(mSaddleB < saddleA)
174   {
175     mSaddleB = saddleA;
176     mSaddleBB = mSaddleB*mSaddleB;
177   }
178   mSaddleAA = saddleA*saddleA;
179   mRotation = Vector2(-displacement.x, displacement.y);
180   mRotation.Normalize();
181 }
182
183 float CubeTransitionWaveEffect::CalculateDelay(float x, float y)
184 {
185   float tx = x + mTranslation.x;
186   float ty = y + mTranslation.y;
187   float valueX = mRotation.x * tx - mRotation.y * ty;
188   float valueY = mRotation.y * tx + mRotation.x * ty;
189   if(!mIsToNextImage) // to previous image
190   {
191     valueX = mSaddleB - valueX;
192   }
193   //the return value is a float number between 0.f and 2.f
194   return (1.f + valueY*valueY / mSaddleAA - valueX*valueX / mSaddleBB);
195 }
196
197 } // namespace Internal
198
199 } // namespace Toolkit
200
201 } // namespace Dali