2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "radial-sweep-view-impl.h"
26 * Method to project a point on a circle of radius halfSide at given
27 * angle onto a square of side 2 * halfSide
29 Vector3 CircleSquareProjection( Degree angle, float halfSide )
31 Vector3 position(0.0f, 0.0f, 0.0f);
32 Radian angleInRadians(angle);
41 if( angle >= 45.0f && angle < 135.0f )
43 position.x = halfSide * cosf(angleInRadians) / sinf(angleInRadians);
44 position.y = -halfSide;
46 else if( angle >= 135.0f && angle < 225.0f )
48 position.x = -halfSide;
49 position.y = halfSide * sinf(angleInRadians) / cosf(angleInRadians);
51 else if( angle >= 225.0f && angle < 315.0f )
53 position.x = -halfSide * cosf(angleInRadians) / sinf(angleInRadians);
54 position.y = halfSide;
58 position.x = halfSide;
59 position.y = -halfSide * sinf(angleInRadians) / cosf(angleInRadians);
64 float HoldZeroFastEaseInOutHoldOne(float progress)
70 else if(progress < 0.5f)
72 return AlphaFunctions::EaseIn((progress-0.2) / 0.3f) * 0.5f;
74 else if(progress < 0.8f)
76 return AlphaFunctions::EaseOut((progress - 0.5f) / 0.3f) * 0.5f + 0.5f;
84 struct SquareFanConstraint
86 SquareFanConstraint(int sideIndex)
87 : mSideIndex(sideIndex)
91 Vector3 operator()( const Vector3& current, const PropertyInput& start, const PropertyInput& rotation )
93 float degree = fmodf((start.GetFloat() + rotation.GetFloat()), 360.0f);
99 float startAngle = (90.0f*mSideIndex)-45.0f;
100 float endAngle = (90.0f*mSideIndex)+45.0f;
101 if(degree < startAngle)
103 return Vector3::ZERO;
105 else if( degree >= endAngle )
109 Vector3 pos = CircleSquareProjection(Degree(degree), 0.5f);
110 pos.x = -pos.x; // Inverting X makes the animation go anti clockwise from left center
117 } // anonymous namespace
120 RadialSweepView RadialSweepViewImpl::New( )
122 return New( 2.0f, 100.0f, Degree(0.0f), Degree(0.0f), Degree(0.0f), Degree(359.999f) );
126 RadialSweepView RadialSweepViewImpl::New( float duration, float diameter, Degree initialAngle, Degree finalAngle, Degree initialSector, Degree finalSector )
128 RadialSweepViewImpl* impl= new RadialSweepViewImpl(duration, diameter, initialAngle, finalAngle, initialSector, finalSector);
129 RadialSweepView handle = RadialSweepView(*impl);
133 RadialSweepViewImpl::RadialSweepViewImpl( float duration, float diameter, Degree initialAngle, Degree finalAngle, Degree initialSector, Degree finalSector )
137 mInitialAngle(initialAngle),
138 mFinalAngle(finalAngle),
139 mInitialSector(initialSector),
140 mFinalSector(finalSector),
141 mInitialActorAngle(0),
143 mEasingFunction(HoldZeroFastEaseInOutHoldOne),
144 mRotateActorsWithStencil(false),
149 void RadialSweepViewImpl::SetDuration(float duration)
151 mDuration = duration;
154 void RadialSweepViewImpl::SetEasingFunction( Dali::AlphaFunction easingFunction )
156 mEasingFunction = easingFunction;
159 void RadialSweepViewImpl::SetDiameter(float diameter)
161 mDiameter = diameter;
164 void RadialSweepViewImpl::SetInitialAngle( Dali::Degree initialAngle)
166 mInitialAngle = initialAngle;
169 void RadialSweepViewImpl::SetFinalAngle( Dali::Degree finalAngle)
171 mFinalAngle = finalAngle;
174 void RadialSweepViewImpl::SetInitialSector( Dali::Degree initialSector)
176 mInitialSector = initialSector;
179 void RadialSweepViewImpl::SetFinalSector( Dali::Degree finalSector)
181 mFinalSector = finalSector;
184 void RadialSweepViewImpl::SetInitialActorAngle( Dali::Degree initialAngle )
186 mInitialActorAngle = initialAngle;
187 mRotateActors = true;
190 void RadialSweepViewImpl::SetFinalActorAngle( Dali::Degree finalAngle )
192 mFinalActorAngle = finalAngle;
193 mRotateActors = true;
196 float RadialSweepViewImpl::GetDuration( )
201 float RadialSweepViewImpl::GetDiameter( )
206 Dali::Degree RadialSweepViewImpl::GetInitialAngle( )
208 return mInitialAngle;
211 Dali::Degree RadialSweepViewImpl::GetFinalAngle( )
216 Dali::Degree RadialSweepViewImpl::GetInitialSector( )
218 return mInitialSector;
221 Dali::Degree RadialSweepViewImpl::GetFinalSector( )
226 Dali::Degree RadialSweepViewImpl::GetInitialActorAngle( )
228 return mInitialActorAngle;
231 Dali::Degree RadialSweepViewImpl::GetFinalActorAngle( )
233 return mFinalActorAngle;
236 void RadialSweepViewImpl::RotateActorsWithStencil(bool rotate)
238 mRotateActorsWithStencil = rotate;
241 void RadialSweepViewImpl::Add(Actor actor)
245 mLayer = Layer::New();
247 mLayer.SetSize( Stage::GetCurrent().GetSize() );
248 mLayer.SetPositionInheritanceMode(USE_PARENT_POSITION);
254 void RadialSweepViewImpl::Activate( Animation anim, float offsetTime, float duration )
256 bool startAnimation=false;
259 mAnim = Animation::New( mDuration );
261 startAnimation = true;
264 if( ! mStencilActor )
266 CreateStencil( mInitialSector );
267 mLayer.Add( mStencilActor );
268 mStencilActor.SetSize(mDiameter, mDiameter);
271 mStencilActor.SetRotation( Degree(mInitialAngle), Vector3::ZAXIS );
272 mStencilActor.SetProperty( mRotationAngleIndex, static_cast<float>(mInitialSector) );
276 for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
278 Actor actor = mLayer.GetChildAt(i);
279 if( actor != mStencilActor )
281 anim.RotateTo( actor, mInitialActorAngle, Vector3::ZAXIS );
286 anim.AnimateTo( Property( mStencilActor, mRotationAngleIndex ), static_cast<float>(mFinalSector), mEasingFunction, TimePeriod( offsetTime, duration) );
287 anim.RotateTo( mStencilActor, mFinalAngle, Vector3::ZAXIS, mEasingFunction, offsetTime, duration );
289 if( mRotateActorsWithStencil )
291 for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
293 Actor actor = mLayer.GetChildAt(i);
294 if( actor != mStencilActor )
296 anim.RotateTo( actor, Degree(mFinalAngle - mInitialAngle), Vector3::ZAXIS, mEasingFunction, offsetTime, duration );
300 else if( mRotateActors )
302 for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
304 Actor actor = mLayer.GetChildAt(i);
305 if( actor != mStencilActor )
307 anim.RotateTo( actor, mFinalActorAngle, Vector3::ZAXIS, mEasingFunction, offsetTime, duration );
315 anim.SetLooping(true);
321 void RadialSweepViewImpl::Deactivate()
327 // mLayer.Remove( mStencilActor );
328 // mStencilActor.Reset();
330 // mMaterial.Reset();
333 void RadialSweepViewImpl::CreateStencil( Degree initialSector )
335 mMaterial = Material::New("Material");
336 mMaterial.SetDiffuseColor(Color::WHITE);
337 mMaterial.SetAmbientColor(Vector4(0.0, 0.1, 0.1, 1.0));
339 // Generate a square mesh with a point at the center:
341 AnimatableMesh::Faces faces;
342 // Create triangles joining up the verts
343 faces.push_back(0); faces.push_back(1); faces.push_back(2);
344 faces.push_back(0); faces.push_back(2); faces.push_back(3);
345 faces.push_back(0); faces.push_back(3); faces.push_back(4);
346 faces.push_back(0); faces.push_back(4); faces.push_back(5);
347 faces.push_back(0); faces.push_back(5); faces.push_back(6);
349 mMesh = AnimatableMesh::New(7, faces, mMaterial);
350 mMesh[0].SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) ); // Center pt
352 mStencilActor = MeshActor::New(mMesh);
353 mStencilActor.SetAffectedByLighting(false);
354 mStencilActor.SetCullFace(CullNone); // Allow clockwise & anticlockwise faces
356 mStartAngleIndex = mStencilActor.RegisterProperty("start-angle", Property::Value(0.0f));
357 mRotationAngleIndex = mStencilActor.RegisterProperty("rotation-angle", Property::Value(initialSector));
359 Source srcStart( mStencilActor, mStartAngleIndex );
360 Source srcRot( mStencilActor, mRotationAngleIndex );
362 // Constrain the vertices of the square mesh to sweep out a sector as the
363 // rotation angle is animated.
364 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(1, AnimatableVertex::POSITION),
365 srcStart, srcStart, SquareFanConstraint(0)));
366 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(2, AnimatableVertex::POSITION),
367 srcStart, srcRot, SquareFanConstraint(0)));
368 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(3, AnimatableVertex::POSITION),
369 srcStart, srcRot, SquareFanConstraint(1)));
370 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(4, AnimatableVertex::POSITION),
371 srcStart, srcRot, SquareFanConstraint(2)));
372 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(5, AnimatableVertex::POSITION),
373 srcStart, srcRot, SquareFanConstraint(3)));
374 mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(6, AnimatableVertex::POSITION),
375 srcStart, srcRot, SquareFanConstraint(4)));
377 mStencilActor.SetDrawMode( DrawMode::STENCIL );
378 mStencilActor.SetPositionInheritanceMode(USE_PARENT_POSITION);