1 #ifndef DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H
2 #define DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H
5 * Copyright (c) 2021 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/devel-api/common/owner-container.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/internal/event/animation/key-frames-impl.h>
29 #include <dali/internal/event/animation/path-impl.h>
30 #include <dali/internal/update/animation/property-accessor.h>
31 #include <dali/internal/update/common/property-base.h>
32 #include <dali/internal/update/nodes/node.h>
33 #include <dali/public-api/animation/alpha-function.h>
34 #include <dali/public-api/animation/animation.h>
35 #include <dali/public-api/animation/time-period.h>
36 #include <dali/public-api/common/constants.h>
37 #include <dali/public-api/common/dali-common.h>
38 #include <dali/public-api/math/quaternion.h>
39 #include <dali/public-api/math/radian.h>
45 using Interpolation = Dali::Animation::Interpolation;
50 * An abstract base class for Animators, which can be added to scene graph animations.
51 * Each animator changes a single property of an object in the scene graph.
53 class AnimatorBase : public PropertyOwner::Observer
56 using AlphaFunc = float (*)(float progress); ///< Definition of an alpha function
59 * Observer to determine when the animator is no longer present
61 class LifecycleObserver
65 * Called shortly before the animator is destroyed.
67 virtual void ObjectDestroyed() = 0;
71 * Virtual destructor, no deletion through this interface
73 virtual ~LifecycleObserver() = default;
79 AnimatorBase(PropertyOwner* propertyOwner,
80 AlphaFunction alphaFunction,
81 const TimePeriod& timePeriod)
82 : mLifecycleObserver(nullptr),
83 mPropertyOwner(propertyOwner),
84 mDurationSeconds(timePeriod.durationSeconds),
85 mIntervalDelaySeconds(timePeriod.delaySeconds),
87 mCurrentProgress(0.f),
88 mAlphaFunction(alphaFunction),
89 mDisconnectAction(Dali::Animation::BAKE_FINAL),
90 mAnimationPlaying(false),
92 mConnectedToSceneGraph(false),
93 mAutoReverseEnabled(false)
100 ~AnimatorBase() override
102 if(mPropertyOwner && mConnectedToSceneGraph)
104 mPropertyOwner->RemoveObserver(*this);
106 if(mLifecycleObserver != nullptr)
108 mLifecycleObserver->ObjectDestroyed();
112 void AddLifecycleObserver(LifecycleObserver& observer)
114 mLifecycleObserver = &observer;
117 void RemoveLifecycleObserver(LifecycleObserver& observer)
119 mLifecycleObserver = nullptr;
122 private: // From PropertyOwner::Observer
124 * @copydoc PropertyOwner::Observer::PropertyOwnerConnected( PropertyOwner& owner )
126 void PropertyOwnerConnected(PropertyOwner& owner) final
132 * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
134 void PropertyOwnerDisconnected(BufferIndex bufferIndex, PropertyOwner& owner) final
136 // If we are active, then bake the value if required
137 if(mAnimationPlaying && mDisconnectAction != Dali::Animation::DISCARD)
139 // Bake to target-value if BakeFinal, otherwise bake current value
140 Update(bufferIndex, (mDisconnectAction == Dali::Animation::BAKE ? mCurrentProgress : 1.0f), true);
147 * @copydoc PropertyOwner::Observer::PropertyOwnerDestroyed( PropertyOwner& owner )
149 void PropertyOwnerDestroyed(PropertyOwner& owner) final
151 mPropertyOwner = nullptr;
156 * Called when Animator is added to the scene-graph in update-thread.
158 void ConnectToSceneGraph()
160 mConnectedToSceneGraph = true;
161 mPropertyOwner->AddObserver(*this);
163 // Enable if the target object is valid and connected to the scene graph.
164 mEnabled = mPropertyOwner->IsAnimationPossible();
168 * Set the duration of the animator.
169 * @pre durationSeconds must be zero or greater; zero is useful when animating boolean values.
170 * @param [in] seconds Duration in seconds.
172 void SetDuration(float seconds)
174 DALI_ASSERT_DEBUG(seconds >= 0.0f);
176 mDurationSeconds = seconds;
180 * Retrieve the duration of the animator.
181 * @return The duration in seconds.
183 float GetDuration() const
185 return mDurationSeconds;
188 void SetSpeedFactor(float factor)
190 mSpeedFactor = factor;
193 void SetLoopCount(int32_t loopCount)
195 mLoopCount = loopCount;
198 float SetProgress(float progress)
202 if(mAutoReverseEnabled)
204 if(mSpeedFactor > 0.0f)
206 value = 1.0f - 2.0f * std::abs(progress - 0.5f);
209 else if(mSpeedFactor < 0.0f)
211 value = 2.0f * std::abs(progress - 0.5f);
223 * Set the delay before the animator should take effect.
224 * The default is zero i.e. no delay.
225 * @param [in] seconds The delay in seconds.
227 void SetIntervalDelay(float seconds)
229 mIntervalDelaySeconds = seconds;
233 * Retrieve the delay before the animator should take effect.
234 * @return The delay in seconds.
236 float GetIntervalDelay() const
238 return mIntervalDelaySeconds;
242 * Set the alpha function for an animator.
243 * @param [in] alphaFunc The alpha function to apply to the animation progress.
245 void SetAlphaFunction(const AlphaFunction& alphaFunction)
247 mAlphaFunction = alphaFunction;
251 * Retrieve the alpha function of an animator.
252 * @return The function.
254 AlphaFunction GetAlphaFunction() const
256 return mAlphaFunction;
260 * Applies the alpha function to the specified progress
261 * @param[in] Current progress
262 * @return The progress after the alpha function has been aplied
264 float ApplyAlphaFunction(float progress) const
266 float result = progress;
268 AlphaFunction::Mode alphaFunctionMode(mAlphaFunction.GetMode());
269 if(alphaFunctionMode == AlphaFunction::BUILTIN_FUNCTION)
271 switch(mAlphaFunction.GetBuiltinFunction())
273 case AlphaFunction::DEFAULT:
274 case AlphaFunction::LINEAR:
278 case AlphaFunction::REVERSE:
280 result = 1.0f - progress;
283 case AlphaFunction::EASE_IN_SQUARE:
285 result = progress * progress;
288 case AlphaFunction::EASE_OUT_SQUARE:
290 result = 1.0f - (1.0f - progress) * (1.0f - progress);
293 case AlphaFunction::EASE_IN:
295 result = progress * progress * progress;
298 case AlphaFunction::EASE_OUT:
300 result = (progress - 1.0f) * (progress - 1.0f) * (progress - 1.0f) + 1.0f;
303 case AlphaFunction::EASE_IN_OUT:
305 result = progress * progress * (3.0f - 2.0f * progress);
308 case AlphaFunction::EASE_IN_SINE:
310 result = -1.0f * cosf(progress * Math::PI_2) + 1.0f;
313 case AlphaFunction::EASE_OUT_SINE:
315 result = sinf(progress * Math::PI_2);
318 case AlphaFunction::EASE_IN_OUT_SINE:
320 result = -0.5f * (cosf(Math::PI * progress) - 1.0f);
323 case AlphaFunction::BOUNCE:
325 result = sinf(progress * Math::PI);
328 case AlphaFunction::SIN:
330 result = 0.5f - cosf(progress * 2.0f * Math::PI) * 0.5f;
333 case AlphaFunction::EASE_OUT_BACK:
335 const float sqrt2 = 1.70158f;
337 result = 1.0f + progress * progress * ((sqrt2 + 1.0f) * progress + sqrt2);
340 case AlphaFunction::COUNT:
346 else if(alphaFunctionMode == AlphaFunction::CUSTOM_FUNCTION)
348 AlphaFunctionPrototype customFunction = mAlphaFunction.GetCustomFunction();
351 result = customFunction(progress);
356 //If progress is very close to 0 or very close to 1 we don't need to evaluate the curve as the result will
357 //be almost 0 or almost 1 respectively
358 if((progress > Math::MACHINE_EPSILON_1) && ((1.0f - progress) > Math::MACHINE_EPSILON_1))
360 Dali::Vector4 controlPoints = mAlphaFunction.GetBezierControlPoints();
362 static const float tolerance = 0.001f; //10 iteration max
364 //Perform a binary search on the curve
365 float lowerBound(0.0f);
366 float upperBound(1.0f);
367 float currentT(0.5f);
368 float currentX = EvaluateCubicBezier(controlPoints.x, controlPoints.z, currentT);
369 while(fabsf(progress - currentX) > tolerance)
371 if(progress > currentX)
373 lowerBound = currentT;
377 upperBound = currentT;
379 currentT = (upperBound + lowerBound) * 0.5f;
380 currentX = EvaluateCubicBezier(controlPoints.x, controlPoints.z, currentT);
382 result = EvaluateCubicBezier(controlPoints.y, controlPoints.w, currentT);
390 * Whether to bake the animation if attached property owner is disconnected.
391 * Property is only baked if the animator is active.
392 * @param [in] action The disconnect action.
394 void SetDisconnectAction(Dali::Animation::EndAction action)
396 mDisconnectAction = action;
400 * Retrieve the disconnect action of an animator.
401 * @return The disconnect action.
403 Dali::Animation::EndAction GetDisconnectAction() const
405 return mDisconnectAction;
409 * Whether the animator is active or not.
410 * @param [in] active The new active state.
411 * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected.
412 * @note When the property owner is disconnected, the active state is set to false.
414 void SetActive(bool active)
416 mAnimationPlaying = active;
420 * Whether the animator's target object is valid and on the stage.
421 * @return The enabled state.
423 bool IsEnabled() const
429 * @brief Sets the looping mode.
430 * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
432 void SetLoopingMode(bool loopingMode)
434 mAutoReverseEnabled = loopingMode;
438 * Returns wheter the target object of the animator is still valid
439 * or has been destroyed.
440 * @return True if animator is orphan, false otherwise *
441 * @note The SceneGraph::Animation will delete any orphan animator in its Update method.
445 return (mPropertyOwner == nullptr);
449 * Update the scene object attached to the animator.
450 * @param[in] bufferIndex The buffer to animate.
451 * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point.
452 * @param[in] bake Bake.
454 void Update(BufferIndex bufferIndex, float progress, bool bake)
458 // Update the progress value
459 progress = SetProgress(progress);
464 mPropertyOwner->SetUpdated(true);
467 float alpha = ApplyAlphaFunction(progress);
469 // PropertyType specific part
470 DoUpdate(bufferIndex, bake, alpha);
472 mCurrentProgress = progress;
476 * Type specific part of the animator
477 * @param bufferIndex index to use
478 * @param bake whether to bake or not
479 * @param alpha value from alpha based on progress
481 virtual void DoUpdate(BufferIndex bufferIndex, bool bake, float alpha) = 0;
485 * Helper function to evaluate a cubic bezier curve assuming first point is at 0.0 and last point is at 1.0
486 * @param[in] p0 First control point of the bezier curve
487 * @param[in] p1 Second control point of the bezier curve
488 * @param[in] t A floating point value between 0.0 and 1.0
489 * @return Value of the curve at progress t
491 inline float EvaluateCubicBezier(float p0, float p1, float t) const
493 float tSquare = t * t;
494 return 3.0f * (1.0f - t) * (1.0f - t) * t * p0 + 3.0f * (1.0f - t) * tSquare * p1 + tSquare * t;
497 LifecycleObserver* mLifecycleObserver;
498 PropertyOwner* mPropertyOwner;
500 float mDurationSeconds;
501 float mIntervalDelaySeconds;
503 float mCurrentProgress;
505 AlphaFunction mAlphaFunction;
507 int32_t mLoopCount{1};
508 Dali::Animation::EndAction mDisconnectAction; ///< EndAction to apply when target object gets disconnected from the stage.
509 bool mAnimationPlaying : 1; ///< whether disconnect has been applied while it's running.
510 bool mEnabled : 1; ///< Animator is "enabled" while its target object is valid and on the stage.
511 bool mConnectedToSceneGraph : 1; ///< True if ConnectToSceneGraph() has been called in update-thread.
512 bool mAutoReverseEnabled : 1;
516 * An animator for a specific property type PropertyType.
518 template<typename PropertyType, typename PropertyAccessorType>
519 class Animator final : public AnimatorBase
521 using AnimatorFunction = std::function<PropertyType(float, const PropertyType&)>;
523 AnimatorFunction mAnimatorFunction;
527 * Construct a new property animator.
528 * @param[in] property The animatable property; only valid while the Animator is attached.
529 * @param[in] animatorFunction The function used to animate the property.
530 * @param[in] alphaFunction The alpha function to apply.
531 * @param[in] timePeriod The time period of this animation.
532 * @return A newly allocated animator.
534 static AnimatorBase* New(const PropertyOwner& propertyOwner,
535 const PropertyBase& property,
536 AnimatorFunction animatorFunction,
537 AlphaFunction alphaFunction,
538 const TimePeriod& timePeriod)
540 // The property was const in the actor-thread, but animators are used in the scene-graph thread.
541 return new Animator(const_cast<PropertyOwner*>(&propertyOwner),
542 const_cast<PropertyBase*>(&property),
543 std::move(animatorFunction),
549 * @copydoc AnimatorBase::DoUpdate( BufferIndex bufferIndex, bool bake, float alpha )
551 void DoUpdate(BufferIndex bufferIndex, bool bake, float alpha) final
553 const PropertyType& current = mPropertyAccessor.Get(bufferIndex);
555 // need to cast the return value in case property is integer
556 const PropertyType result = static_cast<PropertyType>(mAnimatorFunction(alpha, current));
560 mPropertyAccessor.Bake(bufferIndex, result);
564 mPropertyAccessor.Set(bufferIndex, result);
570 * Private constructor; see also Animator::New().
572 Animator(PropertyOwner* propertyOwner,
573 PropertyBase* property,
574 AnimatorFunction animatorFunction,
575 AlphaFunction alphaFunction,
576 const TimePeriod& timePeriod)
577 : AnimatorBase(propertyOwner, alphaFunction, timePeriod),
578 mAnimatorFunction(std::move(animatorFunction)),
579 mPropertyAccessor(property)
581 // WARNING - this object is created in the event-thread
582 // The scene-graph mPropertyOwner object cannot be observed here
586 Animator(const Animator&);
589 Animator& operator=(const Animator&);
592 PropertyAccessorType mPropertyAccessor;
596 * An animator for a specific property type PropertyType.
598 template<typename PropertyType, typename PropertyAccessorType>
599 class AnimatorTransformProperty final : public AnimatorBase
601 using AnimatorFunction = std::function<PropertyType(float, const PropertyType&)>;
603 AnimatorFunction mAnimatorFunction;
607 * Construct a new property animator.
608 * @param[in] property The animatable property; only valid while the Animator is attached.
609 * @param[in] animatorFunction The function used to animate the property.
610 * @param[in] alphaFunction The alpha function to apply.
611 * @param[in] timePeriod The time period of this animation.
612 * @return A newly allocated animator.
614 static AnimatorBase* New(const PropertyOwner& propertyOwner,
615 const PropertyBase& property,
616 AnimatorFunction animatorFunction,
617 AlphaFunction alphaFunction,
618 const TimePeriod& timePeriod)
620 // The property was const in the actor-thread, but animators are used in the scene-graph thread.
621 return new AnimatorTransformProperty(const_cast<PropertyOwner*>(&propertyOwner),
622 const_cast<PropertyBase*>(&property),
623 std::move(animatorFunction),
629 * @copydoc AnimatorBase::DoUpdate( BufferIndex bufferIndex, bool bake, float alpha )
631 void DoUpdate(BufferIndex bufferIndex, bool bake, float alpha) final
633 const PropertyType& current = mPropertyAccessor.Get(bufferIndex);
635 // need to cast the return value in case property is integer
636 const PropertyType result = static_cast<PropertyType>(mAnimatorFunction(alpha, current));
640 mPropertyAccessor.Bake(bufferIndex, result);
644 mPropertyAccessor.Set(bufferIndex, result);
650 * Private constructor; see also Animator::New().
652 AnimatorTransformProperty(PropertyOwner* propertyOwner,
653 PropertyBase* property,
654 AnimatorFunction animatorFunction,
655 AlphaFunction alphaFunction,
656 const TimePeriod& timePeriod)
657 : AnimatorBase(propertyOwner, alphaFunction, timePeriod),
658 mAnimatorFunction(std::move(animatorFunction)),
659 mPropertyAccessor(property)
661 // WARNING - this object is created in the event-thread
662 // The scene-graph mPropertyOwner object cannot be observed here
666 AnimatorTransformProperty() = delete;
667 AnimatorTransformProperty(const AnimatorTransformProperty&) = delete;
668 AnimatorTransformProperty& operator=(const AnimatorTransformProperty&) = delete;
671 PropertyAccessorType mPropertyAccessor;
674 } // namespace SceneGraph
678 struct AnimateByInteger
680 AnimateByInteger(const int& relativeValue)
681 : mRelative(relativeValue)
685 float operator()(float alpha, const int32_t& property)
687 // integers need to be correctly rounded
688 return roundf(static_cast<float>(property) + static_cast<float>(mRelative) * alpha);
694 struct AnimateToInteger
696 AnimateToInteger(const int& targetValue)
697 : mTarget(targetValue)
701 float operator()(float alpha, const int32_t& property)
703 // integers need to be correctly rounded
704 return roundf(static_cast<float>(property) + (static_cast<float>(mTarget - property) * alpha));
710 struct AnimateByFloat
712 AnimateByFloat(const float& relativeValue)
713 : mRelative(relativeValue)
717 float operator()(float alpha, const float& property)
719 return float(property + mRelative * alpha);
725 struct AnimateToFloat
727 AnimateToFloat(const float& targetValue)
728 : mTarget(targetValue)
732 float operator()(float alpha, const float& property)
734 return float(property + ((mTarget - property) * alpha));
740 struct AnimateByVector2
742 AnimateByVector2(const Vector2& relativeValue)
743 : mRelative(relativeValue)
747 Vector2 operator()(float alpha, const Vector2& property)
749 return Vector2(property + mRelative * alpha);
755 struct AnimateToVector2
757 AnimateToVector2(const Vector2& targetValue)
758 : mTarget(targetValue)
762 Vector2 operator()(float alpha, const Vector2& property)
764 return Vector2(property + ((mTarget - property) * alpha));
770 struct AnimateByVector3
772 AnimateByVector3(const Vector3& relativeValue)
773 : mRelative(relativeValue)
777 Vector3 operator()(float alpha, const Vector3& property)
779 return Vector3(property + mRelative * alpha);
785 struct AnimateToVector3
787 AnimateToVector3(const Vector3& targetValue)
788 : mTarget(targetValue)
792 Vector3 operator()(float alpha, const Vector3& property)
794 return Vector3(property + ((mTarget - property) * alpha));
800 struct AnimateByVector4
802 AnimateByVector4(const Vector4& relativeValue)
803 : mRelative(relativeValue)
807 Vector4 operator()(float alpha, const Vector4& property)
809 return Vector4(property + mRelative * alpha);
815 struct AnimateToVector4
817 AnimateToVector4(const Vector4& targetValue)
818 : mTarget(targetValue)
822 Vector4 operator()(float alpha, const Vector4& property)
824 return Vector4(property + ((mTarget - property) * alpha));
830 struct AnimateByOpacity
832 AnimateByOpacity(const float& relativeValue)
833 : mRelative(relativeValue)
837 Vector4 operator()(float alpha, const Vector4& property)
839 Vector4 result(property);
840 result.a += mRelative * alpha;
848 struct AnimateToOpacity
850 AnimateToOpacity(const float& targetValue)
851 : mTarget(targetValue)
855 Vector4 operator()(float alpha, const Vector4& property)
857 Vector4 result(property);
858 result.a = property.a + ((mTarget - property.a) * alpha);
866 struct AnimateByBoolean
868 AnimateByBoolean(bool relativeValue)
869 : mRelative(relativeValue)
873 bool operator()(float alpha, const bool& property)
875 // Alpha is not useful here, just keeping to the same template as other update functors
876 return bool(alpha >= 1.0f ? (property || mRelative) : property);
882 struct AnimateToBoolean
884 AnimateToBoolean(bool targetValue)
885 : mTarget(targetValue)
889 bool operator()(float alpha, const bool& property)
891 // Alpha is not useful here, just keeping to the same template as other update functors
892 return bool(alpha >= 1.0f ? mTarget : property);
898 struct RotateByAngleAxis
900 RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
901 : mAngleRadians(angleRadians),
902 mAxis(axis.x, axis.y, axis.z)
906 Quaternion operator()(float alpha, const Quaternion& rotation)
910 return rotation * Quaternion(mAngleRadians * alpha, mAxis);
916 Radian mAngleRadians;
920 struct RotateToQuaternion
922 RotateToQuaternion(const Quaternion& targetValue)
923 : mTarget(targetValue)
927 Quaternion operator()(float alpha, const Quaternion& rotation)
929 return Quaternion::Slerp(rotation, mTarget, alpha);
935 struct KeyFrameBooleanFunctor
937 KeyFrameBooleanFunctor(KeyFrameBoolean keyFrames)
938 : mKeyFrames(std::move(keyFrames))
942 bool operator()(float progress, const bool& property)
944 if(mKeyFrames.IsActive(progress))
946 return mKeyFrames.GetValue(progress, Dali::Animation::LINEAR);
951 KeyFrameBoolean mKeyFrames;
954 struct KeyFrameIntegerFunctor
956 KeyFrameIntegerFunctor(KeyFrameInteger keyFrames, Interpolation interpolation)
957 : mKeyFrames(std::move(keyFrames)),
958 mInterpolation(interpolation)
962 float operator()(float progress, const int32_t& property)
964 if(mKeyFrames.IsActive(progress))
966 return static_cast<float>(mKeyFrames.GetValue(progress, mInterpolation));
968 return static_cast<float>(property);
971 KeyFrameInteger mKeyFrames;
972 Interpolation mInterpolation;
975 struct KeyFrameNumberFunctor
977 KeyFrameNumberFunctor(KeyFrameNumber keyFrames, Interpolation interpolation)
978 : mKeyFrames(std::move(keyFrames)),
979 mInterpolation(interpolation)
983 float operator()(float progress, const float& property)
985 if(mKeyFrames.IsActive(progress))
987 return mKeyFrames.GetValue(progress, mInterpolation);
992 KeyFrameNumber mKeyFrames;
993 Interpolation mInterpolation;
996 struct KeyFrameVector2Functor
998 KeyFrameVector2Functor(KeyFrameVector2 keyFrames, Interpolation interpolation)
999 : mKeyFrames(std::move(keyFrames)),
1000 mInterpolation(interpolation)
1004 Vector2 operator()(float progress, const Vector2& property)
1006 if(mKeyFrames.IsActive(progress))
1008 return mKeyFrames.GetValue(progress, mInterpolation);
1013 KeyFrameVector2 mKeyFrames;
1014 Interpolation mInterpolation;
1017 struct KeyFrameVector3Functor
1019 KeyFrameVector3Functor(KeyFrameVector3 keyFrames, Interpolation interpolation)
1020 : mKeyFrames(std::move(keyFrames)),
1021 mInterpolation(interpolation)
1025 Vector3 operator()(float progress, const Vector3& property)
1027 if(mKeyFrames.IsActive(progress))
1029 return mKeyFrames.GetValue(progress, mInterpolation);
1034 KeyFrameVector3 mKeyFrames;
1035 Interpolation mInterpolation;
1038 struct KeyFrameVector4Functor
1040 KeyFrameVector4Functor(KeyFrameVector4 keyFrames, Interpolation interpolation)
1041 : mKeyFrames(std::move(keyFrames)),
1042 mInterpolation(interpolation)
1046 Vector4 operator()(float progress, const Vector4& property)
1048 if(mKeyFrames.IsActive(progress))
1050 return mKeyFrames.GetValue(progress, mInterpolation);
1055 KeyFrameVector4 mKeyFrames;
1056 Interpolation mInterpolation;
1059 struct KeyFrameQuaternionFunctor
1061 KeyFrameQuaternionFunctor(KeyFrameQuaternion keyFrames)
1062 : mKeyFrames(std::move(keyFrames))
1066 Quaternion operator()(float progress, const Quaternion& property)
1068 if(mKeyFrames.IsActive(progress))
1070 return mKeyFrames.GetValue(progress, Dali::Animation::LINEAR);
1075 KeyFrameQuaternion mKeyFrames;
1078 struct PathPositionFunctor
1080 PathPositionFunctor(PathPtr path)
1085 Vector3 operator()(float progress, const Vector3& property)
1087 Vector3 position(property);
1088 static_cast<void>(mPath->SamplePosition(progress, position));
1095 struct PathRotationFunctor
1097 PathRotationFunctor(PathPtr path, const Vector3& forward)
1101 mForward.Normalize();
1104 Quaternion operator()(float progress, const Quaternion& property)
1107 if(mPath->SampleTangent(progress, tangent))
1109 return Quaternion(mForward, tangent);
1121 } // namespace Internal
1125 #endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H