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=8b30afd4a3a04fbf48646f1aa86f11741cbd8c08;hpb=b5effb133a41a6542033267da856b4986d983564;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 8b30afd..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. @@ -19,7 +19,7 @@ */ // INTERNAL INCLUDES -#include +#include #include #include #include @@ -31,6 +31,8 @@ #include #include #include +#include + namespace Dali { @@ -67,11 +69,12 @@ public: */ AnimatorBase() : mDurationSeconds(1.0f), - mInitialDelaySeconds(0.0f), + mIntervalDelaySeconds(0.0f), mAlphaFunction(AlphaFunction::DEFAULT), mDisconnectAction(Dali::Animation::BakeFinal), mActive(false), - mEnabled(true) + mEnabled(true), + mConnectedToSceneGraph(false) { } @@ -83,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. @@ -98,7 +106,7 @@ public: * Retrieve the duration of the animator. * @return The duration in seconds. */ - float GetDuration() + float GetDuration() const { return mDurationSeconds; } @@ -108,18 +116,18 @@ 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; } /** @@ -221,8 +229,10 @@ public: result = 1.0f + progress * progress * ( ( sqrt2 + 1.0f ) * progress + sqrt2 ); break; } - default: + case AlphaFunction::COUNT: + { break; + } } } else if( alphaFunctionMode == AlphaFunction::CUSTOM_FUNCTION ) @@ -347,13 +357,14 @@ protected: } float mDurationSeconds; - float mInitialDelaySeconds; + float mIntervalDelaySeconds; AlphaFunction mAlphaFunction; 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. }; /** @@ -386,7 +397,7 @@ public: animatorFunction ); animator->SetAlphaFunction( alphaFunction ); - animator->SetInitialDelay( timePeriod.delaySeconds ); + animator->SetIntervalDelay( timePeriod.delaySeconds ); animator->SetDuration( timePeriod.durationSeconds ); return animator; @@ -397,15 +408,21 @@ public: */ virtual ~Animator() { - if (mPropertyOwner) + if (mPropertyOwner && mConnectedToSceneGraph) { mPropertyOwner->RemoveObserver(*this); } - if( mAnimatorFunction ) - { - delete mAnimatorFunction; - } + delete mAnimatorFunction; + } + + /** + * Called when Animator is added to the scene-graph in update-thread. + */ + virtual void ConnectToSceneGraph() + { + mConnectedToSceneGraph = true; + mPropertyOwner->AddObserver(*this); } /** @@ -438,8 +455,6 @@ public: virtual void PropertyOwnerDestroyed( PropertyOwner& owner ) { mPropertyOwner = NULL; - mPropertyAccessor.Reset(); - mEnabled = false; } /** @@ -485,7 +500,8 @@ private: mAnimatorFunction( animatorFunction ), mCurrentProgress( 0.0f ) { - mPropertyOwner->AddObserver(*this); + // WARNING - this object is created in the event-thread + // The scene-graph mPropertyOwner object cannot be observed here } // Undefined @@ -503,6 +519,161 @@ protected: 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 ); + + animator->SetAlphaFunction( alphaFunction ); + animator->SetIntervalDelay( timePeriod.delaySeconds ); + animator->SetDuration( timePeriod.durationSeconds ); + + return animator; + } + + /** + * Virtual destructor. + */ + virtual ~AnimatorTransformProperty() + { + if (mPropertyOwner && mConnectedToSceneGraph) + { + mPropertyOwner->RemoveObserver(*this); + } + + delete mAnimatorFunction; + } + + /** + * 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 PropertyOwnerConnected( PropertyOwner& owner ) + { + mEnabled = true; + } + + /** + * 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 ) + { + // 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 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: + + /** + * Private constructor; see also Animator::New(). + */ + 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 + AnimatorTransformProperty( const AnimatorTransformProperty& ); + + // Undefined + AnimatorTransformProperty& operator=( const AnimatorTransformProperty& ); + +protected: + + PropertyOwner* mPropertyOwner; + PropertyAccessorType mPropertyAccessor; + + AnimatorFunctionBase* mAnimatorFunction; + float mCurrentProgress; +}; + } // namespace SceneGraph /* @@ -572,6 +743,7 @@ struct AnimateByInteger : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); float operator()(float alpha, const int& property) { return int(property + mRelative * alpha + 0.5f ); @@ -587,6 +759,7 @@ struct AnimateToInteger : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); float operator()(float alpha, const int& property) { return int(property + ((mTarget - property) * alpha) + 0.5f); @@ -602,6 +775,7 @@ struct AnimateByFloat : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); float operator()(float alpha, const float& property) { return float(property + mRelative * alpha); @@ -617,6 +791,7 @@ struct AnimateToFloat : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); float operator()(float alpha, const float& property) { return float(property + ((mTarget - property) * alpha)); @@ -632,6 +807,7 @@ struct AnimateByVector2 : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector2 operator()(float alpha, const Vector2& property) { return Vector2(property + mRelative * alpha); @@ -647,6 +823,7 @@ struct AnimateToVector2 : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector2 operator()(float alpha, const Vector2& property) { return Vector2(property + ((mTarget - property) * alpha)); @@ -662,6 +839,7 @@ struct AnimateByVector3 : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector3 operator()(float alpha, const Vector3& property) { return Vector3(property + mRelative * alpha); @@ -677,6 +855,7 @@ struct AnimateToVector3 : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector3 operator()(float alpha, const Vector3& property) { return Vector3(property + ((mTarget - property) * alpha)); @@ -692,6 +871,7 @@ struct AnimateByVector4 : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float alpha, const Vector4& property) { return Vector4(property + mRelative * alpha); @@ -707,6 +887,7 @@ struct AnimateToVector4 : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float alpha, const Vector4& property) { return Vector4(property + ((mTarget - property) * alpha)); @@ -722,6 +903,7 @@ struct AnimateByOpacity : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float alpha, const Vector4& property) { Vector4 result(property); @@ -740,6 +922,7 @@ struct AnimateToOpacity : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float alpha, const Vector4& property) { Vector4 result(property); @@ -758,6 +941,7 @@ struct AnimateByBoolean : public AnimatorFunctionBase { } + 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 @@ -774,6 +958,7 @@ struct AnimateToBoolean : public AnimatorFunctionBase { } + 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 @@ -791,6 +976,7 @@ struct RotateByAngleAxis : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Quaternion operator()(float alpha, const Quaternion& rotation) { if (alpha > 0.0f) @@ -812,6 +998,7 @@ struct RotateToQuaternion : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Quaternion operator()(float alpha, const Quaternion& rotation) { return Quaternion::Slerp(rotation, mTarget, alpha); @@ -828,6 +1015,7 @@ struct KeyFrameBooleanFunctor : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); bool operator()(float progress, const bool& property) { if(mKeyFrames->IsActive(progress)) @@ -847,6 +1035,7 @@ struct KeyFrameIntegerFunctor : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); float operator()(float progress, const int& property) { if(mKeyFrames->IsActive(progress)) @@ -867,6 +1056,7 @@ struct KeyFrameNumberFunctor : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); float operator()(float progress, const float& property) { if(mKeyFrames->IsActive(progress)) @@ -887,6 +1077,7 @@ struct KeyFrameVector2Functor : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector2 operator()(float progress, const Vector2& property) { if(mKeyFrames->IsActive(progress)) @@ -908,6 +1099,7 @@ struct KeyFrameVector3Functor : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector3 operator()(float progress, const Vector3& property) { if(mKeyFrames->IsActive(progress)) @@ -928,6 +1120,7 @@ struct KeyFrameVector4Functor : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Vector4 operator()(float progress, const Vector4& property) { if(mKeyFrames->IsActive(progress)) @@ -948,6 +1141,7 @@ struct KeyFrameQuaternionFunctor : public AnimatorFunctionBase { } + using AnimatorFunctionBase::operator(); Quaternion operator()(float progress, const Quaternion& property) { if(mKeyFrames->IsActive(progress)) @@ -967,9 +1161,12 @@ struct PathPositionFunctor : public AnimatorFunctionBase { } + 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; @@ -984,17 +1181,24 @@ struct PathRotationFunctor : public AnimatorFunctionBase 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