1 #ifndef DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H
2 #define DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H
5 * Copyright (c) 2024 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),
99 ~AnimatorBase() override
101 if(mPropertyOwner && mConnectedToSceneGraph)
103 mPropertyOwner->RemoveObserver(*this);
105 if(mLifecycleObserver != nullptr)
107 mLifecycleObserver->ObjectDestroyed();
111 void AddLifecycleObserver(LifecycleObserver& observer)
113 mLifecycleObserver = &observer;
116 void RemoveLifecycleObserver(LifecycleObserver& observer)
118 mLifecycleObserver = nullptr;
121 private: // From PropertyOwner::Observer
123 * @copydoc PropertyOwner::Observer::PropertyOwnerConnected( PropertyOwner& owner )
125 void PropertyOwnerConnected(PropertyOwner& owner) final
131 * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
133 NotifyReturnType PropertyOwnerDisconnected(BufferIndex bufferIndex, PropertyOwner& owner) final
135 // If we are active, then bake the value if required
136 if(mAnimationPlaying && mDisconnectAction != Dali::Animation::DISCARD)
138 // Bake to target-value if BakeFinal, otherwise bake current value
139 Update(bufferIndex, (mDisconnectAction == Dali::Animation::BAKE ? mCurrentProgress : 1.0f), 0.0f, true);
144 return NotifyReturnType::KEEP_OBSERVING;
148 * @copydoc PropertyOwner::Observer::PropertyOwnerDestroyed( PropertyOwner& owner )
150 void PropertyOwnerDestroyed(PropertyOwner& owner) final
152 mPropertyOwner = nullptr;
157 * Called when Animator is added to the scene-graph in update-thread.
159 void ConnectToSceneGraph()
161 mConnectedToSceneGraph = true;
162 mPropertyOwner->AddObserver(*this);
164 // Enable if the target object is valid and connected to the scene graph.
165 mEnabled = mPropertyOwner->IsAnimationPossible();
169 * Set the duration of the animator.
170 * @pre durationSeconds must be zero or greater; zero is useful when animating boolean values.
171 * @param [in] seconds Duration in seconds.
173 void SetDuration(float seconds)
175 DALI_ASSERT_DEBUG(seconds >= 0.0f);
177 mDurationSeconds = seconds;
181 * Retrieve the duration of the animator.
182 * @return The duration in seconds.
184 float GetDuration() const
186 return mDurationSeconds;
189 void SetSpeedFactor(float factor)
191 mSpeedFactor = factor;
194 void SetLoopCount(int32_t loopCount)
196 mLoopCount = loopCount;
199 float SetProgress(float progress)
203 if(mAutoReverseEnabled)
205 if(mSpeedFactor > 0.0f)
207 value = 1.0f - 2.0f * std::abs(progress - 0.5f);
210 else if(mSpeedFactor < 0.0f)
212 value = 2.0f * std::abs(progress - 0.5f);
224 * Set the delay before the animator should take effect.
225 * The default is zero i.e. no delay.
226 * @param [in] seconds The delay in seconds.
228 void SetIntervalDelay(float seconds)
230 mIntervalDelaySeconds = seconds;
234 * Retrieve the delay before the animator should take effect.
235 * @return The delay in seconds.
237 float GetIntervalDelay() const
239 return mIntervalDelaySeconds;
243 * Sets whether the animator is delayed or not.
244 * @param delayed True if the animator is delayed.
246 void SetDelayed(bool delayed)
248 if(delayed != mDelayed)
252 mPropertyOwner->SetUpdated(true);
259 * Set the alpha function for an animator.
260 * @param [in] alphaFunc The alpha function to apply to the animation progress.
262 void SetAlphaFunction(const AlphaFunction& alphaFunction)
264 mAlphaFunction = alphaFunction;
268 * Retrieve the alpha function of an animator.
269 * @return The function.
271 AlphaFunction GetAlphaFunction() const
273 return mAlphaFunction;
277 * Applies the alpha function to the specified progress
278 * @param[in] Current progress
279 * @return The progress after the alpha function has been aplied
281 float ApplyAlphaFunction(float progress) const
283 float result = progress;
285 AlphaFunction::Mode alphaFunctionMode(mAlphaFunction.GetMode());
286 if(alphaFunctionMode == AlphaFunction::BUILTIN_FUNCTION)
288 switch(mAlphaFunction.GetBuiltinFunction())
290 case AlphaFunction::DEFAULT:
291 case AlphaFunction::LINEAR:
295 case AlphaFunction::REVERSE:
297 result = 1.0f - progress;
300 case AlphaFunction::EASE_IN_SQUARE:
302 result = progress * progress;
305 case AlphaFunction::EASE_OUT_SQUARE:
307 result = 1.0f - (1.0f - progress) * (1.0f - progress);
310 case AlphaFunction::EASE_IN:
312 result = progress * progress * progress;
315 case AlphaFunction::EASE_OUT:
317 result = (progress - 1.0f) * (progress - 1.0f) * (progress - 1.0f) + 1.0f;
320 case AlphaFunction::EASE_IN_OUT:
322 result = progress * progress * (3.0f - 2.0f * progress);
325 case AlphaFunction::EASE_IN_SINE:
327 result = -1.0f * cosf(progress * Math::PI_2) + 1.0f;
330 case AlphaFunction::EASE_OUT_SINE:
332 result = sinf(progress * Math::PI_2);
335 case AlphaFunction::EASE_IN_OUT_SINE:
337 result = -0.5f * (cosf(Math::PI * progress) - 1.0f);
340 case AlphaFunction::BOUNCE:
342 result = sinf(progress * Math::PI);
345 case AlphaFunction::SIN:
347 result = 0.5f - cosf(progress * 2.0f * Math::PI) * 0.5f;
350 case AlphaFunction::EASE_OUT_BACK:
352 const float sqrt2 = 1.70158f;
354 result = 1.0f + progress * progress * ((sqrt2 + 1.0f) * progress + sqrt2);
357 case AlphaFunction::COUNT:
363 else if(alphaFunctionMode == AlphaFunction::CUSTOM_FUNCTION)
365 AlphaFunctionPrototype customFunction = mAlphaFunction.GetCustomFunction();
368 result = customFunction(progress);
373 // If progress is very close to 0 or very close to 1 we don't need to evaluate the curve as the result will
374 // be almost 0 or almost 1 respectively
375 if((progress > Math::MACHINE_EPSILON_1) && ((1.0f - progress) > Math::MACHINE_EPSILON_1))
377 Dali::Vector4 controlPoints = mAlphaFunction.GetBezierControlPoints();
379 static const float tolerance = 0.00005f; // 15 iteration max
381 // Perform a binary search on the curve
382 float lowerBound(0.0f);
383 float upperBound(1.0f);
384 float currentT(0.5f);
385 float currentX = EvaluateCubicBezier(controlPoints.x, controlPoints.z, currentT);
386 while(fabsf(progress - currentX) > tolerance)
388 if(progress > currentX)
390 lowerBound = currentT;
394 upperBound = currentT;
396 currentT = (upperBound + lowerBound) * 0.5f;
397 currentX = EvaluateCubicBezier(controlPoints.x, controlPoints.z, currentT);
399 result = EvaluateCubicBezier(controlPoints.y, controlPoints.w, currentT);
407 * Whether to bake the animation if attached property owner is disconnected.
408 * Property is only baked if the animator is active.
409 * @param [in] action The disconnect action.
411 void SetDisconnectAction(Dali::Animation::EndAction action)
413 mDisconnectAction = action;
417 * Retrieve the disconnect action of an animator.
418 * @return The disconnect action.
420 Dali::Animation::EndAction GetDisconnectAction() const
422 return mDisconnectAction;
426 * Whether the animator is active or not.
427 * @param [in] active The new active state.
428 * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected.
429 * @note When the property owner is disconnected, the active state is set to false.
431 void SetActive(bool active)
433 mAnimationPlaying = active;
437 * Whether the animator's target object is valid and on the stage.
438 * @return The enabled state.
440 bool IsEnabled() const
446 * @brief Sets the looping mode.
447 * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
449 void SetLoopingMode(bool loopingMode)
451 mAutoReverseEnabled = loopingMode;
455 * Returns wheter the target object of the animator is still valid
456 * or has been destroyed.
457 * @return True if animator is orphan, false otherwise *
458 * @note The SceneGraph::Animation will delete any orphan animator in its Update method.
462 return (mPropertyOwner == nullptr);
466 * Update the scene object attached to the animator.
467 * @param[in] bufferIndex The buffer to animate.
468 * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point.
469 * @param[in] blendPoint A value between [0,1], The Animated property is animated as it blends until the progress reaches the blendPoint.
470 * @param[in] bake Bake.
472 void Update(BufferIndex bufferIndex, float progress, float blendPoint, bool bake)
476 // Update the progress value
477 progress = SetProgress(progress);
482 mPropertyOwner->SetUpdated(true);
485 float alpha = ApplyAlphaFunction(progress);
487 // PropertyType specific part
488 DoUpdate(bufferIndex, bake, alpha, blendPoint);
490 mCurrentProgress = progress;
495 * Type specific part of the animator
496 * @param bufferIndex index to use
497 * @param bake whether to bake or not
498 * @param alpha value from alpha based on progress
499 * @param blendPoint A value between [0,1], The Animated property is animated as it blends until the progress reaches the blendPoint.
501 virtual void DoUpdate(BufferIndex bufferIndex, bool bake, float alpha, float blendPoint) = 0;
505 * Helper function to evaluate a cubic bezier curve assuming first point is at 0.0 and last point is at 1.0
506 * @param[in] p0 First control point of the bezier curve
507 * @param[in] p1 Second control point of the bezier curve
508 * @param[in] t A floating point value between 0.0 and 1.0
509 * @return Value of the curve at progress t
511 inline float EvaluateCubicBezier(float p0, float p1, float t) const
513 float tSquare = t * t;
514 return 3.0f * (1.0f - t) * (1.0f - t) * t * p0 + 3.0f * (1.0f - t) * tSquare * p1 + tSquare * t;
517 LifecycleObserver* mLifecycleObserver;
518 PropertyOwner* mPropertyOwner;
520 float mDurationSeconds;
521 float mIntervalDelaySeconds;
523 float mCurrentProgress;
525 AlphaFunction mAlphaFunction;
527 int32_t mLoopCount{1};
528 Dali::Animation::EndAction mDisconnectAction; ///< EndAction to apply when target object gets disconnected from the stage.
529 bool mAnimationPlaying : 1; ///< whether disconnect has been applied while it's running.
530 bool mEnabled : 1; ///< Animator is "enabled" while its target object is valid and on the stage.
531 bool mConnectedToSceneGraph : 1; ///< True if ConnectToSceneGraph() has been called in update-thread.
532 bool mAutoReverseEnabled : 1;
533 bool mDelayed : 1; ///< True if the animator is in delayed state
537 * An animator for a specific property type PropertyType.
539 template<typename PropertyType, typename PropertyAccessorType>
540 class Animator final : public AnimatorBase
542 using AnimatorFunction = std::function<PropertyType(float, float, const PropertyType&)>;
544 AnimatorFunction mAnimatorFunction;
548 * Construct a new property animator.
549 * @param[in] property The animatable property; only valid while the Animator is attached.
550 * @param[in] animatorFunction The function used to animate the property.
551 * @param[in] alphaFunction The alpha function to apply.
552 * @param[in] timePeriod The time period of this animation.
553 * @return A newly allocated animator.
555 static AnimatorBase* New(const PropertyOwner& propertyOwner,
556 const PropertyBase& property,
557 AnimatorFunction animatorFunction,
558 AlphaFunction alphaFunction,
559 const TimePeriod& timePeriod)
561 // The property was const in the actor-thread, but animators are used in the scene-graph thread.
562 return new Animator(const_cast<PropertyOwner*>(&propertyOwner),
563 const_cast<PropertyBase*>(&property),
564 std::move(animatorFunction),
570 * @copydoc AnimatorBase::DoUpdate( BufferIndex bufferIndex, bool bake, float alpha )
572 void DoUpdate(BufferIndex bufferIndex, bool bake, float alpha, float blendPoint) final
574 const PropertyType& current = mPropertyAccessor.Get(bufferIndex);
576 // need to cast the return value in case property is integer
577 const PropertyType result = static_cast<PropertyType>(mAnimatorFunction(alpha, blendPoint, current));
581 mPropertyAccessor.Bake(bufferIndex, result);
585 mPropertyAccessor.Set(bufferIndex, result);
591 * Private constructor; see also Animator::New().
593 Animator(PropertyOwner* propertyOwner,
594 PropertyBase* property,
595 AnimatorFunction animatorFunction,
596 AlphaFunction alphaFunction,
597 const TimePeriod& timePeriod)
598 : AnimatorBase(propertyOwner, alphaFunction, timePeriod),
599 mAnimatorFunction(std::move(animatorFunction)),
600 mPropertyAccessor(property)
602 // WARNING - this object is created in the event-thread
603 // The scene-graph mPropertyOwner object cannot be observed here
607 Animator(const Animator&);
610 Animator& operator=(const Animator&);
613 PropertyAccessorType mPropertyAccessor;
617 * An animator for a specific property type PropertyType.
619 template<typename PropertyType, typename PropertyAccessorType>
620 class AnimatorTransformProperty final : public AnimatorBase
622 using AnimatorFunction = std::function<PropertyType(float, float, const PropertyType&)>;
624 AnimatorFunction mAnimatorFunction;
628 * Construct a new property animator.
629 * @param[in] property The animatable property; only valid while the Animator is attached.
630 * @param[in] animatorFunction The function used to animate the property.
631 * @param[in] alphaFunction The alpha function to apply.
632 * @param[in] timePeriod The time period of this animation.
633 * @return A newly allocated animator.
635 static AnimatorBase* New(const PropertyOwner& propertyOwner,
636 const PropertyBase& property,
637 AnimatorFunction animatorFunction,
638 AlphaFunction alphaFunction,
639 const TimePeriod& timePeriod)
641 // The property was const in the actor-thread, but animators are used in the scene-graph thread.
642 return new AnimatorTransformProperty(const_cast<PropertyOwner*>(&propertyOwner),
643 const_cast<PropertyBase*>(&property),
644 std::move(animatorFunction),
650 * @copydoc AnimatorBase::DoUpdate( BufferIndex bufferIndex, bool bake, float alpha )
652 void DoUpdate(BufferIndex bufferIndex, bool bake, float alpha, float blendPoint) final
654 const PropertyType& current = mPropertyAccessor.Get(bufferIndex);
656 // need to cast the return value in case property is integer
657 const PropertyType result = static_cast<PropertyType>(mAnimatorFunction(alpha, blendPoint, current));
661 mPropertyAccessor.Bake(bufferIndex, result);
665 mPropertyAccessor.Set(bufferIndex, result);
671 * Private constructor; see also Animator::New().
673 AnimatorTransformProperty(PropertyOwner* propertyOwner,
674 PropertyBase* property,
675 AnimatorFunction animatorFunction,
676 AlphaFunction alphaFunction,
677 const TimePeriod& timePeriod)
678 : AnimatorBase(propertyOwner, alphaFunction, timePeriod),
679 mAnimatorFunction(std::move(animatorFunction)),
680 mPropertyAccessor(property)
682 // WARNING - this object is created in the event-thread
683 // The scene-graph mPropertyOwner object cannot be observed here
687 AnimatorTransformProperty() = delete;
688 AnimatorTransformProperty(const AnimatorTransformProperty&) = delete;
689 AnimatorTransformProperty& operator=(const AnimatorTransformProperty&) = delete;
692 PropertyAccessorType mPropertyAccessor;
695 } // namespace SceneGraph
699 struct AnimateByInteger
701 AnimateByInteger(const int& relativeValue)
702 : mRelative(relativeValue)
706 float operator()(float alpha, float blendPoint, const int32_t& property)
708 // integers need to be correctly rounded
709 return roundf(static_cast<float>(property) + static_cast<float>(mRelative) * alpha);
715 struct AnimateToInteger
717 AnimateToInteger(const int& targetValue)
718 : mTarget(targetValue)
722 float operator()(float alpha, float blendPoint, const int32_t& property)
724 // integers need to be correctly rounded
725 return roundf(static_cast<float>(property) + (static_cast<float>(mTarget - property) * alpha));
731 struct AnimateByFloat
733 AnimateByFloat(const float& relativeValue)
734 : mRelative(relativeValue)
738 float operator()(float alpha, float blendPoint, const float& property)
740 return float(property + mRelative * alpha);
746 struct AnimateToFloat
748 AnimateToFloat(const float& targetValue)
749 : mTarget(targetValue)
753 float operator()(float alpha, float blendPoint, const float& property)
755 return float(property + ((mTarget - property) * alpha));
761 struct AnimateByVector2
763 AnimateByVector2(const Vector2& relativeValue)
764 : mRelative(relativeValue)
768 Vector2 operator()(float alpha, float blendPoint, const Vector2& property)
770 return Vector2(property + mRelative * alpha);
776 struct AnimateToVector2
778 AnimateToVector2(const Vector2& targetValue)
779 : mTarget(targetValue)
783 Vector2 operator()(float alpha, float blendPoint, const Vector2& property)
785 return Vector2(property + ((mTarget - property) * alpha));
791 struct AnimateByVector3
793 AnimateByVector3(const Vector3& relativeValue)
794 : mRelative(relativeValue)
798 Vector3 operator()(float alpha, float blendPoint, const Vector3& property)
800 return Vector3(property + mRelative * alpha);
806 struct AnimateToVector3
808 AnimateToVector3(const Vector3& targetValue)
809 : mTarget(targetValue)
813 Vector3 operator()(float alpha, float blendPoint, const Vector3& property)
815 return Vector3(property + ((mTarget - property) * alpha));
821 struct AnimateByVector4
823 AnimateByVector4(const Vector4& relativeValue)
824 : mRelative(relativeValue)
828 Vector4 operator()(float alpha, float blendPoint, const Vector4& property)
830 return Vector4(property + mRelative * alpha);
836 struct AnimateToVector4
838 AnimateToVector4(const Vector4& targetValue)
839 : mTarget(targetValue)
843 Vector4 operator()(float alpha, float blendPoint, const Vector4& property)
845 return Vector4(property + ((mTarget - property) * alpha));
851 struct AnimateByOpacity
853 AnimateByOpacity(const float& relativeValue)
854 : mRelative(relativeValue)
858 Vector4 operator()(float alpha, float blendPoint, const Vector4& property)
860 Vector4 result(property);
861 result.a += mRelative * alpha;
869 struct AnimateToOpacity
871 AnimateToOpacity(const float& targetValue)
872 : mTarget(targetValue)
876 Vector4 operator()(float alpha, float blendPoint, const Vector4& property)
878 Vector4 result(property);
879 result.a = property.a + ((mTarget - property.a) * alpha);
887 struct AnimateByBoolean
889 AnimateByBoolean(bool relativeValue)
890 : mRelative(relativeValue)
894 bool operator()(float alpha, float blendPoint, const bool& property)
896 // Alpha is not useful here, just keeping to the same template as other update functors
897 return bool(alpha >= 1.0f ? (property || mRelative) : property);
903 struct AnimateToBoolean
905 AnimateToBoolean(bool targetValue)
906 : mTarget(targetValue)
910 bool operator()(float alpha, float blendPoint, const bool& property)
912 // Alpha is not useful here, just keeping to the same template as other update functors
913 return bool(alpha >= 1.0f ? mTarget : property);
919 struct RotateByAngleAxis
921 RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
922 : mAngleRadians(angleRadians),
923 mAxis(axis.x, axis.y, axis.z)
927 Quaternion operator()(float alpha, float blendPoint, const Quaternion& rotation)
931 return rotation * Quaternion(mAngleRadians * alpha, mAxis);
937 Radian mAngleRadians;
941 struct RotateToQuaternion
943 RotateToQuaternion(const Quaternion& targetValue)
944 : mTarget(targetValue)
948 Quaternion operator()(float alpha, float blendPoint, const Quaternion& rotation)
950 return Quaternion::Slerp(rotation, mTarget, alpha);
956 struct KeyFrameBooleanFunctor
958 KeyFrameBooleanFunctor(KeyFrameBoolean keyFrames)
959 : mKeyFrames(std::move(keyFrames))
963 bool operator()(float progress, float blendPoint, const bool& property)
965 if(mKeyFrames.IsActive(progress))
967 return mKeyFrames.GetValue(progress, Dali::Animation::LINEAR);
972 KeyFrameBoolean mKeyFrames;
975 struct KeyFrameIntegerFunctor
977 KeyFrameIntegerFunctor(KeyFrameInteger keyFrames, Interpolation interpolation)
978 : mKeyFrames(std::move(keyFrames)),
979 mInterpolation(interpolation)
983 int32_t operator()(float progress, float blendPoint, const int32_t& property)
985 if(mKeyFrames.IsActive(progress))
987 if(progress < blendPoint)
989 float subProgress = progress / blendPoint;
990 float original = static_cast<float>(mKeyFrames.GetValue(progress, mInterpolation));
991 float base = Dali::Lerp(subProgress, static_cast<float>(property), static_cast<float>(mKeyFrames.GetValue(blendPoint, mInterpolation)));
992 return static_cast<int32_t>(Dali::Lerp(subProgress, base, original));
996 return static_cast<int32_t>(mKeyFrames.GetValue(progress, mInterpolation));
999 return static_cast<int32_t>(property);
1002 KeyFrameInteger mKeyFrames;
1003 Interpolation mInterpolation;
1006 struct KeyFrameNumberFunctor
1008 KeyFrameNumberFunctor(KeyFrameNumber keyFrames, Interpolation interpolation)
1009 : mKeyFrames(std::move(keyFrames)),
1010 mInterpolation(interpolation)
1014 float operator()(float progress, float blendPoint, const float& property)
1016 if(mKeyFrames.IsActive(progress))
1018 if(progress < blendPoint)
1020 float subProgress = progress / blendPoint;
1021 float original = mKeyFrames.GetValue(progress, mInterpolation);
1022 float base = Dali::Lerp(subProgress, property, mKeyFrames.GetValue(blendPoint, mInterpolation));
1023 return Dali::Lerp(subProgress, base, original);
1027 return mKeyFrames.GetValue(progress, mInterpolation);
1033 KeyFrameNumber mKeyFrames;
1034 Interpolation mInterpolation;
1037 struct KeyFrameVector2Functor
1039 KeyFrameVector2Functor(KeyFrameVector2 keyFrames, Interpolation interpolation)
1040 : mKeyFrames(std::move(keyFrames)),
1041 mInterpolation(interpolation)
1045 Vector2 operator()(float progress, float blendPoint, const Vector2& property)
1047 if(mKeyFrames.IsActive(progress))
1049 if(progress < blendPoint)
1051 float subProgress = progress / blendPoint;
1052 Vector2 original = mKeyFrames.GetValue(progress, mInterpolation);
1053 Vector2 base = Dali::Lerp(subProgress, property, mKeyFrames.GetValue(blendPoint, mInterpolation));
1054 return Dali::Lerp(subProgress, base, original);
1058 return mKeyFrames.GetValue(progress, mInterpolation);
1064 KeyFrameVector2 mKeyFrames;
1065 Interpolation mInterpolation;
1068 struct KeyFrameVector3Functor
1070 KeyFrameVector3Functor(KeyFrameVector3 keyFrames, Interpolation interpolation)
1071 : mKeyFrames(std::move(keyFrames)),
1072 mInterpolation(interpolation)
1076 Vector3 operator()(float progress, float blendPoint, const Vector3& property)
1078 if(mKeyFrames.IsActive(progress))
1080 if(progress < blendPoint)
1082 float subProgress = progress / blendPoint;
1083 Vector3 original = mKeyFrames.GetValue(progress, mInterpolation);
1084 Vector3 base = Dali::Lerp(subProgress, property, mKeyFrames.GetValue(blendPoint, mInterpolation));
1085 return Dali::Lerp(subProgress, base, original);
1089 return mKeyFrames.GetValue(progress, mInterpolation);
1095 KeyFrameVector3 mKeyFrames;
1096 Interpolation mInterpolation;
1099 struct KeyFrameVector4Functor
1101 KeyFrameVector4Functor(KeyFrameVector4 keyFrames, Interpolation interpolation)
1102 : mKeyFrames(std::move(keyFrames)),
1103 mInterpolation(interpolation)
1107 Vector4 operator()(float progress, float blendPoint, const Vector4& property)
1109 if(mKeyFrames.IsActive(progress))
1111 if(progress < blendPoint)
1113 float subProgress = progress / blendPoint;
1114 Vector4 original = mKeyFrames.GetValue(progress, mInterpolation);
1115 Vector4 base = Dali::Lerp(subProgress, property, mKeyFrames.GetValue(blendPoint, mInterpolation));
1116 return Dali::Lerp(subProgress, base, original);
1120 return mKeyFrames.GetValue(progress, mInterpolation);
1126 KeyFrameVector4 mKeyFrames;
1127 Interpolation mInterpolation;
1130 struct KeyFrameQuaternionFunctor
1132 KeyFrameQuaternionFunctor(KeyFrameQuaternion keyFrames)
1133 : mKeyFrames(std::move(keyFrames))
1137 Quaternion operator()(float progress, float blendPoint, const Quaternion& property)
1139 if(mKeyFrames.IsActive(progress))
1141 if(progress < blendPoint)
1143 float subProgress = progress / blendPoint;
1144 Quaternion original = mKeyFrames.GetValue(progress, Dali::Animation::LINEAR);
1145 Quaternion base = Quaternion::Slerp(property, mKeyFrames.GetValue(blendPoint, Dali::Animation::LINEAR), subProgress);
1146 return Quaternion::Slerp(base, original, subProgress);
1150 return mKeyFrames.GetValue(progress, Dali::Animation::LINEAR);
1156 KeyFrameQuaternion mKeyFrames;
1159 struct PathPositionFunctor
1161 PathPositionFunctor(PathPtr path)
1166 Vector3 operator()(float progress, float blendPoint, const Vector3& property)
1168 Vector3 position(property);
1169 static_cast<void>(mPath->SamplePosition(progress, position));
1176 struct PathRotationFunctor
1178 PathRotationFunctor(PathPtr path, const Vector3& forward)
1182 mForward.Normalize();
1185 Quaternion operator()(float progress, float blendPoint, const Quaternion& property)
1188 if(mPath->SampleTangent(progress, tangent))
1190 return Quaternion(mForward, tangent);
1202 } // namespace Internal
1206 #endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H