Adjusted SHAnimationEditor to fit new animation clip format
This commit is contained in:
parent
3b5d1ef6d5
commit
52913562e7
|
@ -60,6 +60,7 @@ namespace SHADE
|
||||||
/// Constructs an SHAnimation Clip from a specified SHAnimAsset.
|
/// Constructs an SHAnimation Clip from a specified SHAnimAsset.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="asset">Animation asset to load.</param>
|
/// <param name="asset">Animation asset to load.</param>
|
||||||
|
SHAnimationClip() = default;
|
||||||
explicit SHAnimationClip(const SHAnimAsset& asset);
|
explicit SHAnimationClip(const SHAnimAsset& asset);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -68,6 +69,7 @@ namespace SHADE
|
||||||
const std::vector<Channel>& GetChannels() const noexcept { return channels; }
|
const std::vector<Channel>& GetChannels() const noexcept { return channels; }
|
||||||
int GetTicksPerSecond() const noexcept { return ticksPerSecond; }
|
int GetTicksPerSecond() const noexcept { return ticksPerSecond; }
|
||||||
float GetTotalTime() const noexcept { return totalTime; }
|
float GetTotalTime() const noexcept { return totalTime; }
|
||||||
|
int GetTotalFrames() const noexcept { return totalFrames; }
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -76,6 +78,7 @@ namespace SHADE
|
||||||
std::vector<Channel> channels;
|
std::vector<Channel> channels;
|
||||||
int ticksPerSecond;
|
int ticksPerSecond;
|
||||||
float totalTime;
|
float totalTime;
|
||||||
|
int totalFrames;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
|
@ -32,22 +32,22 @@ namespace SHADE
|
||||||
SHAnimationClip::Channel
|
SHAnimationClip::Channel
|
||||||
{
|
{
|
||||||
.Name = "Child 1",
|
.Name = "Child 1",
|
||||||
.KeyFrames =
|
.PositionKeyFrames =
|
||||||
{
|
{
|
||||||
SHAnimationKeyFrame
|
SHAnimationKeyFrame<SHVec3>
|
||||||
{
|
{
|
||||||
.TimeStamp = 0.0f,
|
.FrameIndex = 0,
|
||||||
.Position = SHVec3 { 1.0f, 0.0f, 0.0f }
|
.Data = SHVec3 { 1.0f, 0.0f, 0.0f }
|
||||||
},
|
},
|
||||||
SHAnimationKeyFrame
|
SHAnimationKeyFrame<SHVec3>
|
||||||
{
|
{
|
||||||
.TimeStamp = 1.0f,
|
.FrameIndex = 30,
|
||||||
.Position = SHVec3 { 0.0f, 0.0f, 0.0f }
|
.Data = SHVec3 { 0.0f, 0.0f, 0.0f }
|
||||||
},
|
},
|
||||||
SHAnimationKeyFrame
|
SHAnimationKeyFrame<SHVec3>
|
||||||
{
|
{
|
||||||
.TimeStamp = 2.0f,
|
.FrameIndex = 60,
|
||||||
.Position = SHVec3 { 1.0f, 0.0f, 0.0f }
|
.Data = SHVec3 { 1.0f, 0.0f, 0.0f }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,17 +57,17 @@ namespace SHADE
|
||||||
SHAnimationClip::Channel
|
SHAnimationClip::Channel
|
||||||
{
|
{
|
||||||
.Name = "Child 2",
|
.Name = "Child 2",
|
||||||
.KeyFrames =
|
.PositionKeyFrames =
|
||||||
{
|
{
|
||||||
SHAnimationKeyFrame
|
SHAnimationKeyFrame<SHVec3>
|
||||||
{
|
{
|
||||||
.TimeStamp = 0.0f,
|
.FrameIndex = 0,
|
||||||
.Position = SHVec3 { 1.0f, 0.0f, 0.0f }
|
.Data = SHVec3 { 1.0f, 0.0f, 0.0f }
|
||||||
},
|
},
|
||||||
SHAnimationKeyFrame
|
SHAnimationKeyFrame<SHVec3>
|
||||||
{
|
{
|
||||||
.TimeStamp = 1.0f,
|
.FrameIndex = 30,
|
||||||
.Position = SHVec3 { 0.0f, 0.0f, 0.0f }
|
.Data = SHVec3 { 0.0f, 0.0f, 0.0f }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,27 +77,28 @@ namespace SHADE
|
||||||
SHAnimationClip::Channel
|
SHAnimationClip::Channel
|
||||||
{
|
{
|
||||||
.Name = "Child 3",
|
.Name = "Child 3",
|
||||||
.KeyFrames =
|
.PositionKeyFrames =
|
||||||
{
|
{
|
||||||
SHAnimationKeyFrame
|
SHAnimationKeyFrame<SHVec3>
|
||||||
{
|
{
|
||||||
.TimeStamp = 0.5f,
|
.FrameIndex = 15,
|
||||||
.Position = SHVec3 { 1.0f, 0.0f, 0.0f }
|
.Data = SHVec3 { 1.0f, 0.0f, 0.0f }
|
||||||
},
|
},
|
||||||
SHAnimationKeyFrame
|
SHAnimationKeyFrame<SHVec3>
|
||||||
{
|
{
|
||||||
.TimeStamp = 1.0f,
|
.FrameIndex = 30,
|
||||||
.Position = SHVec3 { 0.0f, 0.0f, 0.0f }
|
.Data = SHVec3 { 0.0f, 0.0f, 0.0f }
|
||||||
},
|
},
|
||||||
SHAnimationKeyFrame
|
SHAnimationKeyFrame<SHVec3>
|
||||||
{
|
{
|
||||||
.TimeStamp = 1.5f,
|
.FrameIndex = 45,
|
||||||
.Position = SHVec3 { 1.0f, 0.0f, 0.0f }
|
.Data = SHVec3 { 1.0f, 0.0f, 0.0f }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
clip.totalTime = 3.0f;
|
clip.totalFrames = 60;
|
||||||
|
clip.totalTime = static_cast<float>(clip.totalFrames) / clip.GetTicksPerSecond();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Compute dimensions for the clip
|
// Compute dimensions for the clip
|
||||||
const float COL_WIDTH = windowSize.x - CHANNELS_COL_WIDTH - TMP_TABLE_PADDING;
|
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<float>(clip.GetTotalFrames()); // Hardcoded distance based on the keyframe icon size
|
||||||
|
|
||||||
// Get Resources
|
// Get Resources
|
||||||
const auto WINDOW_POS = ImGui::GetWindowPos();
|
const auto WINDOW_POS = ImGui::GetWindowPos();
|
||||||
|
@ -138,24 +139,22 @@ namespace SHADE
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const auto TIMELINE_HEADER_START_POS = ImGui::GetCursorPos();
|
const auto TIMELINE_HEADER_START_POS = ImGui::GetCursorPos();
|
||||||
static constexpr float STEP = 1.0f;
|
static constexpr int STEP = 10;
|
||||||
for (float time = 0.0f; time <= clip.GetTotalTime(); time += STEP)
|
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
|
// Draw Text
|
||||||
ImGui::SetCursorPos(ImVec2(X_OFFSET, TIMELINE_HEADER_START_POS.y));
|
ImGui::SetCursorPos(ImVec2(X_OFFSET, TIMELINE_HEADER_START_POS.y));
|
||||||
std::string timeText = std::format("{:.{}f}", time, 1);
|
SHEditorUI::Text(std::to_string(frame));
|
||||||
SHEditorUI::Text(timeText);
|
|
||||||
|
|
||||||
// Draw line
|
// Draw line
|
||||||
ImVec2 startPoint { WINDOW_POS.x + X_OFFSET, WINDOW_POS.y + TIMELINE_HEADER_START_POS.y };
|
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)));
|
drawList->AddLine(startPoint, ImVec2(startPoint.x, startPoint.y + beginContentRegionAvailable.y), ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f)));
|
||||||
|
|
||||||
// Draw smaller lines
|
// Draw smaller lines
|
||||||
static constexpr float MINI_STEP = 0.1f;
|
for (int innerFrames = frame + 1; innerFrames < std::min(frame + STEP, clip.GetTotalFrames()); ++innerFrames)
|
||||||
for (float innerTime = time; innerTime < std::min(time + STEP, clip.GetTotalTime()); innerTime += MINI_STEP)
|
|
||||||
{
|
{
|
||||||
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)));
|
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
|
// Draw all the keyframes
|
||||||
const auto START_POS = ImGui::GetCursorPos();
|
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
|
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);
|
ImGui::SetCursorPos(START_POS);
|
||||||
|
|
Loading…
Reference in New Issue