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