diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h index d8415942..1c2e9ede 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -56,6 +56,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Constructors */ /*---------------------------------------------------------------------------------*/ + SHAnimationClip() = default; explicit SHAnimationClip(const SHAnimAsset& asset); /*---------------------------------------------------------------------------------*/ @@ -64,7 +65,7 @@ namespace SHADE const std::vector& GetChannels() const noexcept { return channels; } float GetTotalTime() const noexcept { return totalTime; } - private: + //private: /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.cpp new file mode 100644 index 00000000..0c6673fa --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.cpp @@ -0,0 +1,195 @@ +/************************************************************************************//*! +\file SHAnimationClip.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 20, 2022 +\brief Contains the function definitions of the SHAnimationClip class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Pre-compiled Header +#include "SHpch.h" +// Primary Header +#include "SHAnimationEditor.h" +// External Dependencies +#include +#include "Editor/IconsMaterialDesign.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------------*/ + SHAnimationEditor::SHAnimationEditor() + : SHEditorWindow(ICON_MD_ANIMATION" Animation Editor", ImGuiWindowFlags_MenuBar) + { + // Construct a simple test clip + clip.channels.emplace_back + ( + SHAnimationClip::Channel + { + .Name = "Child 1", + .KeyFrames = + { + SHAnimationKeyFrame + { + .TimeStamp = 0.0f, + .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + }, + SHAnimationKeyFrame + { + .TimeStamp = 1.0f, + .Position = SHVec3 { 0.0f, 0.0f, 0.0f } + }, + SHAnimationKeyFrame + { + .TimeStamp = 2.0f, + .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + } + } + } + ); + clip.channels.emplace_back + ( + SHAnimationClip::Channel + { + .Name = "Child 2", + .KeyFrames = + { + SHAnimationKeyFrame + { + .TimeStamp = 0.0f, + .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + }, + SHAnimationKeyFrame + { + .TimeStamp = 1.0f, + .Position = SHVec3 { 0.0f, 0.0f, 0.0f } + } + } + } + ); + clip.channels.emplace_back + ( + SHAnimationClip::Channel + { + .Name = "Child 3", + .KeyFrames = + { + SHAnimationKeyFrame + { + .TimeStamp = 0.5f, + .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + }, + SHAnimationKeyFrame + { + .TimeStamp = 1.0f, + .Position = SHVec3 { 0.0f, 0.0f, 0.0f } + }, + SHAnimationKeyFrame + { + .TimeStamp = 1.5f, + .Position = SHVec3 { 1.0f, 0.0f, 0.0f } + } + } + } + ); + clip.totalTime = 3.0f; + } + + + /*-----------------------------------------------------------------------------------*/ + /* Editor Lifecycle */ + /*-----------------------------------------------------------------------------------*/ + void SHAnimationEditor::Init() + { + SHEditorWindow::Init(); + } + void SHAnimationEditor::Update() + { + SHEditorWindow::Update(); + + // Constants + static constexpr float CHANNELS_COL_WIDTH = 150.0f; + static constexpr float TMP_TABLE_PADDING = 50.0f; + + // Render the window + if (Begin()) + { + // Construct 2-column table of the channels on the left + if (ImGui::BeginTable("animWindowTable", 2, ImGuiTableFlags_None)) + { + // Set up Columns + ImGui::TableSetupColumn("Channels", ImGuiTableColumnFlags_WidthFixed, CHANNELS_COL_WIDTH); + ImGui::TableSetupColumn(""); + + // Compute dimensions for the clip + const float COL_WIDTH = windowSize.x - CHANNELS_COL_WIDTH - TMP_TABLE_PADDING; + const float DIST_PER_SECOND = COL_WIDTH / clip.GetTotalTime(); + + // Get Resources + const auto WINDOW_POS = ImGui::GetWindowPos(); + auto drawList = ImGui::GetForegroundDrawList(); + + // Render Header + 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) + { + const float X_OFFSET = TIMELINE_HEADER_START_POS.x + time * DIST_PER_SECOND; + // Draw Text + ImGui::SetCursorPos(ImVec2(X_OFFSET, TIMELINE_HEADER_START_POS.y)); + std::string timeText = std::format("{:.{}f}", time, 1); + ImGui::Text(timeText.c_str()); + + // 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 + windowSize.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) + { + ImVec2 innerStartPoint { WINDOW_POS.x + TIMELINE_HEADER_START_POS.x + innerTime * DIST_PER_SECOND, WINDOW_POS.y + TIMELINE_HEADER_START_POS.y }; + drawList->AddLine(innerStartPoint, ImVec2(innerStartPoint.x, innerStartPoint.y + windowSize.y), ImGui::GetColorU32(ImVec4(0.2f, 0.2f, 0.2f, 1.0f))); + } + } + ImGui::SetCursorPos(TIMELINE_HEADER_START_POS); + + // Render all channels + for (const auto& channel : clip.channels) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text(channel.Name.c_str()); + ImGui::TableNextColumn(); + + const auto START_POS = ImGui::GetCursorPos(); + for (const auto& keyframe : channel.KeyFrames) + { + ImGui::SetCursorPos(ImVec2(START_POS.x + keyframe.TimeStamp * DIST_PER_SECOND, START_POS.y)); + ImGui::Text(ICON_MD_RADIO_BUTTON_CHECKED); + } + ImGui::SetCursorPos(START_POS); + } + + ImGui::EndTable(); + } + + } + ImGui::End(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------------*/ + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.h b/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.h new file mode 100644 index 00000000..ca2026da --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/AnimationEditor/SHAnimationEditor.h @@ -0,0 +1,44 @@ +/************************************************************************************//*! +\file SHAnimationEditor.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Jan 8, 2023 +\brief Contains the definition of the SHAnimationEditor class and related types. + +Copyright (C) 2023 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// Project Includes +#include "Editor/EditorWindow/SHEditorWindow.h" +#include "Animation/SHAnimationClip.h" + +namespace SHADE +{ + /// + /// ImGui window that contains the SHAnimationEditor + /// + class SHAnimationEditor final : public SHEditorWindow + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*---------------------------------------------------------------------------------*/ + SHAnimationEditor(); + virtual ~SHAnimationEditor() = default; + + /*---------------------------------------------------------------------------------*/ + /* Editor Lifecycle */ + /*---------------------------------------------------------------------------------*/ + void Init() override; + void Update() override; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + SHAnimationClip clip; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 2b8ddbb5..81abb32e 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -31,6 +31,7 @@ //#==============================================================# #include "EditorWindow/SHEditorWindowManager.h" #include "EditorWindow/SHEditorWindowIncludes.h" +#include "EditorWindow/AnimationEditor/SHAnimationEditor.h" //#==============================================================# //|| Library Includes || @@ -104,6 +105,7 @@ namespace SHADE SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow();