Add loopCount to PlaySlotAnimation for looping slot animation

This commit is contained in:
Wojtek Figat
2022-04-14 23:18:37 +02:00
parent 03524caebf
commit 991abb1cf8
5 changed files with 29 additions and 10 deletions

View File

@@ -111,6 +111,8 @@ void SlotBucketInit(AnimGraphInstanceData::Bucket& bucket)
bucket.Slot.TimePosition = 0.0f;
bucket.Slot.BlendInPosition = 0.0f;
bucket.Slot.BlendOutPosition = 0.0f;
bucket.Slot.LoopsDone = 0;
bucket.Slot.LoopsLeft = 0;
}
bool SortMultiBlend1D(const byte& a, const byte& b, AnimGraphNode* n)

View File

@@ -260,6 +260,7 @@ struct FLAXENGINE_API AnimGraphSlot
float Speed = 1.0f;
float BlendInTime = 0.0f;
float BlendOutTime = 0.0f;
int32 LoopCount = 0;
bool Pause = false;
};
@@ -314,6 +315,8 @@ public:
float TimePosition;
float BlendInPosition;
float BlendOutPosition;
int32 LoopsDone;
int32 LoopsLeft;
};
/// <summary>

View File

@@ -1924,6 +1924,8 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
bucket.TimePosition = 0.0f;
bucket.BlendInPosition = 0.0f;
bucket.BlendOutPosition = 0.0f;
bucket.LoopsDone = 0;
bucket.LoopsLeft = slot.LoopCount;
break;
}
}
@@ -1940,18 +1942,27 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
ASSERT(slot.Animation && slot.Animation->IsLoaded());
const float deltaTime = slot.Pause ? 0.0f : context.DeltaTime * slot.Speed;
const float length = anim->GetLength();
const bool loop = bucket.LoopsLeft != 0;
float newTimePos = bucket.TimePosition + deltaTime;
if (newTimePos >= length)
{
// End playing animation
value = tryGetValue(node->GetBox(1), Value::Null);
bucket.Index = -1;
slot.Animation = nullptr;
return;
if (bucket.LoopsLeft == 0)
{
// End playing animation
value = tryGetValue(node->GetBox(1), Value::Null);
bucket.Index = -1;
slot.Animation = nullptr;
return;
}
// Loop animation
if (bucket.LoopsLeft > 0)
bucket.LoopsLeft--;
bucket.LoopsDone++;
}
value = SampleAnimation(node, false, length, 0.0f, bucket.TimePosition, newTimePos, anim, slot.Speed);
value = SampleAnimation(node, loop, length, 0.0f, bucket.TimePosition, newTimePos, anim, slot.Speed);
bucket.TimePosition = newTimePos;
if (slot.BlendOutTime > 0.0f && length - slot.BlendOutTime < bucket.TimePosition)
if (bucket.LoopsLeft == 0 && slot.BlendOutTime > 0.0f && length - slot.BlendOutTime < bucket.TimePosition)
{
// Blend out
auto input = tryGetValue(node->GetBox(1), Value::Null);
@@ -1959,7 +1970,7 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
const float alpha = Math::Saturate(bucket.BlendOutPosition / slot.BlendOutTime);
value = Blend(node, value, input, alpha, AlphaBlendMode::HermiteCubic);
}
else if (slot.BlendInTime > 0.0f && bucket.BlendInPosition < slot.BlendInTime)
else if (bucket.LoopsDone == 0 && slot.BlendInTime > 0.0f && bucket.BlendInPosition < slot.BlendInTime)
{
// Blend in
auto input = tryGetValue(node->GetBox(1), Value::Null);

View File

@@ -325,7 +325,7 @@ void AnimatedModel::ClearBlendShapeWeights()
_blendShapes.Clear();
}
void AnimatedModel::PlaySlotAnimation(const StringView& slotName, Animation* anim, float speed, float blendInTime, float blendOutTime)
void AnimatedModel::PlaySlotAnimation(const StringView& slotName, Animation* anim, float speed, float blendInTime, float blendOutTime, int32 loopCount)
{
CHECK(anim);
for (auto& slot : GraphInstance.Slots)
@@ -334,6 +334,7 @@ void AnimatedModel::PlaySlotAnimation(const StringView& slotName, Animation* ani
{
slot.Pause = false;
slot.BlendInTime = blendInTime;
slot.LoopCount = loopCount;
return;
}
}
@@ -351,6 +352,7 @@ void AnimatedModel::PlaySlotAnimation(const StringView& slotName, Animation* ani
slot.Speed = speed;
slot.BlendInTime = blendInTime;
slot.BlendOutTime = blendOutTime;
slot.LoopCount = loopCount;
}
void AnimatedModel::StopSlotAnimation()

View File

@@ -313,7 +313,8 @@ public:
/// <param name="speed">The playback speed.</param>
/// <param name="blendInTime">The animation blending in time (in seconds). Cam be used to smooth the slot animation playback with the input pose when starting the animation.</param>
/// <param name="blendOutTime">The animation blending out time (in seconds). Cam be used to smooth the slot animation playback with the input pose when ending animation.</param>
API_FUNCTION() void PlaySlotAnimation(const StringView& slotName, Animation* anim, float speed = 1.0f, float blendInTime = 0.2f, float blendOutTime = 0.2f);
/// <param name="loopCount">The amount of loops to play the animation: 0 to play once, -1 to play infinite, 1 or higher to loop once or more.</param>
API_FUNCTION() void PlaySlotAnimation(const StringView& slotName, Animation* anim, float speed = 1.0f, float blendInTime = 0.2f, float blendOutTime = 0.2f, int32 loopCount = 0);
/// <summary>
/// Stops all the animations playback on the all slots in Anim Graph.