2 * Copyright (c) 2015 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"
27 const char* VERTEX_SHADER_PREFIX( "#define MATH_PI_2 1.570796\n#define MATH_PI_4 0.785398\n" );
29 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
30 attribute mediump float aAngleIndex;\n
31 attribute mediump vec2 aPosition1;\n
32 attribute mediump vec2 aPosition2;\n
33 uniform mediump mat4 uMvpMatrix;\n
34 uniform mediump float uStartAngle;\n
35 uniform mediump float uRotationAngle;\n
39 float currentAngle = uStartAngle + uRotationAngle;\n
40 float angleInterval1 = MATH_PI_4 * aAngleIndex;\n
41 vec4 vertexPosition = vec4(0.0, 0.0, 0.0, 1.0);\n
42 if( currentAngle >= angleInterval1)\n
44 float angleInterval2 = angleInterval1 + MATH_PI_2;\n
45 float angle = currentAngle < angleInterval2 ? currentAngle : angleInterval2;\n
47 if( mod( aAngleIndex+4.0, 4.0) < 2.0 )\n
49 delta = 0.5 - 0.5*cos(angle) / sin(angle);\n
53 delta = 0.5 + 0.5*sin(angle) / cos(angle);\n
55 vertexPosition.xy = mix( aPosition1, aPosition2, delta );\n
57 gl_Position = uMvpMatrix * vertexPosition;\n
61 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
62 uniform lowp vec4 uColor;\n
66 gl_FragColor = uColor;\n
70 float HoldZeroFastEaseInOutHoldOne(float progress)
76 else if(progress < 0.5f)
78 progress = (progress-0.2) / 0.3f;
79 return progress*progress*progress*0.5f;
81 else if(progress < 0.8f)
83 progress = ((progress - 0.5f) / 0.3f) - 1.0f;
84 return (progress*progress*progress+1.0f) * 0.5f + 0.5f;
92 } // anonymous namespace
95 RadialSweepView RadialSweepViewImpl::New( )
97 return New( 2.0f, 100.0f, ANGLE_0, ANGLE_0, ANGLE_0, ANGLE_360 );
101 RadialSweepView RadialSweepViewImpl::New( float duration, float diameter, Radian initialAngle, Radian finalAngle, Radian initialSector, Radian finalSector )
103 RadialSweepViewImpl* impl= new RadialSweepViewImpl(duration, diameter, initialAngle, finalAngle, initialSector, finalSector);
104 RadialSweepView handle = RadialSweepView(*impl);
108 RadialSweepViewImpl::RadialSweepViewImpl( float duration, float diameter, Radian initialAngle, Radian finalAngle, Radian initialSector, Radian finalSector )
109 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
112 mInitialAngle(initialAngle),
113 mFinalAngle(finalAngle),
114 mInitialSector(initialSector),
115 mFinalSector(finalSector),
116 mInitialActorAngle(0),
118 mEasingFunction(HoldZeroFastEaseInOutHoldOne),
119 mStartAngleIndex(Property::INVALID_INDEX),
120 mRotationAngleIndex(Property::INVALID_INDEX),
121 mRotateActorsWithStencil(false),
126 void RadialSweepViewImpl::SetDuration(float duration)
128 mDuration = duration;
131 void RadialSweepViewImpl::SetEasingFunction( Dali::AlphaFunction easingFunction )
133 mEasingFunction = easingFunction;
136 void RadialSweepViewImpl::SetDiameter(float diameter)
138 mDiameter = diameter;
141 void RadialSweepViewImpl::SetInitialAngle( Dali::Radian initialAngle)
143 mInitialAngle = initialAngle;
146 void RadialSweepViewImpl::SetFinalAngle( Dali::Radian finalAngle)
148 mFinalAngle = finalAngle;
151 void RadialSweepViewImpl::SetInitialSector( Dali::Radian initialSector)
153 mInitialSector = initialSector;
156 void RadialSweepViewImpl::SetFinalSector( Dali::Radian finalSector)
158 mFinalSector = finalSector;
161 void RadialSweepViewImpl::SetInitialActorAngle( Dali::Radian initialAngle )
163 mInitialActorAngle = initialAngle;
164 mRotateActors = true;
167 void RadialSweepViewImpl::SetFinalActorAngle( Dali::Radian finalAngle )
169 mFinalActorAngle = finalAngle;
170 mRotateActors = true;
173 float RadialSweepViewImpl::GetDuration( )
178 float RadialSweepViewImpl::GetDiameter( )
183 Dali::Radian RadialSweepViewImpl::GetInitialAngle( )
185 return mInitialAngle;
188 Dali::Radian RadialSweepViewImpl::GetFinalAngle( )
193 Dali::Radian RadialSweepViewImpl::GetInitialSector( )
195 return mInitialSector;
198 Dali::Radian RadialSweepViewImpl::GetFinalSector( )
203 Dali::Radian RadialSweepViewImpl::GetInitialActorAngle( )
205 return mInitialActorAngle;
208 Dali::Radian RadialSweepViewImpl::GetFinalActorAngle( )
210 return mFinalActorAngle;
213 void RadialSweepViewImpl::RotateActorsWithStencil(bool rotate)
215 mRotateActorsWithStencil = rotate;
218 void RadialSweepViewImpl::Add(Actor actor)
222 mLayer = Layer::New();
224 mLayer.SetSize( Stage::GetCurrent().GetSize() );
225 mLayer.SetPositionInheritanceMode(USE_PARENT_POSITION);
231 void RadialSweepViewImpl::Activate( Animation anim, float offsetTime, float duration )
233 bool startAnimation=false;
236 mAnim = Animation::New( mDuration );
238 startAnimation = true;
241 if( ! mStencilActor )
243 CreateStencil( mInitialSector );
244 mLayer.Add( mStencilActor );
245 mStencilActor.SetScale(mDiameter);
248 mStencilActor.SetOrientation( mInitialAngle, Vector3::ZAXIS );
249 mStencilActor.SetProperty( mRotationAngleIndex, mInitialSector.radian );
253 for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
255 Actor actor = mLayer.GetChildAt(i);
256 if( actor != mStencilActor )
258 anim.AnimateTo( Property( actor, Actor::Property::ORIENTATION ), Quaternion( Radian( mInitialActorAngle ), Vector3::ZAXIS ) );
263 anim.AnimateTo( Property( mStencilActor, mRotationAngleIndex ), mFinalSector.radian, mEasingFunction, TimePeriod( offsetTime, duration ) );
264 anim.AnimateTo( Property( mStencilActor, Actor::Property::ORIENTATION ), Quaternion( Radian( mFinalAngle ), Vector3::ZAXIS ), mEasingFunction, TimePeriod( offsetTime, duration ) );
266 if( mRotateActorsWithStencil )
268 for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
270 Actor actor = mLayer.GetChildAt(i);
271 if( actor != mStencilActor )
273 anim.AnimateTo( Property( actor, Actor::Property::ORIENTATION ), Quaternion( Radian( mFinalAngle.radian - mInitialAngle.radian ) , Vector3::ZAXIS ), mEasingFunction, TimePeriod( offsetTime, duration ) );
277 else if( mRotateActors )
279 for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
281 Actor actor = mLayer.GetChildAt(i);
282 if( actor != mStencilActor )
284 anim.AnimateTo( Property( actor, Actor::Property::ORIENTATION ), Quaternion( Radian( mFinalActorAngle ), Vector3::ZAXIS ), mEasingFunction, TimePeriod( offsetTime, duration ) );
292 anim.SetLooping(true);
298 void RadialSweepViewImpl::Deactivate()
304 // mLayer.Remove( mStencilActor );
305 // mStencilActor.Reset();
307 // mMaterial.Reset();
310 void RadialSweepViewImpl::CreateStencil( Radian initialSector )
312 // Create the stencil mesh geometry
319 struct VertexPosition { float angleIndex; Vector2 position1; Vector2 position2; };
320 VertexPosition vertexData[7] = { // With X coordinate inverted to make the animation go anti clockwise from left center
321 { 9.f, Vector2( 0.f, 0.f ), Vector2( 0.f, 0.f ) }, // center point, keep static
322 { 0.f, Vector2( -0.5f, 0.f ), Vector2( -0.5f, 0.f ) }, // vertex 1, 0 degree, keep static
323 { -1.f, Vector2( -0.5f, 0.5f ), Vector2( -0.5f, -0.5f ) }, // -45 ~ 45 degrees ( 0 ~ 45)
324 { 1.f, Vector2( -0.5f, -0.5f ), Vector2( 0.5f, -0.5f ) }, // 45 ~ 135 degrees
325 { 3.f, Vector2( 0.5f, -0.5f ), Vector2( 0.5f, 0.5f ) }, // 135 ~ 225 degrees
326 { 5.f, Vector2( 0.5f, 0.5f ), Vector2( -0.5f, 0.5f ) }, // 225 ~ 315 degrees
327 { 7.f, Vector2( -0.5f, 0.5f ), Vector2( -0.5f, -0.5f ) } // 315 ~ 405 degrees ( 315 ~ 359.999 )
329 Property::Map vertexFormat;
330 vertexFormat["aAngleIndex"] = Property::FLOAT;
331 vertexFormat["aPosition1"] = Property::VECTOR2;
332 vertexFormat["aPosition2"] = Property::VECTOR2;
333 PropertyBuffer vertices = PropertyBuffer::New( vertexFormat, 7u );
334 vertices.SetData( vertexData );
336 unsigned int indexData[15] = { 0,1,2,0,2,3,0,3,4,0,4,5,0,5,6 };
337 Property::Map indexFormat;
338 indexFormat["indices"] = Property::UNSIGNED_INTEGER;
339 PropertyBuffer indices = PropertyBuffer::New( indexFormat, 15u );
340 indices.SetData( indexData );
342 Geometry meshGeometry = Geometry::New();
343 meshGeometry.AddVertexBuffer( vertices );
344 meshGeometry.SetIndexBuffer( indices );
347 std::ostringstream vertexShaderStringStream;
348 vertexShaderStringStream<<VERTEX_SHADER_PREFIX<<VERTEX_SHADER;
349 Shader shader = Shader::New( vertexShaderStringStream.str(), FRAGMENT_SHADER );
350 Material material = Material::New( shader );
353 Renderer renderer = Renderer::New( meshGeometry, material );
355 mStencilActor = Actor::New();
356 mStencilActor.AddRenderer( renderer );
357 mStencilActor.SetSize(1.f, 1.f);
359 // register properties
360 mStartAngleIndex = mStencilActor.RegisterProperty("start-angle", 0.f);
361 mStencilActor.AddUniformMapping( mStartAngleIndex, "uStartAngle " );
362 mRotationAngleIndex = mStencilActor.RegisterProperty("rotation-angle", initialSector.radian);
363 mStencilActor.AddUniformMapping( mRotationAngleIndex, "uRotationAngle" );
365 mStencilActor.SetDrawMode( DrawMode::STENCIL );
366 mStencilActor.SetPositionInheritanceMode(USE_PARENT_POSITION);