2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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.
17 #include "radial-sweep-view-impl.h"
25 * Method to project a point on a circle of radius halfSide at given
26 * angle onto a square of side 2 * halfSide
28 Vector3 CircleSquareProjection( Degree angle, float halfSide )
30 Vector3 position(0.0f, 0.0f, 0.0f);
31 Radian angleInRadians(angle);
40 if( angle >= 45.0f && angle < 135.0f )
42 position.x = halfSide * cosf(angleInRadians) / sinf(angleInRadians);
43 position.y = -halfSide;
45 else if( angle >= 135.0f && angle < 225.0f )
47 position.x = -halfSide;
48 position.y = halfSide * sinf(angleInRadians) / cosf(angleInRadians);
50 else if( angle >= 225.0f && angle < 315.0f )
52 position.x = -halfSide * cosf(angleInRadians) / sinf(angleInRadians);
53 position.y = halfSide;
57 position.x = halfSide;
58 position.y = -halfSide * sinf(angleInRadians) / cosf(angleInRadians);
63 float HoldZeroFastEaseInOutHoldOne(float progress)
69 else if(progress < 0.5f)
71 return AlphaFunctions::EaseIn((progress-0.2) / 0.3f) * 0.5f;
73 else if(progress < 0.8f)
75 return AlphaFunctions::EaseOut((progress - 0.5f) / 0.3f) * 0.5f + 0.5f;
83 struct SquareFanConstraint
85 SquareFanConstraint(int sideIndex)
86 : mSideIndex(sideIndex)
90 Vector3 operator()( const Vector3& current, const PropertyInput& start, const PropertyInput& rotation )
92 float degree = fmodf((start.GetFloat() + rotation.GetFloat()), 360.0f);
98 float startAngle = (90.0f*mSideIndex)-45.0f;
99 float endAngle = (90.0f*mSideIndex)+45.0f;
100 if(degree < startAngle)
102 return Vector3::ZERO;
104 else if( degree >= endAngle )
108 Vector3 pos = CircleSquareProjection(Degree(degree), 0.5f);
109 pos.x = -pos.x; // Inverting X makes the animation go anti clockwise from left center
116 } // anonymous namespace
119 RadialSweepView RadialSweepViewImpl::New( )
121 return New( 2.0f, 100.0f, Degree(0.0f), Degree(0.0f), Degree(0.0f), Degree(359.999f) );
125 RadialSweepView RadialSweepViewImpl::New( float duration, float diameter, Degree initialAngle, Degree finalAngle, Degree initialSector, Degree finalSector )
127 RadialSweepViewImpl* impl= new RadialSweepViewImpl(duration, diameter, initialAngle, finalAngle, initialSector, finalSector);
128 RadialSweepView handle = RadialSweepView(*impl);
132 RadialSweepViewImpl::RadialSweepViewImpl( float duration, float diameter, Degree initialAngle, Degree finalAngle, Degree initialSector, Degree finalSector )
136 mInitialAngle(initialAngle),
137 mFinalAngle(finalAngle),
138 mInitialSector(initialSector),
139 mFinalSector(finalSector),
140 mInitialActorAngle(0),
142 mEasingFunction(HoldZeroFastEaseInOutHoldOne),
143 mRotateActorsWithStencil(false),
148 void RadialSweepViewImpl::SetDuration(float duration)
150 mDuration = duration;
153 void RadialSweepViewImpl::SetEasingFunction( Dali::AlphaFunction easingFunction )
155 mEasingFunction = easingFunction;
158 void RadialSweepViewImpl::SetDiameter(float diameter)
160 mDiameter = diameter;
163 void RadialSweepViewImpl::SetInitialAngle( Dali::Degree initialAngle)
165 mInitialAngle = initialAngle;
168 void RadialSweepViewImpl::SetFinalAngle( Dali::Degree finalAngle)
170 mFinalAngle = finalAngle;
173 void RadialSweepViewImpl::SetInitialSector( Dali::Degree initialSector)
175 mInitialSector = initialSector;
178 void RadialSweepViewImpl::SetFinalSector( Dali::Degree finalSector)
180 mFinalSector = finalSector;
183 void RadialSweepViewImpl::SetInitialActorAngle( Dali::Degree initialAngle )
185 mInitialActorAngle = initialAngle;
186 mRotateActors = true;
189 void RadialSweepViewImpl::SetFinalActorAngle( Dali::Degree finalAngle )
191 mFinalActorAngle = finalAngle;
192 mRotateActors = true;
195 float RadialSweepViewImpl::GetDuration( )
200 float RadialSweepViewImpl::GetDiameter( )
205 Dali::Degree RadialSweepViewImpl::GetInitialAngle( )
207 return mInitialAngle;
210 Dali::Degree RadialSweepViewImpl::GetFinalAngle( )
215 Dali::Degree RadialSweepViewImpl::GetInitialSector( )
217 return mInitialSector;
220 Dali::Degree RadialSweepViewImpl::GetFinalSector( )
225 Dali::Degree RadialSweepViewImpl::GetInitialActorAngle( )
227 return mInitialActorAngle;
230 Dali::Degree RadialSweepViewImpl::GetFinalActorAngle( )
232 return mFinalActorAngle;
235 void RadialSweepViewImpl::RotateActorsWithStencil(bool rotate)
237 mRotateActorsWithStencil = rotate;
240 void RadialSweepViewImpl::Add(Actor actor)
244 mLayer = Layer::New();
246 mLayer.SetSize( Stage::GetCurrent().GetSize() );
247 mLayer.SetPositionInheritanceMode(USE_PARENT_POSITION);
253 void RadialSweepViewImpl::Activate( Animation anim, float offsetTime, float duration )
255 bool startAnimation=false;
258 mAnim = Animation::New( mDuration );
260 startAnimation = true;
263 if( ! mStencilActor )
265 CreateStencil( mInitialSector );
266 mLayer.Add( mStencilActor );
267 mStencilActor.SetSize(mDiameter, mDiameter);
270 mStencilActor.SetRotation( Degree(mInitialAngle), Vector3::ZAXIS );
271 mStencilActor.SetProperty( mRotationAngleIndex, static_cast<float>(mInitialSector) );
275 for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
277 Actor actor = mLayer.GetChildAt(i);
278 if( actor != mStencilActor )
280 anim.RotateTo( actor, mInitialActorAngle, Vector3::ZAXIS );
285 anim.AnimateTo( Property( mStencilActor, mRotationAngleIndex ), static_cast<float>(mFinalSector), mEasingFunction, TimePeriod( offsetTime, duration) );
286 anim.RotateTo( mStencilActor, mFinalAngle, Vector3::ZAXIS, mEasingFunction, offsetTime, duration );
288 if( mRotateActorsWithStencil )
290 for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
292 Actor actor = mLayer.GetChildAt(i);
293 if( actor != mStencilActor )
295 anim.RotateTo( actor, Degree(mFinalAngle - mInitialAngle), Vector3::ZAXIS, mEasingFunction, offsetTime, duration );
299 else if( mRotateActors )
301 for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
303 Actor actor = mLayer.GetChildAt(i);
304 if( actor != mStencilActor )
306 anim.RotateTo( actor, mFinalActorAngle, Vector3::ZAXIS, mEasingFunction, offsetTime, duration );
314 anim.SetLooping(true);
320 void RadialSweepViewImpl::Deactivate()
326 // mLayer.Remove( mStencilActor );
327 // mStencilActor.Reset();
329 // mMaterial.Reset();
332 void RadialSweepViewImpl::CreateStencil( Degree initialSector )
334 mMaterial = Material::New("Material");
335 mMaterial.SetDiffuseColor(Color::WHITE);
336 mMaterial.SetAmbientColor(Vector4(0.0, 0.1, 0.1, 1.0));
338 // Generate a square mesh with a point at the center:
340 AnimatableMesh::Faces faces;
341 // Create triangles joining up the verts
342 faces.push_back(0); faces.push_back(1); faces.push_back(2);
343 faces.push_back(0); faces.push_back(2); faces.push_back(3);
344 faces.push_back(0); faces.push_back(3); faces.push_back(4);
345 faces.push_back(0); faces.push_back(4); faces.push_back(5);
346 faces.push_back(0); faces.push_back(5); faces.push_back(6);
348 mMesh = AnimatableMesh::New(7, faces, mMaterial);
349 mMesh[0].SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) ); // Center pt
351 mStencilActor = MeshActor::New(mMesh);
352 mStencilActor.SetAffectedByLighting(false);
353 mStencilActor.SetCullFace(CullNone); // Allow clockwise & anticlockwise faces
355 mStartAngleIndex = mStencilActor.RegisterProperty("start-angle", Property::Value(0.0f));
356 mRotationAngleIndex = mStencilActor.RegisterProperty("rotation-angle", Property::Value(initialSector));
358 Source srcStart( mStencilActor, mStartAngleIndex );
359 Source srcRot( mStencilActor, mRotationAngleIndex );
361 // Constrain the vertices of the square mesh to sweep out a sector as the
362 // rotation angle is animated.
363 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(1, AnimatableVertex::POSITION),
364 srcStart, srcStart, SquareFanConstraint(0)));
365 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(2, AnimatableVertex::POSITION),
366 srcStart, srcRot, SquareFanConstraint(0)));
367 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(3, AnimatableVertex::POSITION),
368 srcStart, srcRot, SquareFanConstraint(1)));
369 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(4, AnimatableVertex::POSITION),
370 srcStart, srcRot, SquareFanConstraint(2)));
371 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(5, AnimatableVertex::POSITION),
372 srcStart, srcRot, SquareFanConstraint(3)));
373 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(6, AnimatableVertex::POSITION),
374 srcStart, srcRot, SquareFanConstraint(4)));
376 mStencilActor.SetDrawMode( DrawMode::STENCIL );
377 mStencilActor.SetPositionInheritanceMode(USE_PARENT_POSITION);