1 #ifndef DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H
2 #define DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H
5 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
26 #include <dali/internal/event/animation/key-frames-impl.h>
27 #include <dali/internal/event/animation/path-impl.h>
28 #include <dali/internal/update/animation/property-accessor.h>
29 #include <dali/internal/update/common/property-base.h>
30 #include <dali/internal/update/common/property-owner.h>
31 #include <dali/public-api/animation/alpha-function.h>
32 #include <dali/public-api/animation/animation.h>
33 #include <dali/public-api/animation/time-period.h>
34 #include <dali/public-api/common/constants.h>
35 #include <dali/public-api/common/dali-common.h>
36 #include <dali/public-api/math/quaternion.h>
37 #include <dali/public-api/math/radian.h>
43 using Interpolation = Dali::Animation::Interpolation;
48 * An abstract base class for Animators, which can be added to scene graph animations.
49 * Each animator changes a single property of an object in the scene graph.
51 class AnimatorBase : public PropertyOwner::Observer
54 using AlphaFunc = float (*)(float progress); ///< Definition of an alpha function
57 * Observer to determine when the animator is no longer present
59 class LifecycleObserver
63 * Called shortly before the animator is destroyed.
65 virtual void ObjectDestroyed() = 0;
69 * Virtual destructor, no deletion through this interface
71 virtual ~LifecycleObserver() = default;
77 AnimatorBase(PropertyOwner* propertyOwner,
78 AlphaFunction alphaFunction,
79 const TimePeriod& timePeriod)
80 : mLifecycleObserver(nullptr),
81 mPropertyOwner(propertyOwner),
82 mDurationSeconds(timePeriod.durationSeconds),
83 mIntervalDelaySeconds(timePeriod.delaySeconds),
85 mCurrentProgress(0.f),
86 mAlphaFunction(alphaFunction),
87 mDisconnectAction(Dali::Animation::BAKE_FINAL),
88 mAnimationPlaying(false),
90 mConnectedToSceneGraph(false),
91 mAutoReverseEnabled(false)
98 ~AnimatorBase() override
100 if(mPropertyOwner && mConnectedToSceneGraph)
102 mPropertyOwner->RemoveObserver(*this);
104 if(mLifecycleObserver != nullptr)
106 mLifecycleObserver->ObjectDestroyed();
110 void AddLifecycleObserver(LifecycleObserver& observer)
112 mLifecycleObserver = &observer;
115 void RemoveLifecycleObserver(LifecycleObserver& observer)
117 mLifecycleObserver = nullptr;
120 private: // From PropertyOwner::Observer
122 * @copydoc PropertyOwner::Observer::PropertyOwnerConnected( PropertyOwner& owner )
124 void PropertyOwnerConnected(PropertyOwner& owner) final
130 * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
132 void PropertyOwnerDisconnected(BufferIndex bufferIndex, PropertyOwner& owner) final
134 // If we are active, then bake the value if required
135 if(mAnimationPlaying && mDisconnectAction != Dali::Animation::DISCARD)
137 // Bake to target-value if BakeFinal, otherwise bake current value
138 Update(bufferIndex, (mDisconnectAction == Dali::Animation::BAKE ? mCurrentProgress : 1.0f), true);
145 * @copydoc PropertyOwner::Observer::PropertyOwnerDestroyed( PropertyOwner& owner )
147 void PropertyOwnerDestroyed(PropertyOwner& owner) final
149 mPropertyOwner = nullptr;
154 * Called when Animator is added to the scene-graph in update-thread.
156 void ConnectToSceneGraph()
158 mConnectedToSceneGraph = true;
159 mPropertyOwner->AddObserver(*this);
161 // Enable if the target object is valid and connected to the scene graph.
162 mEnabled = mPropertyOwner->IsAnimationPossible();
166 * Set the duration of the animator.
167 * @pre durationSeconds must be zero or greater; zero is useful when animating boolean values.
168 * @param [in] seconds Duration in seconds.
170 void SetDuration(float seconds)
172 DALI_ASSERT_DEBUG(seconds >= 0.0f);
174 mDurationSeconds = seconds;
178 * Retrieve the duration of the animator.
179 * @return The duration in seconds.
181 float GetDuration() const
183 return mDurationSeconds;
186 void SetSpeedFactor(float factor)
188 mSpeedFactor = factor;
191 void SetLoopCount(int32_t loopCount)
193 mLoopCount = loopCount;
196 float SetProgress(float progress)
200 if(mAutoReverseEnabled)
202 if(mSpeedFactor > 0.0f)
204 value = 1.0f - 2.0f * std::abs(progress - 0.5f);
207 else if(mSpeedFactor < 0.0f)
209 value = 2.0f * std::abs(progress - 0.5f);
221 * Set the delay before the animator should take effect.
222 * The default is zero i.e. no delay.
223 * @param [in] seconds The delay in seconds.
225 void SetIntervalDelay(float seconds)
227 mIntervalDelaySeconds = seconds;
231 * Retrieve the delay before the animator should take effect.
232 * @return The delay in seconds.
234 float GetIntervalDelay() const
236 return mIntervalDelaySeconds;
240 * Set the alpha function for an animator.
241 * @param [in] alphaFunc The alpha function to apply to the animation progress.
243 void SetAlphaFunction(const AlphaFunction& alphaFunction)
245 mAlphaFunction = alphaFunction;
249 * Retrieve the alpha function of an animator.
250 * @return The function.
252 AlphaFunction GetAlphaFunction() const
254 return mAlphaFunction;
258 * Applies the alpha function to the specified progress
259 * @param[in] Current progress
260 * @return The progress after the alpha function has been aplied
262 float ApplyAlphaFunction(float progress) const
264 float result = progress;
266 AlphaFunction::Mode alphaFunctionMode(mAlphaFunction.GetMode());
267 if(alphaFunctionMode == AlphaFunction::BUILTIN_FUNCTION)
269 switch(mAlphaFunction.GetBuiltinFunction())
271 case AlphaFunction::DEFAULT:
272 case AlphaFunction::LINEAR:
276 case AlphaFunction::REVERSE:
278 result = 1.0f - progress;
281 case AlphaFunction::EASE_IN_SQUARE:
283 result = progress * progress;
286 case AlphaFunction::EASE_OUT_SQUARE:
288 result = 1.0f - (1.0f - progress) * (1.0f - progress);
291 case AlphaFunction::EASE_IN:
293 result = progress * progress * progress;
296 case AlphaFunction::EASE_OUT:
298 result = (progress - 1.0f) * (progress - 1.0f) * (progress - 1.0f) + 1.0f;
301 case AlphaFunction::EASE_IN_OUT:
303 result = progress * progress * (3.0f - 2.0f * progress);
306 case AlphaFunction::EASE_IN_SINE:
308 result = -1.0f * cosf(progress * Math::PI_2) + 1.0f;
311 case AlphaFunction::EASE_OUT_SINE:
313 result = sinf(progress * Math::PI_2);
316 case AlphaFunction::EASE_IN_OUT_SINE:
318 result = -0.5f * (cosf(Math::PI * progress) - 1.0f);
321 case AlphaFunction::BOUNCE:
323 result = sinf(progress * Math::PI);
326 case AlphaFunction::SIN:
328 result = 0.5f - cosf(progress * 2.0f * Math::PI) * 0.5f;
331 case AlphaFunction::EASE_OUT_BACK:
333 const float sqrt2 = 1.70158f;
335 result = 1.0f + progress * progress * ((sqrt2 + 1.0f) * progress + sqrt2);
338 case AlphaFunction::COUNT:
344 else if(alphaFunctionMode == AlphaFunction::CUSTOM_FUNCTION)
346 AlphaFunctionPrototype customFunction = mAlphaFunction.GetCustomFunction();
349 result = customFunction(progress);
354 //If progress is very close to 0 or very close to 1 we don't need to evaluate the curve as the result will
355 //be almost 0 or almost 1 respectively
356 if((progress > Math::MACHINE_EPSILON_1) && ((1.0f - progress) > Math::MACHINE_EPSILON_1))
358 Dali::Vector4 controlPoints = mAlphaFunction.GetBezierControlPoints();
360 static const float tolerance = 0.001f; //10 iteration max
362 //Perform a binary search on the curve
363 float lowerBound(0.0f);
364 float upperBound(1.0f);
365 float currentT(0.5f);
366 float currentX = EvaluateCubicBezier(controlPoints.x, controlPoints.z, currentT);
367 while(fabsf(progress - currentX) > tolerance)
369 if(progress > currentX)
371 lowerBound = currentT;
375 upperBound = currentT;
377 currentT = (upperBound + lowerBound) * 0.5f;
378 currentX = EvaluateCubicBezier(controlPoints.x, controlPoints.z, currentT);
380 result = EvaluateCubicBezier(controlPoints.y, controlPoints.w, currentT);
388 * Whether to bake the animation if attached property owner is disconnected.
389 * Property is only baked if the animator is active.
390 * @param [in] action The disconnect action.
392 void SetDisconnectAction(Dali::Animation::EndAction action)
394 mDisconnectAction = action;
398 * Retrieve the disconnect action of an animator.
399 * @return The disconnect action.
401 Dali::Animation::EndAction GetDisconnectAction() const
403 return mDisconnectAction;
407 * Whether the animator is active or not.
408 * @param [in] active The new active state.
409 * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected.
410 * @note When the property owner is disconnected, the active state is set to false.
412 void SetActive(bool active)
414 mAnimationPlaying = active;
418 * Whether the animator's target object is valid and on the stage.
419 * @return The enabled state.
421 bool IsEnabled() const
427 * @brief Sets the looping mode.
428 * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
430 void SetLoopingMode(bool loopingMode)
432 mAutoReverseEnabled = loopingMode;
436 * Returns wheter the target object of the animator is still valid
437 * or has been destroyed.
438 * @return True if animator is orphan, false otherwise *
439 * @note The SceneGraph::Animation will delete any orphan animator in its Update method.
443 return (mPropertyOwner == nullptr);
447 * Update the scene object attached to the animator.
448 * @param[in] bufferIndex The buffer to animate.
449 * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point.
450 * @param[in] bake Bake.
452 void Update(BufferIndex bufferIndex, float progress, bool bake)
456 // Update the progress value
457 progress = SetProgress(progress);
462 mPropertyOwner->SetUpdated(true);
465 float alpha = ApplyAlphaFunction(progress);
467 // PropertyType specific part
468 DoUpdate(bufferIndex, bake, alpha);
470 mCurrentProgress = progress;
474 * Type specific part of the animator
475 * @param bufferIndex index to use
476 * @param bake whether to bake or not
477 * @param alpha value from alpha based on progress
479 virtual void DoUpdate(BufferIndex bufferIndex, bool bake, float alpha) = 0;
483 * Helper function to evaluate a cubic bezier curve assuming first point is at 0.0 and last point is at 1.0
484 * @param[in] p0 First control point of the bezier curve
485 * @param[in] p1 Second control point of the bezier curve
486 * @param[in] t A floating point value between 0.0 and 1.0
487 * @return Value of the curve at progress t
489 inline float EvaluateCubicBezier(float p0, float p1, float t) const
491 float tSquare = t * t;
492 return 3.0f * (1.0f - t) * (1.0f - t) * t * p0 + 3.0f * (1.0f - t) * tSquare * p1 + tSquare * t;
495 LifecycleObserver* mLifecycleObserver;
496 PropertyOwner* mPropertyOwner;
498 float mDurationSeconds;
499 float mIntervalDelaySeconds;
501 float mCurrentProgress;
503 AlphaFunction mAlphaFunction;
505 int32_t mLoopCount{1};
506 Dali::Animation::EndAction mDisconnectAction; ///< EndAction to apply when target object gets disconnected from the stage.
507 bool mAnimationPlaying : 1; ///< whether disconnect has been applied while it's running.
508 bool mEnabled : 1; ///< Animator is "enabled" while its target object is valid and on the stage.
509 bool mConnectedToSceneGraph : 1; ///< True if ConnectToSceneGraph() has been called in update-thread.
510 bool mAutoReverseEnabled : 1;
514 * An animator for a specific property type PropertyType.
516 template<typename PropertyType, typename PropertyAccessorType>
517 class Animator final : public AnimatorBase
519 using AnimatorFunction = std::function<PropertyType(float, const PropertyType&)>;
521 AnimatorFunction mAnimatorFunction;
525 * Construct a new property animator.
526 * @param[in] property The animatable property; only valid while the Animator is attached.
527 * @param[in] animatorFunction The function used to animate the property.
528 * @param[in] alphaFunction The alpha function to apply.
529 * @param[in] timePeriod The time period of this animation.
530 * @return A newly allocated animator.
532 static AnimatorBase* New(const PropertyOwner& propertyOwner,
533 const PropertyBase& property,
534 AnimatorFunction animatorFunction,
535 AlphaFunction alphaFunction,
536 const TimePeriod& timePeriod)
538 // The property was const in the actor-thread, but animators are used in the scene-graph thread.
539 return new Animator(const_cast<PropertyOwner*>(&propertyOwner),
540 const_cast<PropertyBase*>(&property),
541 std::move(animatorFunction),
547 * @copydoc AnimatorBase::DoUpdate( BufferIndex bufferIndex, bool bake, float alpha )
549 void DoUpdate(BufferIndex bufferIndex, bool bake, float alpha) final
551 const PropertyType& current = mPropertyAccessor.Get(bufferIndex);
553 // need to cast the return value in case property is integer
554 const PropertyType result = static_cast<PropertyType>(mAnimatorFunction(alpha, current));
558 mPropertyAccessor.Bake(bufferIndex, result);
562 mPropertyAccessor.Set(bufferIndex, result);
568 * Private constructor; see also Animator::New().
570 Animator(PropertyOwner* propertyOwner,
571 PropertyBase* property,
572 AnimatorFunction animatorFunction,
573 AlphaFunction alphaFunction,
574 const TimePeriod& timePeriod)
575 : AnimatorBase(propertyOwner, alphaFunction, timePeriod),
576 mAnimatorFunction(std::move(animatorFunction)),
577 mPropertyAccessor(property)
579 // WARNING - this object is created in the event-thread
580 // The scene-graph mPropertyOwner object cannot be observed here
584 Animator(const Animator&);
587 Animator& operator=(const Animator&);
590 PropertyAccessorType mPropertyAccessor;
594 * An animator for a specific property type PropertyType.
596 template<typename PropertyType, typename PropertyAccessorType>
597 class AnimatorTransformProperty final : public AnimatorBase
599 using AnimatorFunction = std::function<PropertyType(float, const PropertyType&)>;
601 AnimatorFunction mAnimatorFunction;
605 * Construct a new property animator.
606 * @param[in] property The animatable property; only valid while the Animator is attached.
607 * @param[in] animatorFunction The function used to animate the property.
608 * @param[in] alphaFunction The alpha function to apply.
609 * @param[in] timePeriod The time period of this animation.
610 * @return A newly allocated animator.
612 static AnimatorBase* New(const PropertyOwner& propertyOwner,
613 const PropertyBase& property,
614 AnimatorFunction animatorFunction,
615 AlphaFunction alphaFunction,
616 const TimePeriod& timePeriod)
618 // The property was const in the actor-thread, but animators are used in the scene-graph thread.
619 return new AnimatorTransformProperty(const_cast<PropertyOwner*>(&propertyOwner),
620 const_cast<PropertyBase*>(&property),
621 std::move(animatorFunction),
627 * @copydoc AnimatorBase::DoUpdate( BufferIndex bufferIndex, bool bake, float alpha )
629 void DoUpdate(BufferIndex bufferIndex, bool bake, float alpha) final
631 const PropertyType& current = mPropertyAccessor.Get(bufferIndex);
633 // need to cast the return value in case property is integer
634 const PropertyType result = static_cast<PropertyType>(mAnimatorFunction(alpha, current));
638 mPropertyAccessor.Bake(bufferIndex, result);
642 mPropertyAccessor.Set(bufferIndex, result);
648 * Private constructor; see also Animator::New().
650 AnimatorTransformProperty(PropertyOwner* propertyOwner,
651 PropertyBase* property,
652 AnimatorFunction animatorFunction,
653 AlphaFunction alphaFunction,
654 const TimePeriod& timePeriod)
655 : AnimatorBase(propertyOwner, alphaFunction, timePeriod),
656 mAnimatorFunction(std::move(animatorFunction)),
657 mPropertyAccessor(property)
659 // WARNING - this object is created in the event-thread
660 // The scene-graph mPropertyOwner object cannot be observed here
664 AnimatorTransformProperty() = delete;
665 AnimatorTransformProperty(const AnimatorTransformProperty&) = delete;
666 AnimatorTransformProperty& operator=(const AnimatorTransformProperty&) = delete;
669 PropertyAccessorType mPropertyAccessor;
672 } // namespace SceneGraph
676 struct AnimateByInteger
678 AnimateByInteger(const int& relativeValue)
679 : mRelative(relativeValue)
683 float operator()(float alpha, const int32_t& property)
685 // integers need to be correctly rounded
686 return roundf(static_cast<float>(property) + static_cast<float>(mRelative) * alpha);
692 struct AnimateToInteger
694 AnimateToInteger(const int& targetValue)
695 : mTarget(targetValue)
699 float operator()(float alpha, const int32_t& property)
701 // integers need to be correctly rounded
702 return roundf(static_cast<float>(property) + (static_cast<float>(mTarget - property) * alpha));
708 struct AnimateByFloat
710 AnimateByFloat(const float& relativeValue)
711 : mRelative(relativeValue)
715 float operator()(float alpha, const float& property)
717 return float(property + mRelative * alpha);
723 struct AnimateToFloat
725 AnimateToFloat(const float& targetValue)
726 : mTarget(targetValue)
730 float operator()(float alpha, const float& property)
732 return float(property + ((mTarget - property) * alpha));
738 struct AnimateByVector2
740 AnimateByVector2(const Vector2& relativeValue)
741 : mRelative(relativeValue)
745 Vector2 operator()(float alpha, const Vector2& property)
747 return Vector2(property + mRelative * alpha);
753 struct AnimateToVector2
755 AnimateToVector2(const Vector2& targetValue)
756 : mTarget(targetValue)
760 Vector2 operator()(float alpha, const Vector2& property)
762 return Vector2(property + ((mTarget - property) * alpha));
768 struct AnimateByVector3
770 AnimateByVector3(const Vector3& relativeValue)
771 : mRelative(relativeValue)
775 Vector3 operator()(float alpha, const Vector3& property)
777 return Vector3(property + mRelative * alpha);
783 struct AnimateToVector3
785 AnimateToVector3(const Vector3& targetValue)
786 : mTarget(targetValue)
790 Vector3 operator()(float alpha, const Vector3& property)
792 return Vector3(property + ((mTarget - property) * alpha));
798 struct AnimateByVector4
800 AnimateByVector4(const Vector4& relativeValue)
801 : mRelative(relativeValue)
805 Vector4 operator()(float alpha, const Vector4& property)
807 return Vector4(property + mRelative * alpha);
813 struct AnimateToVector4
815 AnimateToVector4(const Vector4& targetValue)
816 : mTarget(targetValue)
820 Vector4 operator()(float alpha, const Vector4& property)
822 return Vector4(property + ((mTarget - property) * alpha));
828 struct AnimateByOpacity
830 AnimateByOpacity(const float& relativeValue)
831 : mRelative(relativeValue)
835 Vector4 operator()(float alpha, const Vector4& property)
837 Vector4 result(property);
838 result.a += mRelative * alpha;
846 struct AnimateToOpacity
848 AnimateToOpacity(const float& targetValue)
849 : mTarget(targetValue)
853 Vector4 operator()(float alpha, const Vector4& property)
855 Vector4 result(property);
856 result.a = property.a + ((mTarget - property.a) * alpha);
864 struct AnimateByBoolean
866 AnimateByBoolean(bool relativeValue)
867 : mRelative(relativeValue)
871 bool operator()(float alpha, const bool& property)
873 // Alpha is not useful here, just keeping to the same template as other update functors
874 return bool(alpha >= 1.0f ? (property || mRelative) : property);
880 struct AnimateToBoolean
882 AnimateToBoolean(bool targetValue)
883 : mTarget(targetValue)
887 bool operator()(float alpha, const bool& property)
889 // Alpha is not useful here, just keeping to the same template as other update functors
890 return bool(alpha >= 1.0f ? mTarget : property);
896 struct RotateByAngleAxis
898 RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
899 : mAngleRadians(angleRadians),
900 mAxis(axis.x, axis.y, axis.z)
904 Quaternion operator()(float alpha, const Quaternion& rotation)
908 return rotation * Quaternion(mAngleRadians * alpha, mAxis);
914 Radian mAngleRadians;
918 struct RotateToQuaternion
920 RotateToQuaternion(const Quaternion& targetValue)
921 : mTarget(targetValue)
925 Quaternion operator()(float alpha, const Quaternion& rotation)
927 return Quaternion::Slerp(rotation, mTarget, alpha);
933 struct KeyFrameBooleanFunctor
935 KeyFrameBooleanFunctor(KeyFrameBoolean keyFrames)
936 : mKeyFrames(std::move(keyFrames))
940 bool operator()(float progress, const bool& property)
942 if(mKeyFrames.IsActive(progress))
944 return mKeyFrames.GetValue(progress, Dali::Animation::LINEAR);
949 KeyFrameBoolean mKeyFrames;
952 struct KeyFrameIntegerFunctor
954 KeyFrameIntegerFunctor(KeyFrameInteger keyFrames, Interpolation interpolation)
955 : mKeyFrames(std::move(keyFrames)),
956 mInterpolation(interpolation)
960 float operator()(float progress, const int32_t& property)
962 if(mKeyFrames.IsActive(progress))
964 return static_cast<float>(mKeyFrames.GetValue(progress, mInterpolation));
966 return static_cast<float>(property);
969 KeyFrameInteger mKeyFrames;
970 Interpolation mInterpolation;
973 struct KeyFrameNumberFunctor
975 KeyFrameNumberFunctor(KeyFrameNumber keyFrames, Interpolation interpolation)
976 : mKeyFrames(std::move(keyFrames)),
977 mInterpolation(interpolation)
981 float operator()(float progress, const float& property)
983 if(mKeyFrames.IsActive(progress))
985 return mKeyFrames.GetValue(progress, mInterpolation);
990 KeyFrameNumber mKeyFrames;
991 Interpolation mInterpolation;
994 struct KeyFrameVector2Functor
996 KeyFrameVector2Functor(KeyFrameVector2 keyFrames, Interpolation interpolation)
997 : mKeyFrames(std::move(keyFrames)),
998 mInterpolation(interpolation)
1002 Vector2 operator()(float progress, const Vector2& property)
1004 if(mKeyFrames.IsActive(progress))
1006 return mKeyFrames.GetValue(progress, mInterpolation);
1011 KeyFrameVector2 mKeyFrames;
1012 Interpolation mInterpolation;
1015 struct KeyFrameVector3Functor
1017 KeyFrameVector3Functor(KeyFrameVector3 keyFrames, Interpolation interpolation)
1018 : mKeyFrames(std::move(keyFrames)),
1019 mInterpolation(interpolation)
1023 Vector3 operator()(float progress, const Vector3& property)
1025 if(mKeyFrames.IsActive(progress))
1027 return mKeyFrames.GetValue(progress, mInterpolation);
1032 KeyFrameVector3 mKeyFrames;
1033 Interpolation mInterpolation;
1036 struct KeyFrameVector4Functor
1038 KeyFrameVector4Functor(KeyFrameVector4 keyFrames, Interpolation interpolation)
1039 : mKeyFrames(std::move(keyFrames)),
1040 mInterpolation(interpolation)
1044 Vector4 operator()(float progress, const Vector4& property)
1046 if(mKeyFrames.IsActive(progress))
1048 return mKeyFrames.GetValue(progress, mInterpolation);
1053 KeyFrameVector4 mKeyFrames;
1054 Interpolation mInterpolation;
1057 struct KeyFrameQuaternionFunctor
1059 KeyFrameQuaternionFunctor(KeyFrameQuaternion keyFrames)
1060 : mKeyFrames(std::move(keyFrames))
1064 Quaternion operator()(float progress, const Quaternion& property)
1066 if(mKeyFrames.IsActive(progress))
1068 return mKeyFrames.GetValue(progress, Dali::Animation::LINEAR);
1073 KeyFrameQuaternion mKeyFrames;
1076 struct PathPositionFunctor
1078 PathPositionFunctor(PathPtr path)
1083 Vector3 operator()(float progress, const Vector3& property)
1085 Vector3 position(property);
1086 static_cast<void>(mPath->SamplePosition(progress, position));
1093 struct PathRotationFunctor
1095 PathRotationFunctor(PathPtr path, const Vector3& forward)
1099 mForward.Normalize();
1102 Quaternion operator()(float progress, const Quaternion& property)
1105 if(mPath->SampleTangent(progress, tangent))
1107 return Quaternion(mForward, tangent);
1119 } // namespace Internal
1123 #endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H