Added extra field in animation clip container for time multiplier #427
|
@ -20,12 +20,13 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHAnimationClip::SHAnimationClip(Handle<SHRawAnimation> rawAnimHandle, int firstFrame, int lastFrame)
|
||||
SHAnimationClip::SHAnimationClip(Handle<SHRawAnimation> rawAnimHandle, int firstFrame, int lastFrame, float playbackMultiplier)
|
||||
: rawAnim { rawAnimHandle }
|
||||
, startFrameIndex { firstFrame }
|
||||
, endFrameIndex { lastFrame }
|
||||
, duration { 0.0f }
|
||||
, startTimeStamp { 0.0f }
|
||||
, playbackSpeedMultiplier { playbackMultiplier }
|
||||
{
|
||||
if (!rawAnim)
|
||||
return;
|
||||
|
|
|
@ -41,16 +41,29 @@ namespace SHADE
|
|||
/// <param name="rawAnimHandle">Handle to the raw animation data.</param>
|
||||
/// <param name="firstFrame">First frame to be played.</param>
|
||||
/// <param name="lastFrame">Last frame to be played.</param>
|
||||
SHAnimationClip(Handle<SHRawAnimation> rawAnimHandle, int firstFrame, int lastFrame);
|
||||
/// <param name="playbackMultiplier">Multiplier for the playback speed.</param>
|
||||
SHAnimationClip(Handle<SHRawAnimation> rawAnimHandle, int firstFrame, int lastFrame, float playbackMultiplier = 1.0f);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
inline Handle<SHRawAnimation> GetRawAnimation() const noexcept { return rawAnim; }
|
||||
inline int GetStartFrameIndex() const noexcept { return startFrameIndex; }
|
||||
inline int GetEndFrameIndex() const noexcept { return endFrameIndex; }
|
||||
inline float GetTotalDuration() const noexcept { return duration; }
|
||||
inline int GetEndFrameIndex() const noexcept { return endFrameIndex; }\
|
||||
inline float GetStartTimeStamp() const noexcept { return startTimeStamp; }
|
||||
inline float GetPlaybackSpeedMultiplier() const noexcept { return playbackSpeedMultiplier; }
|
||||
/// <summary>
|
||||
/// Retrieves the duration of the animation as if the playback speed multiplier is
|
||||
/// in it's default value of 1.0f.
|
||||
/// </summary>
|
||||
/// <returns>Duration of the animation in seconds.</returns>
|
||||
inline float GetTotalDuration() const noexcept { return duration; }
|
||||
/// <summary>
|
||||
/// Retrieves the duration of the animation with the playback speed multiplier
|
||||
/// taken into account.
|
||||
/// </summary>
|
||||
/// <returns>True duration of the animation in seconds.</returns>
|
||||
inline float GetTrueDuration() const noexcept { return duration / playbackSpeedMultiplier; }
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -61,5 +74,6 @@ namespace SHADE
|
|||
int endFrameIndex; // Last Frame (inclusive)
|
||||
float duration; // Total playback time
|
||||
float startTimeStamp; // Starting time stamp of the raw anim
|
||||
float playbackSpeedMultiplier; // Multiplier applied to the playback of an animation clip
|
||||
};
|
||||
}
|
|
@ -62,18 +62,21 @@ namespace SHADE
|
|||
if (!instData.CurrentNode)
|
||||
return;
|
||||
|
||||
// Get the clip
|
||||
Handle<SHAnimationClip> clip = instData.CurrentNode->Clip;
|
||||
|
||||
// Update the current playback
|
||||
instData.ClipPlaybackTime += dt;
|
||||
instData.ClipPlaybackTime += dt * clip->GetPlaybackSpeedMultiplier();
|
||||
|
||||
// Check if we finished playing
|
||||
const float CLIP_CURR_PLAYED_TIME = instData.ClipPlaybackTime - instData.CurrentNode->Clip->GetStartTimeStamp();
|
||||
if (CLIP_CURR_PLAYED_TIME > instData.CurrentNode->Clip->GetTotalDuration())
|
||||
const float CLIP_CURR_PLAYED_TIME = instData.ClipPlaybackTime - clip->GetStartTimeStamp();
|
||||
if (CLIP_CURR_PLAYED_TIME > clip->GetTotalDuration())
|
||||
{
|
||||
// Clamp
|
||||
instData.ClipPlaybackTime = instData.CurrentNode->Clip->GetStartTimeStamp() + instData.CurrentNode->Clip->GetTotalDuration();
|
||||
instData.ClipPlaybackTime = clip->GetStartTimeStamp() + clip->GetTotalDuration();
|
||||
|
||||
// Go to next state
|
||||
Handle<SHAnimationClip> originalClip = instData.CurrentNode->Clip;
|
||||
Handle<SHAnimationClip> originalClip = clip;
|
||||
bool stateChanged = false;
|
||||
for (const auto& transition : instData.CurrentNode->Transitions)
|
||||
{
|
||||
|
|
|
@ -254,7 +254,7 @@ namespace SHADE
|
|||
}
|
||||
void SHAnimatorComponent::updateManualClipState(float dt)
|
||||
{
|
||||
currPlaybackTime += dt;
|
||||
currPlaybackTime += dt * currClip->GetPlaybackSpeedMultiplier();
|
||||
const float CLIP_CURR_PLAYED_TIME = currPlaybackTime - currClip->GetStartTimeStamp();
|
||||
if (CLIP_CURR_PLAYED_TIME > currClip->GetTotalDuration())
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace SHADE
|
|||
uint32_t firstIndex;
|
||||
uint32_t lastIndex;
|
||||
AssetID animRawDataAssetId; // Not serialised, only populated during runtime from parent asset
|
||||
float playbackMultiplier = 1.0f;
|
||||
};
|
||||
|
||||
struct SH_API SHAnimClipContainerAsset final : SHAssetData
|
||||
|
|
|
@ -54,6 +54,7 @@ namespace SHADE
|
|||
newAssetName.clear();
|
||||
firstIndex = 0;
|
||||
lastIndex = rawAnimation->GetTotalFrames();
|
||||
playbackMultiplier = 1.0f;
|
||||
}
|
||||
|
||||
// Assign callback
|
||||
|
@ -72,6 +73,9 @@ namespace SHADE
|
|||
SHEditorUI::PushID(1);
|
||||
SHEditorUI::InputUnsignedInt("Last Frame Index", lastIndex);
|
||||
SHEditorUI::PopID();
|
||||
SHEditorUI::PushID(2);
|
||||
SHEditorUI::InputFloat("Playback Multiplier", playbackMultiplier);
|
||||
SHEditorUI::PopID();
|
||||
|
||||
// Invalid values
|
||||
const bool INVALID_CONFIG = newAssetName.empty() || firstIndex > lastIndex;
|
||||
|
@ -88,6 +92,7 @@ namespace SHADE
|
|||
animClip->firstIndex = firstIndex;
|
||||
animClip->lastIndex = lastIndex;
|
||||
animClip->animRawDataAssetId = SHResourceManager::GetAssetID<SHRawAnimation>(rawAnimation).value_or(0);
|
||||
animClip->playbackMultiplier = playbackMultiplier;
|
||||
SHAssetManager::SaveAsset(containerAsset->id);
|
||||
|
||||
// Close
|
||||
|
@ -168,6 +173,7 @@ namespace SHADE
|
|||
|
||||
int firstIndex = animClip->GetStartFrameIndex();
|
||||
int endIndex = animClip->GetEndFrameIndex();
|
||||
float playbackMp = animClip->GetPlaybackSpeedMultiplier();
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text(animClipName.has_value() ? animClipName.value().c_str() : "");
|
||||
|
@ -183,12 +189,18 @@ namespace SHADE
|
|||
[&]() { return endIndex; },
|
||||
[&](int i) { endIndex = i; }
|
||||
);
|
||||
changed |= SHEditorWidgets::DragFloat
|
||||
(
|
||||
"Playback Multiplier",
|
||||
[&]() { return playbackMp; },
|
||||
[&](float f) { playbackMp = f; }
|
||||
);
|
||||
|
||||
// If there's a change we need to commit changes
|
||||
if (changed && firstIndex < endIndex)
|
||||
{
|
||||
// Update runtime asset
|
||||
*animClip = SHAnimationClip(currRawAnim, firstIndex, endIndex);
|
||||
*animClip = SHAnimationClip(currRawAnim, firstIndex, endIndex, playbackMp);
|
||||
|
||||
// Update serialized asset
|
||||
auto assetId = SHResourceManager::GetAssetID(animClip);
|
||||
|
@ -197,6 +209,7 @@ namespace SHADE
|
|||
auto const animAsset = SHAssetManager::GetData<SHAnimClipAsset>(assetId.value());
|
||||
animAsset->firstIndex = firstIndex;
|
||||
animAsset->lastIndex = endIndex;
|
||||
animAsset->playbackMultiplier = playbackMp;
|
||||
SHAssetManager::SaveAsset(containerAsset->id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace SHADE
|
|||
std::string newAssetName;
|
||||
uint32_t firstIndex = 0;
|
||||
uint32_t lastIndex = 0;
|
||||
float playbackMultiplier = 1.0f;
|
||||
Handle<SHRawAnimation> rawAnimation;
|
||||
SHAsset* containerAsset{nullptr};
|
||||
SHAnimClipContainerAsset* container{nullptr};
|
||||
|
|
|
@ -372,7 +372,8 @@ namespace SHADE
|
|||
(
|
||||
LoadOrGet<SHRawAnimation>(assetData.animRawDataAssetId),
|
||||
assetData.firstIndex,
|
||||
assetData.lastIndex
|
||||
assetData.lastIndex,
|
||||
assetData.playbackMultiplier
|
||||
);
|
||||
}
|
||||
else if constexpr (std::is_same_v<ResourceType, SHAnimationController>)
|
||||
|
|
Loading…
Reference in New Issue