END_TEST;
}
+int UtcDaliAnimationSetLoopingModeP4(void)
+{
+ // Test Loop Count is 1 (== default) and Loop mode being set 'before' Animators connected
+ TestApplication application;
+ Integration::Scene stage(application.GetScene());
+
+ // LoopingMode::AUTO_REVERSE
+ {
+ Actor actor = Actor::New();
+ stage.Add(actor);
+
+ float durationSeconds(1.0f);
+ Animation animation = Animation::New(durationSeconds);
+ DALI_TEST_CHECK(1 == animation.GetLoopCount());
+
+ bool signalReceived(false);
+ AnimationFinishCheck finishCheck(signalReceived);
+ animation.FinishedSignal().Connect(&application, finishCheck);
+ application.SendNotification();
+
+ Vector3 targetPosition(100.0f, 100.0f, 100.0f);
+
+ DALI_TEST_CHECK(animation.GetLoopingMode() == Animation::RESTART);
+ animation.SetLoopingMode(Animation::AUTO_REVERSE);
+ DALI_TEST_CHECK(animation.GetLoopingMode() == Animation::AUTO_REVERSE);
+ animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition);
+
+ // Start the animation
+ animation.Play();
+ application.Render(0);
+ application.SendNotification();
+
+ application.Render(static_cast<unsigned int>(durationSeconds * 0.5f * 1000.0f) /* 50% time progress */);
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+
+ // AUTO_REVERSE mode means, for Animation duration time, the actor starts from the beginning, passes the targetPosition,
+ // and arrives at the beginning.
+ DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), targetPosition, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds * 0.5f * 1000.0f) /* 100% time progress */);
+
+ application.SendNotification();
+ DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3(0.0f, 0.0f, 0.0f), TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds * 1.0f * 1000.0f) + 1u /*just beyond the animation duration*/);
+
+ application.SendNotification();
+ application.Render(0);
+ application.SendNotification();
+ finishCheck.CheckSignalReceived();
+
+ // After all animation finished, arrives at the beginning.
+ DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3(0.0f, 0.0f, 0.0f), TEST_LOCATION);
+
+ finishCheck.Reset();
+ }
+
+ // LoopingMode::AUTO_REVERSE in Reverse mode, which begin from the end
+ {
+ Actor actor = Actor::New();
+ stage.Add(actor);
+
+ float durationSeconds(1.0f);
+ Animation animation = Animation::New(durationSeconds);
+ DALI_TEST_CHECK(1 == animation.GetLoopCount());
+
+ bool signalReceived(false);
+ AnimationFinishCheck finishCheck(signalReceived);
+ animation.FinishedSignal().Connect(&application, finishCheck);
+ application.SendNotification();
+
+ // Specify a negative multiplier to play the animation in reverse
+ animation.SetSpeedFactor(-1.0f);
+
+ animation.SetLoopingMode(Animation::AUTO_REVERSE);
+ DALI_TEST_CHECK(animation.GetLoopingMode() == Animation::AUTO_REVERSE);
+
+ Vector3 targetPosition(100.0f, 100.0f, 100.0f);
+ animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition);
+
+ // Start the animation
+ animation.Play();
+ application.Render(0);
+ application.SendNotification();
+
+ application.Render(static_cast<unsigned int>(durationSeconds * 0.5f * 1000.0f) /* 50% time progress */);
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+
+ // Setting a negative speed factor is to play the animation in reverse.
+ // So, when LoopingMode::AUTO_REVERSE and SetSpeedFactor( -1.0f ) is, for Animation duration time,
+ // the actor starts from the targetPosition, passes the beginning, and arrives at the targetPosition.
+ DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3(0.0f, 0.0f, 0.0f), TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds * 0.5f * 1000.0f) /* 100% time progress */);
+
+ application.SendNotification();
+ DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), targetPosition, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds * 1.0f * 1000.0f) + 1u /*just beyond the animation duration*/);
+
+ application.SendNotification();
+ application.Render(0);
+ application.SendNotification();
+ finishCheck.CheckSignalReceived();
+
+ // After all animation finished, arrives at the target.
+ DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), targetPosition, TEST_LOCATION);
+
+ finishCheck.Reset();
+ }
+
+ END_TEST;
+}
+
int UtcDaliAnimationGetLoopingModeP(void)
{
TestApplication application;
#define DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
mPropertyOwner(propertyOwner),
mDurationSeconds(timePeriod.durationSeconds),
mIntervalDelaySeconds(timePeriod.delaySeconds),
- mSpeedFactor(1.0f),
mCurrentProgress(0.f),
mAlphaFunction(alphaFunction),
mDisconnectAction(Dali::Animation::BAKE_FINAL),
mAnimationPlaying(false),
mEnabled(true),
mConnectedToSceneGraph(false),
- mAutoReverseEnabled(false),
mDelayed(false)
{
}
return mDurationSeconds;
}
- void SetSpeedFactor(float factor)
- {
- mSpeedFactor = factor;
- }
-
- void SetLoopCount(int32_t loopCount)
- {
- mLoopCount = loopCount;
- }
-
- float SetProgress(float progress)
- {
- float value = 0.0f;
-
- if(mAutoReverseEnabled)
- {
- if(mSpeedFactor > 0.0f)
- {
- value = 1.0f - 2.0f * std::abs(progress - 0.5f);
- }
- // Reverse mode
- else if(mSpeedFactor < 0.0f)
- {
- value = 2.0f * std::abs(progress - 0.5f);
- }
- }
- else
- {
- value = progress;
- }
-
- return value;
- }
-
/**
* Set the delay before the animator should take effect.
* The default is zero i.e. no delay.
return mEnabled;
}
- /**
- * @brief Sets the looping mode.
- * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
- */
- void SetLoopingMode(bool loopingMode)
- {
- mAutoReverseEnabled = loopingMode;
- }
-
/**
* Returns wheter the target object of the animator is still valid
* or has been destroyed.
*/
void Update(BufferIndex bufferIndex, float progress, float blendPoint, bool bake)
{
- if(mLoopCount >= 0)
- {
- // Update the progress value
- progress = SetProgress(progress);
- }
-
if(mPropertyOwner)
{
mPropertyOwner->SetUpdated(true);
float mDurationSeconds;
float mIntervalDelaySeconds;
- float mSpeedFactor;
float mCurrentProgress;
AlphaFunction mAlphaFunction;
- int32_t mLoopCount{1};
Dali::Animation::EndAction mDisconnectAction; ///< EndAction to apply when target object gets disconnected from the stage.
bool mAnimationPlaying : 1; ///< whether disconnect has been applied 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.
- bool mAutoReverseEnabled : 1;
- bool mDelayed : 1; ///< True if the animator is in delayed state
+ bool mDelayed : 1; ///< True if the animator is in delayed state
};
/**