X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fanimation%2Fscene-graph-animator.h;h=d1cac15b4d071fb1855412eb854a9343a080ea1b;hb=77de4c4ae763aeb42c5bf02be9191ab0694b48a1;hp=13c245f580f1068eceb181fee23a4327b9ee3cb4;hpb=d46e06b577afa0f99a293d257a834add7c2f3755;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/animation/scene-graph-animator.h b/dali/internal/update/animation/scene-graph-animator.h index 13c245f..d1cac15 100644 --- a/dali/internal/update/animation/scene-graph-animator.h +++ b/dali/internal/update/animation/scene-graph-animator.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,21 +18,21 @@ * */ -// EXTERNAL INCLUDES -#include - // INTERNAL INCLUDES -#include +#include #include #include #include #include -#include +#include #include #include +#include #include #include #include +#include + namespace Dali { @@ -40,6 +40,10 @@ namespace Dali namespace Internal { +typedef Dali::Animation::Interpolation Interpolation; + +struct AnimatorFunctionBase; + namespace SceneGraph { @@ -65,10 +69,12 @@ public: */ AnimatorBase() : mDurationSeconds(1.0f), - mInitialDelaySeconds(0.0f), - mAlphaFunc(AlphaFunctions::Linear), + mIntervalDelaySeconds(0.0f), + mAlphaFunction(AlphaFunction::DEFAULT), mDisconnectAction(Dali::Animation::BakeFinal), - mActive(false) + mActive(false), + mEnabled(true), + mConnectedToSceneGraph(false) { } @@ -80,6 +86,11 @@ public: } /** + * Called when Animator is added to the scene-graph in update-thread. + */ + virtual void ConnectToSceneGraph() = 0; + + /** * Set the duration of the animator. * @pre durationSeconds must be zero or greater; zero is useful when animating boolean values. * @param [in] seconds Duration in seconds. @@ -95,7 +106,7 @@ public: * Retrieve the duration of the animator. * @return The duration in seconds. */ - float GetDuration() + float GetDuration() const { return mDurationSeconds; } @@ -105,36 +116,166 @@ public: * The default is zero i.e. no delay. * @param [in] seconds The delay in seconds. */ - void SetInitialDelay(float seconds) + void SetIntervalDelay(float seconds) { - mInitialDelaySeconds = seconds; + mIntervalDelaySeconds = seconds; } /** - * Retrieve the initial delay of the animator. + * Retrieve the delay before the animator should take effect. * @return The delay in seconds. */ - float GetInitialDelay() + float GetIntervalDelay() const { - return mInitialDelaySeconds; + return mIntervalDelaySeconds; } /** * Set the alpha function for an animator. * @param [in] alphaFunc The alpha function to apply to the animation progress. */ - void SetAlphaFunc(AlphaFunc alphaFunc) + void SetAlphaFunction(const AlphaFunction& alphaFunction) { - mAlphaFunc = alphaFunc; + mAlphaFunction = alphaFunction; } /** * Retrieve the alpha function of an animator. * @return The function. */ - AlphaFunc GetAlphaFunc() const + AlphaFunction GetAlphaFunction() const + { + return mAlphaFunction; + } + + /* + * Applies the alpha function to the specified progress + * @param[in] Current progress + * @return The progress after the alpha function has been aplied + */ + float ApplyAlphaFunction( float progress ) const { - return mAlphaFunc; + float result = progress; + + AlphaFunction::Mode alphaFunctionMode( mAlphaFunction.GetMode() ); + if( alphaFunctionMode == AlphaFunction::BUILTIN_FUNCTION ) + { + switch(mAlphaFunction.GetBuiltinFunction()) + { + case AlphaFunction::DEFAULT: + case AlphaFunction::LINEAR: + { + break; + } + case AlphaFunction::REVERSE: + { + result = 1.0f-progress; + break; + } + case AlphaFunction::EASE_IN_SQUARE: + { + result = progress * progress; + break; + } + case AlphaFunction::EASE_OUT_SQUARE: + { + result = 1.0f - (1.0f-progress) * (1.0f-progress); + break; + } + case AlphaFunction::EASE_IN: + { + result = progress * progress * progress; + break; + } + case AlphaFunction::EASE_OUT: + { + result = (progress-1.0f) * (progress-1.0f) * (progress-1.0f) + 1.0f; + break; + } + case AlphaFunction::EASE_IN_OUT: + { + result = progress*progress*(3.0f-2.0f*progress); + break; + } + case AlphaFunction::EASE_IN_SINE: + { + result = -1.0f * cosf(progress * Math::PI_2) + 1.0f; + break; + } + case AlphaFunction::EASE_OUT_SINE: + { + result = sinf(progress * Math::PI_2); + break; + } + case AlphaFunction::EASE_IN_OUT_SINE: + { + result = -0.5f * (cosf(Math::PI * progress) - 1.0f); + break; + } + case AlphaFunction::BOUNCE: + { + result = sinf(progress * Math::PI); + break; + } + case AlphaFunction::SIN: + { + result = 0.5f - cosf(progress * 2.0f * Math::PI) * 0.5f; + break; + } + case AlphaFunction::EASE_OUT_BACK: + { + const float sqrt2 = 1.70158f; + progress -= 1.0f; + result = 1.0f + progress * progress * ( ( sqrt2 + 1.0f ) * progress + sqrt2 ); + break; + } + case AlphaFunction::COUNT: + { + break; + } + } + } + else if( alphaFunctionMode == AlphaFunction::CUSTOM_FUNCTION ) + { + AlphaFunctionPrototype customFunction = mAlphaFunction.GetCustomFunction(); + if( customFunction ) + { + result = customFunction(progress); + } + } + else + { + //If progress is very close to 0 or very close to 1 we don't need to evaluate the curve as the result will + //be almost 0 or almost 1 respectively + if( ( progress > Math::MACHINE_EPSILON_1 ) && ((1.0f - progress) > Math::MACHINE_EPSILON_1) ) + { + Dali::Vector4 controlPoints = mAlphaFunction.GetBezierControlPoints(); + + static const float tolerance = 0.001f; //10 iteration max + + //Perform a binary search on the curve + float lowerBound(0.0f); + float upperBound(1.0f); + float currentT(0.5f); + float currentX = EvaluateCubicBezier( controlPoints.x, controlPoints.z, currentT); + while( fabs( progress - currentX ) > tolerance ) + { + if( progress > currentX ) + { + lowerBound = currentT; + } + else + { + upperBound = currentT; + } + currentT = (upperBound+lowerBound)*0.5f; + currentX = EvaluateCubicBezier( controlPoints.x, controlPoints.z, currentT); + } + result = EvaluateCubicBezier( controlPoints.y, controlPoints.w, currentT); + } + } + + return result; } /** @@ -158,7 +299,7 @@ public: /** * Whether the animator is active or not. - * @param [in] action The disconnect action. + * @param [in] active The new active state. * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected. * @note When the property owner is disconnected, the active state is set to false. */ @@ -176,38 +317,54 @@ public: return mActive; } + /* + * Retrive wheter the animator's target object is valid and on the stage. + * @return The enabled state. + */ + bool IsEnabled() const + { + return mEnabled; + } /** - * This must be called when the animator is attached to the scene-graph. - * @pre The animatable scene object must also be attached to the scene-graph. - * @param[in] propertyOwner The scene-object that owns the animatable property. + * Returns wheter the target object of the animator is still valid + * or has been destroyed. + * @return True if animator is orphan, false otherwise * + * @note The SceneGraph::Animation will delete any orphan animator in its Update method. */ - virtual void Attach( PropertyOwner* propertyOwner ) = 0; + virtual bool Orphan() = 0; /** * Update the scene object attached to the animator. * @param[in] bufferIndex The buffer to animate. * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point. * @param[in] bake Bake. - * @return True if the update was applied, false if the animator has been orphaned. */ - virtual bool Update(BufferIndex bufferIndex, float progress, bool bake) = 0; + virtual void Update(BufferIndex bufferIndex, float progress, bool bake) = 0; + +protected: /** - * Query whether the animator is still attached to a scene object. - * The attachment will be automatically severed, when the object is destroyed. - * @return True if the animator is attached. + * Helper function to evaluate a cubic bezier curve assuming first point is at 0.0 and last point is at 1.0 + * @param[in] p0 First control point of the bezier curve + * @param[in] p1 Second control point of the bezier curve + * @param[in] t A floating point value between 0.0 and 1.0 + * @return Value of the curve at progress t */ - virtual bool IsAttached() const = 0; - -protected: + inline float EvaluateCubicBezier( float p0, float p1, float t ) const + { + float tSquare = t*t; + return 3.0f*(1.0f-t)*(1.0f-t)*t*p0 + 3.0f*(1.0f-t)*tSquare*p1 + tSquare*t; + } float mDurationSeconds; - float mInitialDelaySeconds; + float mIntervalDelaySeconds; - AlphaFunc mAlphaFunc; + AlphaFunction mAlphaFunction; - Dali::Animation::EndAction mDisconnectAction; - bool mActive:1; + Dali::Animation::EndAction mDisconnectAction; ///< EndAction to apply when target object gets disconnected from the stage. + bool mActive:1; ///< Animator is "active" while it's running. + bool mEnabled:1; ///< Animator is "enabled" while its target object is valid and on the stage. + bool mConnectedToSceneGraph:1; ///< True if ConnectToSceneGraph() has been called in update-thread. }; /** @@ -218,8 +375,6 @@ class Animator : public AnimatorBase, public PropertyOwner::Observer { public: - typedef boost::function< PropertyType (float, const PropertyType&) > AnimatorFunction; - /** * Construct a new property animator. * @param[in] property The animatable property; only valid while the Animator is attached. @@ -228,19 +383,21 @@ public: * @param[in] timePeriod The time period of this animation. * @return A newly allocated animator. */ - static AnimatorBase* New( const PropertyBase& property, - AnimatorFunction animatorFunction, + static AnimatorBase* New( const PropertyOwner& propertyOwner, + const PropertyBase& property, + AnimatorFunctionBase* animatorFunction, AlphaFunction alphaFunction, const TimePeriod& timePeriod ) { typedef Animator< PropertyType, PropertyAccessorType > AnimatorType; // The property was const in the actor-thread, but animators are used in the scene-graph thread. - AnimatorType* animator = new AnimatorType( const_cast( &property ), + AnimatorType* animator = new AnimatorType( const_cast( &propertyOwner ), + const_cast( &property ), animatorFunction ); - animator->SetAlphaFunc( alphaFunction ); - animator->SetInitialDelay( timePeriod.delaySeconds ); + animator->SetAlphaFunction( alphaFunction ); + animator->SetIntervalDelay( timePeriod.delaySeconds ); animator->SetDuration( timePeriod.durationSeconds ); return animator; @@ -251,61 +408,182 @@ public: */ virtual ~Animator() { - if (mPropertyOwner) + if (mPropertyOwner && mConnectedToSceneGraph) { mPropertyOwner->RemoveObserver(*this); } + + delete mAnimatorFunction; } /** - * From AnimatorBase. - * @param[in] propertyOwner The scene-object that owns the animatable property. + * Called when Animator is added to the scene-graph in update-thread. + */ + virtual void ConnectToSceneGraph() + { + mConnectedToSceneGraph = true; + mPropertyOwner->AddObserver(*this); + } + + /** + * Called when mPropertyOwner is connected to the scene graph. */ - virtual void Attach( PropertyOwner* propertyOwner ) + virtual void PropertyOwnerConnected( PropertyOwner& owner ) { - mPropertyOwner = propertyOwner; + mEnabled = true; + } - if (mPropertyOwner) + /** + * Called when mPropertyOwner is disconnected from the scene graph. + */ + virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner ) + { + // If we are active, then bake the value if required + if ( mActive && mDisconnectAction != Dali::Animation::Discard ) { - mPropertyOwner->AddObserver(*this); + // Bake to target-value if BakeFinal, otherwise bake current value + Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true ); } + + mActive = false; + mEnabled = false; + } + + /** + * Called shortly before mPropertyOwner is destroyed + */ + virtual void PropertyOwnerDestroyed( PropertyOwner& owner ) + { + mPropertyOwner = NULL; } /** * From AnimatorBase. */ - virtual bool Update( BufferIndex bufferIndex, float progress, bool bake ) + virtual void Update( BufferIndex bufferIndex, float progress, bool bake ) { - // If the object dies, the animator has no effect - if ( mPropertyOwner ) + float alpha = ApplyAlphaFunction(progress); + + const PropertyType& current = mPropertyAccessor.Get( bufferIndex ); + + const PropertyType result = (*mAnimatorFunction)( alpha, current ); + if ( bake ) + { + mPropertyAccessor.Bake( bufferIndex, result ); + } + else { - float alpha = mAlphaFunc( progress ); + mPropertyAccessor.Set( bufferIndex, result ); + } - const PropertyType& current = mPropertyAccessor.Get( bufferIndex ); + mCurrentProgress = progress; + } - const PropertyType result = mAnimatorFunction( alpha, current ); + /** + * From AnimatorBase. + */ + virtual bool Orphan() + { + return (mPropertyOwner == NULL); + } - if ( bake ) - { - mPropertyAccessor.Bake( bufferIndex, result ); - } - else - { - mPropertyAccessor.Set( bufferIndex, result ); - } +private: + + /** + * Private constructor; see also Animator::New(). + */ + Animator( PropertyOwner* propertyOwner, + PropertyBase* property, + AnimatorFunctionBase* animatorFunction ) + : mPropertyOwner( propertyOwner ), + mPropertyAccessor( property ), + mAnimatorFunction( animatorFunction ), + mCurrentProgress( 0.0f ) + { + // WARNING - this object is created in the event-thread + // The scene-graph mPropertyOwner object cannot be observed here + } + + // Undefined + Animator( const Animator& ); + + // Undefined + Animator& operator=( const Animator& ); + +protected: + + PropertyOwner* mPropertyOwner; + PropertyAccessorType mPropertyAccessor; + + AnimatorFunctionBase* mAnimatorFunction; + float mCurrentProgress; +}; + + + +/** + * An animator for a specific property type PropertyType. + */ +template +class AnimatorTransformProperty : public AnimatorBase, public PropertyOwner::Observer +{ +public: + + /** + * Construct a new property animator. + * @param[in] property The animatable property; only valid while the Animator is attached. + * @param[in] animatorFunction The function used to animate the property. + * @param[in] alphaFunction The alpha function to apply. + * @param[in] timePeriod The time period of this animation. + * @return A newly allocated animator. + */ + static AnimatorBase* New( const PropertyOwner& propertyOwner, + const PropertyBase& property, + AnimatorFunctionBase* animatorFunction, + AlphaFunction alphaFunction, + const TimePeriod& timePeriod ) + { + + // The property was const in the actor-thread, but animators are used in the scene-graph thread. + AnimatorTransformProperty* animator = new AnimatorTransformProperty( const_cast( &propertyOwner ), + const_cast( &property ), + animatorFunction ); - mCurrentProgress = progress; + animator->SetAlphaFunction( alphaFunction ); + animator->SetIntervalDelay( timePeriod.delaySeconds ); + animator->SetDuration( timePeriod.durationSeconds ); + + return animator; + } + + /** + * Virtual destructor. + */ + virtual ~AnimatorTransformProperty() + { + if (mPropertyOwner && mConnectedToSceneGraph) + { + mPropertyOwner->RemoveObserver(*this); } - return IsAttached(); // return false if orphaned + delete mAnimatorFunction; } /** - * From AnimatorBase. + * Called when Animator is added to the scene-graph in update-thread. + */ + virtual void ConnectToSceneGraph() + { + mConnectedToSceneGraph = true; + mPropertyOwner->AddObserver(*this); + } + + /** + * Called when mPropertyOwner is connected to the scene graph. */ - virtual bool IsAttached() const + virtual void PropertyOwnerConnected( PropertyOwner& owner ) { - return NULL != mPropertyOwner; + mEnabled = true; } /** @@ -321,17 +599,47 @@ public: } mActive = false; - mPropertyOwner = NULL; - mPropertyAccessor.Reset(); + mEnabled = false; } /** - * Called shortly before mPropertyOwner is destroyed, along with its property. + * Called shortly before mPropertyOwner is destroyed */ virtual void PropertyOwnerDestroyed( PropertyOwner& owner ) { mPropertyOwner = NULL; - mPropertyAccessor.Reset(); + } + + /** + * From AnimatorBase. + */ + virtual void Update( BufferIndex bufferIndex, float progress, bool bake ) + { + float alpha = ApplyAlphaFunction(progress); + + const T& current = mPropertyAccessor.Get( bufferIndex ); + + const T result = (*mAnimatorFunction)( alpha, current ); + + + if ( bake ) + { + mPropertyAccessor.Bake( bufferIndex, result ); + } + else + { + mPropertyAccessor.Set( bufferIndex, result ); + } + + mCurrentProgress = progress; + } + + /** + * From AnimatorBase. + */ + virtual bool Orphan() + { + return (mPropertyOwner == NULL); } private: @@ -339,72 +647,103 @@ private: /** * Private constructor; see also Animator::New(). */ - Animator( PropertyBase* property, - AnimatorFunction animatorFunction ) - : mPropertyOwner( NULL ), + AnimatorTransformProperty( PropertyOwner* propertyOwner, + PropertyBase* property, + AnimatorFunctionBase* animatorFunction ) + : mPropertyOwner( propertyOwner ), mPropertyAccessor( property ), mAnimatorFunction( animatorFunction ), mCurrentProgress( 0.0f ) { + // WARNING - this object is created in the event-thread + // The scene-graph mPropertyOwner object cannot be observed here } // Undefined - Animator( const Animator& ); + AnimatorTransformProperty( const AnimatorTransformProperty& ); // Undefined - Animator& operator=( const Animator& ); + AnimatorTransformProperty& operator=( const AnimatorTransformProperty& ); protected: PropertyOwner* mPropertyOwner; PropertyAccessorType mPropertyAccessor; - AnimatorFunction mAnimatorFunction; + AnimatorFunctionBase* mAnimatorFunction; float mCurrentProgress; }; } // namespace SceneGraph +/* + * AnimatorFunction base class. + * All update functions must inherit from AnimatorFunctionBase and overload the appropiate "()" operator + */ +struct AnimatorFunctionBase +{ + /** + * Constructor + */ + AnimatorFunctionBase(){} -// Common Update functions + /* + * Virtual destructor (Intended as base class) + */ + virtual ~AnimatorFunctionBase(){} -struct AnimateByFloat -{ - AnimateByFloat(const float& relativeValue) - : mRelative(relativeValue) + ///Stub "()" operators. + virtual bool operator()(float progress, const bool& property) { + return property; } - float operator()(float alpha, const float& property) + virtual float operator()(float progress, const int& property) { - return float(property + mRelative * alpha); + return property; } - float mRelative; -}; + virtual float operator()(float progress, const unsigned int& property) + { + return property; + } -struct AnimateToFloat -{ - AnimateToFloat(const float& targetValue) - : mTarget(targetValue) + virtual float operator()(float progress, const float& property) { + return property; } - float operator()(float alpha, const float& property) + virtual Vector2 operator()(float progress, const Vector2& property) { - return float(property + ((mTarget - property) * alpha)); + return property; } - float mTarget; + virtual Vector3 operator()(float progress, const Vector3& property) + { + return property; + } + + virtual Vector4 operator()(float progress, const Vector4& property) + { + return property; + } + + virtual Quaternion operator()(float progress, const Quaternion& property) + { + return property; + } }; -struct AnimateByInteger +// Update functions + +struct AnimateByInteger : public AnimatorFunctionBase { AnimateByInteger(const int& relativeValue) : mRelative(relativeValue) { } + using AnimatorFunctionBase::operator(); float operator()(float alpha, const int& property) { return int(property + mRelative * alpha + 0.5f ); @@ -413,13 +752,14 @@ struct AnimateByInteger int mRelative; }; -struct AnimateToInteger +struct AnimateToInteger : public AnimatorFunctionBase { AnimateToInteger(const int& targetValue) : mTarget(targetValue) { } + using AnimatorFunctionBase::operator(); float operator()(float alpha, const int& property) { return int(property + ((mTarget - property) * alpha) + 0.5f); @@ -428,13 +768,46 @@ struct AnimateToInteger int mTarget; }; -struct AnimateByVector2 +struct AnimateByFloat : public AnimatorFunctionBase +{ + AnimateByFloat(const float& relativeValue) + : mRelative(relativeValue) + { + } + + using AnimatorFunctionBase::operator(); + float operator()(float alpha, const float& property) + { + return float(property + mRelative * alpha); + } + + float mRelative; +}; + +struct AnimateToFloat : public AnimatorFunctionBase +{ + AnimateToFloat(const float& targetValue) + : mTarget(targetValue) + { + } + + using AnimatorFunctionBase::operator(); + float operator()(float alpha, const float& property) + { + return float(property + ((mTarget - property) * alpha)); + } + + float mTarget; +}; + +struct AnimateByVector2 : public AnimatorFunctionBase { AnimateByVector2(const Vector2& relativeValue) : mRelative(relativeValue) { } + using AnimatorFunctionBase::operator(); Vector2 operator()(float alpha, const Vector2& property) { return Vector2(property + mRelative * alpha); @@ -443,13 +816,14 @@ struct AnimateByVector2 Vector2 mRelative; }; -struct AnimateToVector2 +struct AnimateToVector2 : public AnimatorFunctionBase { AnimateToVector2(const Vector2& targetValue) : mTarget(targetValue) { } + using AnimatorFunctionBase::operator(); Vector2 operator()(float alpha, const Vector2& property) { return Vector2(property + ((mTarget - property) * alpha)); @@ -458,13 +832,14 @@ struct AnimateToVector2 Vector2 mTarget; }; -struct AnimateByVector3 +struct AnimateByVector3 : public AnimatorFunctionBase { AnimateByVector3(const Vector3& relativeValue) : mRelative(relativeValue) { } + using AnimatorFunctionBase::operator(); Vector3 operator()(float alpha, const Vector3& property) { return Vector3(property + mRelative * alpha); @@ -473,13 +848,14 @@ struct AnimateByVector3 Vector3 mRelative; }; -struct AnimateToVector3 +struct AnimateToVector3 : public AnimatorFunctionBase { AnimateToVector3(const Vector3& targetValue) : mTarget(targetValue) { } + using AnimatorFunctionBase::operator(); Vector3 operator()(float alpha, const Vector3& property) { return Vector3(property + ((mTarget - property) * alpha)); @@ -488,13 +864,14 @@ struct AnimateToVector3 Vector3 mTarget; }; -struct AnimateByVector4 +struct AnimateByVector4 : public AnimatorFunctionBase { AnimateByVector4(const Vector4& relativeValue) : mRelative(relativeValue) { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float alpha, const Vector4& property) { return Vector4(property + mRelative * alpha); @@ -503,13 +880,14 @@ struct AnimateByVector4 Vector4 mRelative; }; -struct AnimateToVector4 +struct AnimateToVector4 : public AnimatorFunctionBase { AnimateToVector4(const Vector4& targetValue) : mTarget(targetValue) { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float alpha, const Vector4& property) { return Vector4(property + ((mTarget - property) * alpha)); @@ -518,13 +896,14 @@ struct AnimateToVector4 Vector4 mTarget; }; -struct AnimateByOpacity +struct AnimateByOpacity : public AnimatorFunctionBase { AnimateByOpacity(const float& relativeValue) : mRelative(relativeValue) { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float alpha, const Vector4& property) { Vector4 result(property); @@ -536,13 +915,14 @@ struct AnimateByOpacity float mRelative; }; -struct AnimateToOpacity +struct AnimateToOpacity : public AnimatorFunctionBase { AnimateToOpacity(const float& targetValue) : mTarget(targetValue) { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float alpha, const Vector4& property) { Vector4 result(property); @@ -554,13 +934,14 @@ struct AnimateToOpacity float mTarget; }; -struct AnimateByBoolean +struct AnimateByBoolean : public AnimatorFunctionBase { AnimateByBoolean(bool relativeValue) : mRelative(relativeValue) { } + using AnimatorFunctionBase::operator(); bool operator()(float alpha, const bool& property) { // Alpha is not useful here, just keeping to the same template as other update functors @@ -570,13 +951,14 @@ struct AnimateByBoolean bool mRelative; }; -struct AnimateToBoolean +struct AnimateToBoolean : public AnimatorFunctionBase { AnimateToBoolean(bool targetValue) : mTarget(targetValue) { } + using AnimatorFunctionBase::operator(); bool operator()(float alpha, const bool& property) { // Alpha is not useful here, just keeping to the same template as other update functors @@ -586,14 +968,15 @@ struct AnimateToBoolean bool mTarget; }; -struct RotateByAngleAxis +struct RotateByAngleAxis : public AnimatorFunctionBase { RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis) - : mAngleRadians(angleRadians), - mAxis(axis.x, axis.y, axis.z, 0.0f) + : mAngleRadians( angleRadians ), + mAxis(axis.x, axis.y, axis.z) { } + using AnimatorFunctionBase::operator(); Quaternion operator()(float alpha, const Quaternion& rotation) { if (alpha > 0.0f) @@ -604,17 +987,18 @@ struct RotateByAngleAxis return rotation; } - float mAngleRadians; - Vector4 mAxis; + Radian mAngleRadians; + Vector3 mAxis; }; -struct RotateToQuaternion +struct RotateToQuaternion : public AnimatorFunctionBase { RotateToQuaternion(const Quaternion& targetValue) : mTarget(targetValue) { } + using AnimatorFunctionBase::operator(); Quaternion operator()(float alpha, const Quaternion& rotation) { return Quaternion::Slerp(rotation, mTarget, alpha); @@ -624,18 +1008,19 @@ struct RotateToQuaternion }; -struct KeyFrameBooleanFunctor +struct KeyFrameBooleanFunctor : public AnimatorFunctionBase { KeyFrameBooleanFunctor(KeyFrameBooleanPtr keyFrames) : mKeyFrames(keyFrames) { } + using AnimatorFunctionBase::operator(); bool operator()(float progress, const bool& property) { if(mKeyFrames->IsActive(progress)) { - return mKeyFrames->GetValue(progress); + return mKeyFrames->GetValue(progress, Dali::Animation::Linear); } return property; } @@ -643,114 +1028,125 @@ struct KeyFrameBooleanFunctor KeyFrameBooleanPtr mKeyFrames; }; -struct KeyFrameNumberFunctor +struct KeyFrameIntegerFunctor : public AnimatorFunctionBase { - KeyFrameNumberFunctor(KeyFrameNumberPtr keyFrames) - : mKeyFrames(keyFrames) + KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames, Interpolation interpolation) + : mKeyFrames(keyFrames),mInterpolation(interpolation) { } - float operator()(float progress, const float& property) + using AnimatorFunctionBase::operator(); + float operator()(float progress, const int& property) { if(mKeyFrames->IsActive(progress)) { - return mKeyFrames->GetValue(progress); + return mKeyFrames->GetValue(progress, mInterpolation); } return property; } - KeyFrameNumberPtr mKeyFrames; + KeyFrameIntegerPtr mKeyFrames; + Interpolation mInterpolation; }; -struct KeyFrameIntegerFunctor +struct KeyFrameNumberFunctor : public AnimatorFunctionBase { - KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames) - : mKeyFrames(keyFrames) + KeyFrameNumberFunctor(KeyFrameNumberPtr keyFrames, Interpolation interpolation) + : mKeyFrames(keyFrames),mInterpolation(interpolation) { } - float operator()(float progress, const int& property) + using AnimatorFunctionBase::operator(); + float operator()(float progress, const float& property) { if(mKeyFrames->IsActive(progress)) { - return mKeyFrames->GetValue(progress); + return mKeyFrames->GetValue(progress, mInterpolation); } return property; } - KeyFrameIntegerPtr mKeyFrames; + KeyFrameNumberPtr mKeyFrames; + Interpolation mInterpolation; }; -struct KeyFrameVector2Functor +struct KeyFrameVector2Functor : public AnimatorFunctionBase { - KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames) - : mKeyFrames(keyFrames) + KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames, Interpolation interpolation) + : mKeyFrames(keyFrames),mInterpolation(interpolation) { } + using AnimatorFunctionBase::operator(); Vector2 operator()(float progress, const Vector2& property) { if(mKeyFrames->IsActive(progress)) { - return mKeyFrames->GetValue(progress); + return mKeyFrames->GetValue(progress, mInterpolation); } return property; } KeyFrameVector2Ptr mKeyFrames; + Interpolation mInterpolation; }; -struct KeyFrameVector3Functor +struct KeyFrameVector3Functor : public AnimatorFunctionBase { - KeyFrameVector3Functor(KeyFrameVector3Ptr keyFrames) - : mKeyFrames(keyFrames) + KeyFrameVector3Functor(KeyFrameVector3Ptr keyFrames, Interpolation interpolation) + : mKeyFrames(keyFrames),mInterpolation(interpolation) { } + using AnimatorFunctionBase::operator(); Vector3 operator()(float progress, const Vector3& property) { if(mKeyFrames->IsActive(progress)) { - return mKeyFrames->GetValue(progress); + return mKeyFrames->GetValue(progress, mInterpolation); } return property; } KeyFrameVector3Ptr mKeyFrames; + Interpolation mInterpolation; }; -struct KeyFrameVector4Functor +struct KeyFrameVector4Functor : public AnimatorFunctionBase { - KeyFrameVector4Functor(KeyFrameVector4Ptr keyFrames) - : mKeyFrames(keyFrames) + KeyFrameVector4Functor(KeyFrameVector4Ptr keyFrames, Interpolation interpolation) + : mKeyFrames(keyFrames),mInterpolation(interpolation) { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float progress, const Vector4& property) { if(mKeyFrames->IsActive(progress)) { - return mKeyFrames->GetValue(progress); + return mKeyFrames->GetValue(progress, mInterpolation); } return property; } KeyFrameVector4Ptr mKeyFrames; + Interpolation mInterpolation; }; -struct KeyFrameQuaternionFunctor +struct KeyFrameQuaternionFunctor : public AnimatorFunctionBase { KeyFrameQuaternionFunctor(KeyFrameQuaternionPtr keyFrames) : mKeyFrames(keyFrames) { } + using AnimatorFunctionBase::operator(); Quaternion operator()(float progress, const Quaternion& property) { if(mKeyFrames->IsActive(progress)) { - return mKeyFrames->GetValue(progress); + return mKeyFrames->GetValue(progress, Dali::Animation::Linear); } return property; } @@ -758,22 +1154,25 @@ struct KeyFrameQuaternionFunctor KeyFrameQuaternionPtr mKeyFrames; }; -struct PathPositionFunctor +struct PathPositionFunctor : public AnimatorFunctionBase { PathPositionFunctor( PathPtr path ) : mPath(path) { } + using AnimatorFunctionBase::operator(); Vector3 operator()(float progress, const Vector3& property) { - return mPath->SamplePosition(progress ); + Vector3 position(property); + static_cast( mPath->SamplePosition(progress, position) ); + return position; } PathPtr mPath; }; -struct PathRotationFunctor +struct PathRotationFunctor : public AnimatorFunctionBase { PathRotationFunctor( PathPtr path, const Vector3& forward ) : mPath(path), @@ -782,17 +1181,24 @@ struct PathRotationFunctor mForward.Normalize(); } + using AnimatorFunctionBase::operator(); Quaternion operator()(float progress, const Quaternion& property) { - Vector3 tangent( mPath->SampleTangent(progress) ); - return Quaternion( mForward, tangent ); + Vector3 tangent; + if( mPath->SampleTangent(progress, tangent) ) + { + return Quaternion( mForward, tangent ); + } + else + { + return property; + } } PathPtr mPath; Vector3 mForward; }; - } // namespace Internal } // namespace Dali