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