Implemented Animation Clip asset and animation controller #410

Merged
XiaoQiDigipen merged 66 commits from SP3-22-AnimationController into main 2023-03-09 16:19:40 +08:00
4 changed files with 96 additions and 11 deletions
Showing only changes of commit beeeae99ca - Show all commits

BIN
Assets/Animation Clips/Main Normal file

Binary file not shown.

View File

@ -24,6 +24,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Resource/SHResourceManager.h" #include "Resource/SHResourceManager.h"
#include "Editor/EditorWindow/SHEditorWindowManager.h" #include "Editor/EditorWindow/SHEditorWindowManager.h"
#include "Editor/SHEditorUI.h" #include "Editor/SHEditorUI.h"
#include "Assets/SHAssetManager.h"
namespace SHADE namespace SHADE
{ {
@ -36,7 +37,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* SHAnimClipCreatePrompt - Lifecycle Functions */ /* SHAnimClipCreatePrompt - Lifecycle Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SHAnimClipCreatePrompt::Init(Handle<SHRawAnimation> rawAnim) void SHAnimClipCreatePrompt::Init(Handle<SHRawAnimation> rawAnim, std::function<void(AssetID)> onClose)
{ {
rawAnimation = rawAnim; rawAnimation = rawAnim;
@ -47,6 +48,9 @@ namespace SHADE
firstIndex = 0; firstIndex = 0;
lastIndex = rawAnimation->GetTotalFrames(); lastIndex = rawAnimation->GetTotalFrames();
} }
// Assign callback
this->onClose = onClose;
} }
void SHAnimClipCreatePrompt::Draw() void SHAnimClipCreatePrompt::Draw()
@ -71,10 +75,17 @@ namespace SHADE
if (ImGui::Button("Save")) if (ImGui::Button("Save"))
{ {
// Generate new asset // Generate new asset
const AssetID NEW_ASSET_ID = SHAssetManager::CreateNewAsset(AssetType::ANIM_CLIP, newAssetName);
auto animClip = SHAssetManager::GetData<SHAnimClipAsset>(NEW_ASSET_ID);
animClip->animRawDataAssetId = SHResourceManager::GetAssetID<SHRawAnimation>(rawAnimation).value_or(INVALID_ASSET_ID);
animClip->firstIndex = firstIndex;
animClip->lastIndex = lastIndex;
SHAssetManager::SaveAsset(NEW_ASSET_ID);
// Close // Close
isOpen = false; isOpen = false;
if (onClose)
onClose(NEW_ASSET_ID);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
} }
@ -84,6 +95,8 @@ namespace SHADE
{ {
// Close // Close
isOpen = false; isOpen = false;
if (onClose)
onClose(INVALID_ASSET_ID);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
ImGui::EndPopup(); ImGui::EndPopup();
@ -114,27 +127,63 @@ namespace SHADE
// Draw // Draw
if (Begin()) if (Begin())
{ {
// Ignore if no asset // Ignore if no asset
if (currRawAnim) if (currRawAnim)
{ {
drawMenuBar(); drawMenuBar();
// Button to add a new clip // Button to add a new clip
if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data())) if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data()))
{ {
auto prompt = SHEditorWindowManager::GetPopupWindow<SHAnimClipCreatePrompt>(); auto prompt = SHEditorWindowManager::GetPopupWindow<SHAnimClipCreatePrompt>();
prompt->Init(currRawAnim); prompt->Init(currRawAnim, [this](AssetID createdAssetId)
{
if (createdAssetId != INVALID_ASSET_ID)
{
childAnimClips.emplace_back(SHResourceManager::LoadOrGet<SHAnimationClip>(createdAssetId));
}
});
prompt->isOpen = true; prompt->isOpen = true;
} }
// Render all clips // Render all clips
for (auto animClip : childAnimClips)
{
bool changed = false;
std::optional<std::string> animClipName = SHResourceManager::GetAssetName<SHAnimationClip>(animClip);
int firstIndex = animClip->GetStartFrameIndex();
int endIndex = animClip->GetEndFrameIndex();
ImGui::Text(animClipName.has_value() ? animClipName.value().c_str() : "");
ImGui::SameLine();
SHEditorUI::PushID(0);
changed |= SHEditorUI::InputInt("", firstIndex);
SHEditorUI::PopID();
ImGui::SameLine();
ImGui::Text(" - ");
ImGui::SameLine();
SHEditorUI::PushID(1);
changed |= SHEditorUI::InputInt("", endIndex);
SHEditorUI::PopID();
// If there's a change we need to commit changes
if (changed)
{
auto assetId = SHResourceManager::GetAssetID(animClip);
if (assetId.has_value())
{
auto animAsset = SHAssetManager::GetData<SHAnimClipAsset>(assetId.value());
animAsset->firstIndex = firstIndex;
animAsset->lastIndex = endIndex;
SHAssetManager::SaveAsset(assetId.value());
}
}
} }
} }
ImGui::End(); ImGui::End();
} }
}
void SHRawAnimInspector::Exit() void SHRawAnimInspector::Exit()
{ {
@ -147,6 +196,12 @@ namespace SHADE
void SHRawAnimInspector::Open(AssetID assetId) void SHRawAnimInspector::Open(AssetID assetId)
{ {
currRawAnim = SHResourceManager::LoadOrGet<SHRawAnimation>(assetId); currRawAnim = SHResourceManager::LoadOrGet<SHRawAnimation>(assetId);
// Load anim clips
if (currRawAnim)
{
childAnimClips = getChildAnimClips(assetId);
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -167,4 +222,21 @@ namespace SHADE
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
} }
std::vector<Handle<SHAnimationClip>> SHRawAnimInspector::getChildAnimClips(AssetID rawAnimId)
{
std::vector<Handle<SHAnimationClip>> animClips;
const auto ALL_ANIM_CLIPS = SHAssetManager::GetAllRecordOfType(AssetType::ANIM_CLIP);
for (auto asset : ALL_ANIM_CLIPS)
{
const SHAnimClipAsset* ANIM_CLIP = SHAssetManager::GetData<SHAnimClipAsset>(asset.id);
if (ANIM_CLIP->animRawDataAssetId == rawAnimId)
{
animClips.emplace_back(SHResourceManager::LoadOrGet<SHAnimationClip>(asset.id));
}
}
return animClips;
}
} }

View File

@ -20,6 +20,16 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
struct SHAnimClipAsset;
class SHRawAnimation;
class SHAnimationClip;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Prompt for creating an animation clip. Init() must be called to pass in the correct /// Prompt for creating an animation clip. Init() must be called to pass in the correct
/// SHRawAnimation that the created clip will use. /// SHRawAnimation that the created clip will use.
@ -35,7 +45,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */ /* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Init(Handle<SHRawAnimation> rawAnim); void Init(Handle<SHRawAnimation> rawAnim, std::function<void(AssetID)> onClose = nullptr);
void Draw() override; void Draw() override;
private: private:
@ -46,6 +56,7 @@ namespace SHADE
int firstIndex = 0; int firstIndex = 0;
int lastIndex = 0; int lastIndex = 0;
Handle<SHRawAnimation> rawAnimation; Handle<SHRawAnimation> rawAnimation;
std::function<void(AssetID)> onClose;
}; };
/// <summary> /// <summary>
@ -77,10 +88,12 @@ namespace SHADE
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHRawAnimation> currRawAnim; Handle<SHRawAnimation> currRawAnim;
std::vector<Handle<SHAnimationClip>> childAnimClips;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void drawMenuBar(); void drawMenuBar();
std::vector<Handle<SHAnimationClip>> getChildAnimClips(AssetID rawAnimId);
}; };
} }

View File

@ -368,9 +368,9 @@ namespace SHADE
loadedAssetData.emplace_back(assetId); loadedAssetData.emplace_back(assetId);
return resourceHub.Create<ResourceType> return resourceHub.Create<ResourceType>
( (
LoadOrGet<SHRawAnimation>(assetData->animRawDataAssetId), LoadOrGet<SHRawAnimation>(assetData.animRawDataAssetId),
assetData->firstIndex, assetData.firstIndex,
assetData->lastIndex assetData.lastIndex
); );
} }
else if constexpr (std::is_same_v<ResourceType, SHAnimationController>) else if constexpr (std::is_same_v<ResourceType, SHAnimationController>)