diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h index 16e96f41..e43b1696 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -60,6 +60,7 @@ namespace SHADE /// Constructs an SHAnimation Clip from a specified SHAnimAsset. /// /// Animation asset to load. + SHAnimationClip() = default; explicit SHAnimationClip(const SHAnimAsset& asset); /*---------------------------------------------------------------------------------*/ @@ -68,6 +69,7 @@ namespace SHADE const std::vector& GetChannels() const noexcept { return channels; } int GetTicksPerSecond() const noexcept { return ticksPerSecond; } float GetTotalTime() const noexcept { return totalTime; } + int GetTotalFrames() const noexcept { return totalFrames; } //private: /*---------------------------------------------------------------------------------*/ @@ -76,6 +78,7 @@ namespace SHADE std::vector channels; int ticksPerSecond; float totalTime; + int totalFrames; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.cpp index 944b1b85..161223a6 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.cpp @@ -32,22 +32,22 @@ namespace SHADE SHAnimationClip::Channel { .Name = "Child 1", - .KeyFrames = + .PositionKeyFrames = { - SHAnimationKeyFrame + SHAnimationKeyFrame { - .TimeStamp = 0.0f, - .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + .FrameIndex = 0, + .Data = SHVec3 { 1.0f, 0.0f, 0.0f } }, - SHAnimationKeyFrame + SHAnimationKeyFrame { - .TimeStamp = 1.0f, - .Position = SHVec3 { 0.0f, 0.0f, 0.0f } + .FrameIndex = 30, + .Data = SHVec3 { 0.0f, 0.0f, 0.0f } }, - SHAnimationKeyFrame + SHAnimationKeyFrame { - .TimeStamp = 2.0f, - .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + .FrameIndex = 60, + .Data = SHVec3 { 1.0f, 0.0f, 0.0f } } } } @@ -57,17 +57,17 @@ namespace SHADE SHAnimationClip::Channel { .Name = "Child 2", - .KeyFrames = + .PositionKeyFrames = { - SHAnimationKeyFrame + SHAnimationKeyFrame { - .TimeStamp = 0.0f, - .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + .FrameIndex = 0, + .Data = SHVec3 { 1.0f, 0.0f, 0.0f } }, - SHAnimationKeyFrame + SHAnimationKeyFrame { - .TimeStamp = 1.0f, - .Position = SHVec3 { 0.0f, 0.0f, 0.0f } + .FrameIndex = 30, + .Data = SHVec3 { 0.0f, 0.0f, 0.0f } } } } @@ -77,27 +77,28 @@ namespace SHADE SHAnimationClip::Channel { .Name = "Child 3", - .KeyFrames = + .PositionKeyFrames = { - SHAnimationKeyFrame + SHAnimationKeyFrame { - .TimeStamp = 0.5f, - .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + .FrameIndex = 15, + .Data = SHVec3 { 1.0f, 0.0f, 0.0f } }, - SHAnimationKeyFrame + SHAnimationKeyFrame { - .TimeStamp = 1.0f, - .Position = SHVec3 { 0.0f, 0.0f, 0.0f } + .FrameIndex = 30, + .Data = SHVec3 { 0.0f, 0.0f, 0.0f } }, - SHAnimationKeyFrame + SHAnimationKeyFrame { - .TimeStamp = 1.5f, - .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + .FrameIndex = 45, + .Data = SHVec3 { 1.0f, 0.0f, 0.0f } } } } ); - clip.totalTime = 3.0f; + clip.totalFrames = 60; + clip.totalTime = static_cast(clip.totalFrames) / clip.GetTicksPerSecond(); } @@ -128,7 +129,7 @@ namespace SHADE // Compute dimensions for the clip const float COL_WIDTH = windowSize.x - CHANNELS_COL_WIDTH - TMP_TABLE_PADDING; - const float DIST_PER_SECOND = 202.666672f;// COL_WIDTH / clip.GetTotalTime(); // Hardcoded distance based on the keyframe icon size + const float DIST_PER_FRAME = 18.0f;//COL_WIDTH / static_cast(clip.GetTotalFrames()); // Hardcoded distance based on the keyframe icon size // Get Resources const auto WINDOW_POS = ImGui::GetWindowPos(); @@ -138,24 +139,22 @@ namespace SHADE ImGui::TableHeadersRow(); ImGui::SameLine(); const auto TIMELINE_HEADER_START_POS = ImGui::GetCursorPos(); - static constexpr float STEP = 1.0f; - for (float time = 0.0f; time <= clip.GetTotalTime(); time += STEP) + static constexpr int STEP = 10; + for (int frame = 0; frame <= clip.GetTotalFrames(); frame += STEP) { - const float X_OFFSET = TIMELINE_HEADER_START_POS.x + time * DIST_PER_SECOND; + const float X_OFFSET = TIMELINE_HEADER_START_POS.x + frame * DIST_PER_FRAME; // Draw Text ImGui::SetCursorPos(ImVec2(X_OFFSET, TIMELINE_HEADER_START_POS.y)); - std::string timeText = std::format("{:.{}f}", time, 1); - SHEditorUI::Text(timeText); + SHEditorUI::Text(std::to_string(frame)); // Draw line ImVec2 startPoint { WINDOW_POS.x + X_OFFSET, WINDOW_POS.y + TIMELINE_HEADER_START_POS.y }; drawList->AddLine(startPoint, ImVec2(startPoint.x, startPoint.y + beginContentRegionAvailable.y), ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f))); // Draw smaller lines - static constexpr float MINI_STEP = 0.1f; - for (float innerTime = time; innerTime < std::min(time + STEP, clip.GetTotalTime()); innerTime += MINI_STEP) + for (int innerFrames = frame + 1; innerFrames < std::min(frame + STEP, clip.GetTotalFrames()); ++innerFrames) { - ImVec2 innerStartPoint{ WINDOW_POS.x + TIMELINE_HEADER_START_POS.x + innerTime * DIST_PER_SECOND, WINDOW_POS.y + TIMELINE_HEADER_START_POS.y }; + ImVec2 innerStartPoint{ WINDOW_POS.x + TIMELINE_HEADER_START_POS.x + innerFrames * DIST_PER_FRAME, WINDOW_POS.y + TIMELINE_HEADER_START_POS.y }; drawList->AddLine(innerStartPoint, ImVec2(innerStartPoint.x, innerStartPoint.y + beginContentRegionAvailable.y), ImGui::GetColorU32(ImVec4(0.2f, 0.2f, 0.2f, 1.0f))); } } @@ -171,9 +170,9 @@ namespace SHADE // Draw all the keyframes const auto START_POS = ImGui::GetCursorPos(); - for (const auto& keyframe : channel.KeyFrames) + for (const auto& keyframe : channel.PositionKeyFrames) { - ImGui::SetCursorPos(ImVec2(START_POS.x + keyframe.TimeStamp * DIST_PER_SECOND, START_POS.y)); + ImGui::SetCursorPos(ImVec2(START_POS.x + keyframe.FrameIndex * DIST_PER_FRAME, START_POS.y)); SHEditorUI::OffsetText(ICON_MD_RADIO_BUTTON_CHECKED, 6.0f); // Hardcoded offset to align icon since ImGui can't calculate icon with properly } ImGui::SetCursorPos(START_POS);