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