Automatically dis/connect registered visuals to stage
[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 )
31 : CubeTransitionEffect( numRows, numColumns ),
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 )
39 {
40   // Create the implementation
41   IntrusivePtr< CubeTransitionWaveEffect > internalCubeTransEffect = new CubeTransitionWaveEffect( numRows, numColumns );
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   for( unsigned int idx = 0; idx < mTargetTiles.size(); idx++ )
55   {
56     SetTargetRight( idx );
57   }
58 }
59
60 void CubeTransitionWaveEffect::OnStartTransition( Vector2 panPosition, Vector2 panDisplacement )
61 {
62   bool forward = panDisplacement.x < 0.0;
63   CalculateSaddleSurfaceParameters( panPosition, forward ? panDisplacement : -panDisplacement );
64
65   float angle = Math::PI_2;
66
67   unsigned int idx;
68   if( forward )
69   {
70     for( idx = 0; idx < mTargetTiles.size(); idx++ )
71     {
72       SetTargetRight( idx );
73     }
74   }
75   else
76   {
77     angle = -angle;
78     for( idx = 0; idx < mTargetTiles.size(); idx++ )
79     {
80       SetTargetLeft( idx );
81     }
82   }
83
84   float thirdAnimationDuration = mAnimationDuration / 3.f;
85
86   for( unsigned int y = 0; y < mRows; y++ )
87   {
88     idx = y * mColumns;
89     for( unsigned int x = 0; x < mColumns; x++, idx++)
90     {
91       // the delay value is within 0.f ~ 2.f*thirdAnimationDuration
92       float delay = thirdAnimationDuration * CalculateDelay( x * mTileSize.width, y * mTileSize.height, forward );
93
94       mAnimation.AnimateTo( Property( mBoxes[ idx ], Actor::Property::ORIENTATION ), Quaternion( Radian( -angle ), Vector3::YAXIS ),
95                             AlphaFunction::EASE_OUT_SINE, TimePeriod( delay, thirdAnimationDuration ) );
96       mAnimation.AnimateBy( Property( mBoxes[idx], Actor::Property::POSITION ), Vector3( 0.f, 0.f, -mCubeDisplacement ),
97                          AlphaFunction::BOUNCE, TimePeriod( delay, thirdAnimationDuration ) );
98
99       mAnimation.AnimateTo( Property( mCurrentTiles[ idx ], Actor::Property::COLOR ), HALF_BRIGHTNESS,
100                           AlphaFunction::EASE_OUT, TimePeriod( delay, thirdAnimationDuration ) );
101       mAnimation.AnimateTo( Property( mTargetTiles[ idx ], Actor::Property::COLOR ), FULL_BRIGHTNESS,
102                           AlphaFunction::EASE_IN, TimePeriod( delay, thirdAnimationDuration ) );
103     }
104   }
105
106   mAnimation.Play();
107   mIsAnimating = true;
108 }
109
110 void  CubeTransitionWaveEffect::CalculateSaddleSurfaceParameters( Vector2 position, Vector2 displacement )
111 {
112   const Vector2 size = Self().GetCurrentSize().GetVectorXY();
113   // the line passes through 'position' and has the direction of 'displacement'
114   float coefA, coefB, coefC; //line equation: Ax+By+C=0;
115   coefA = displacement.y;
116   coefB = -displacement.x;
117   coefC = -displacement.y*position.x + displacement.x*position.y;
118
119   float inversedAABB = 1.f / (coefA*coefA+coefB*coefB);
120   float inversedSqrtAABB = sqrtf(inversedAABB);
121   float saddleA;
122
123   if(displacement.y > 0)
124   {
125     //distance from (0,0) to the line
126     float distanceTopLeft =  fabsf(coefC) * inversedSqrtAABB;
127     //distance from (viewAreaSize.x, viewAreaSize.y) to the line
128     float distanceBottomRight = fabsf(coefA*size.x+coefB*size.y+coefC) * inversedSqrtAABB;
129     saddleA = std::max( distanceTopLeft, distanceBottomRight );
130
131     //foot of a perpendicular: (viewAreaSize.x,0) to the line
132     float footX1 = ( coefB*coefB*size.x - coefA*coefC) * inversedAABB;
133     float footY1 = (-coefA*coefB*size.x - coefB*coefC) * inversedAABB;
134     //foot of a perpendicular: (0,viewAreaSize.y) to the line
135     float footX2 = (-coefA*coefB*size.y - coefA*coefC) * inversedAABB;
136     float footY2 = ( coefA*coefA*size.y - coefB*coefC) * inversedAABB;
137     mSaddleBB = (footX1-footX2)*(footX1-footX2) + (footY1-footY2)*(footY1-footY2);
138     mTranslation = Vector2(-footX2,-footY2);
139   }
140   else
141   {
142     //distance from(viewAreaSize.x,0) to the line
143     float distanceTopRight = fabsf(coefA*size.x+coefC) * inversedSqrtAABB;
144     //distance from(0,viewAreaSize.y) to the line
145     float distanceBottomLeft = fabsf(coefB*size.y+coefC) * inversedSqrtAABB;
146     saddleA = std::max( distanceTopRight, distanceBottomLeft );
147     //foot of a perpendicular: (0,0) to the line
148     float footX3 = (-coefA*coefC) * inversedAABB;
149     float footY3 = (-coefB*coefC) * inversedAABB;
150     //foot of a perpendicular: (viewAreaSize.x,viewAreaSize.y) to the line
151     float footX4 = ( coefB*coefB*size.x - coefA*coefB*size.y - coefA*coefC) * inversedAABB;
152     float footY4 = (-coefA*coefB*size.x + coefA*coefA*size.y - coefB*coefC) * inversedAABB;
153     mSaddleBB = (footX3-footX4)*(footX3-footX4) + (footY3-footY4)*(footY3-footY4);
154     mTranslation = Vector2(-footX3, -footY3);
155   }
156
157   mSaddleB = sqrtf(mSaddleBB);
158   //prevent high curve shape
159   if(mSaddleB > 2.f * saddleA)
160   {
161     saddleA = mSaddleB * 0.5f;
162   }
163   else if(mSaddleB < saddleA)
164   {
165     mSaddleB = saddleA;
166     mSaddleBB = mSaddleB*mSaddleB;
167   }
168   mSaddleAA = saddleA*saddleA;
169   mRotation = Vector2(-displacement.x, displacement.y);
170   mRotation.Normalize();
171 }
172
173 float CubeTransitionWaveEffect::CalculateDelay( float x, float y, bool forward )
174 {
175   float tx = x + mTranslation.x;
176   float ty = y + mTranslation.y;
177   float valueX = mRotation.x * tx - mRotation.y * ty;
178   float valueY = mRotation.y * tx + mRotation.x * ty;
179   if( !forward ) // to previous image
180   {
181     valueX = mSaddleB - valueX;
182   }
183   //the return value is a float number between 0.f and 2.f
184   return (1.f + valueY*valueY / mSaddleAA - valueX*valueX / mSaddleBB);
185 }
186
187 } // namespace Internal
188
189 } // namespace Toolkit
190
191 } // namespace Dali