From 2c8eca4125ce2332fbe406dd75c39fd262b5148b Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 9 Mar 2023 01:51:54 +0800 Subject: [PATCH] Added facility to create new animation clip container asset. Changed raw anim editor to open when double clicking anim container asset/after creating new anim container asset Changed new clip fields from slider to unsigned int input --- .../racoonAnims.shanimcontainer | Bin 0 -> 215 bytes .../racoonAnims.shanimcontainer.shmeta | 37 +++++++++ SHADE_Engine/src/Animation/SHRawAnimation.cpp | 2 + .../Asset Types/SHAnimClipContainerAsset.h | 2 +- SHADE_Engine/src/Assets/SHAssetMacros.h | 2 +- SHADE_Engine/src/Assets/SHAssetManager.cpp | 45 +++++++---- .../AssetBrowser/SHAssetBrowser.cpp | 70 +++++++++++++++--- .../SHRawAnimInspector.cpp | 53 ++++++------- .../SHRawAnimInspector.h | 19 ++++- 9 files changed, 169 insertions(+), 61 deletions(-) create mode 100644 Assets/Animation Clips/racoonAnims.shanimcontainer create mode 100644 Assets/Animation Clips/racoonAnims.shanimcontainer.shmeta diff --git a/Assets/Animation Clips/racoonAnims.shanimcontainer b/Assets/Animation Clips/racoonAnims.shanimcontainer new file mode 100644 index 0000000000000000000000000000000000000000..499ff4227890e1a3318fa2195f1ab20264722c5b GIT binary patch literal 215 zcmaExu$YCLfq{V)h(iMMi&KF#11Au(0I_FEPAV6WRsv#XAPy?c(*RNqK+Fcj0h!6! zr3G$4Ru~Y26gnps6;;NAv_%1VML-NP3L*;BTmj@v0AjFZ8AbW!(}0|1KnyZ1xS%LA zuVfXFwF`(rrg@d-7Q_daBo>wI1M-dnF~~Hqs84==!7(7`91wHB1YPq|&I8%kfEWPp CuPSu_ literal 0 HcmV?d00001 diff --git a/Assets/Animation Clips/racoonAnims.shanimcontainer.shmeta b/Assets/Animation Clips/racoonAnims.shanimcontainer.shmeta new file mode 100644 index 00000000..928c9fc5 --- /dev/null +++ b/Assets/Animation Clips/racoonAnims.shanimcontainer.shmeta @@ -0,0 +1,37 @@ +Name: racoonAnims +ID: 201804216 +Type: 12 +Sub Assets: +Name: TPose +ID: 231493784 +Type: 13 +Name: Idle +ID: 227450439 +Type: 13 +Name: Run +ID: 229125027 +Type: 13 +Name: Pickup +ID: 219605278 +Type: 13 +Name: Carry_Idle +ID: 231128260 +Type: 13 +Name: Carry_Run +ID: 227671720 +Type: 13 +Name: Throw +ID: 223399345 +Type: 13 +Name: Sprint +ID: 228149757 +Type: 13 +Name: Jump_Start +ID: 223009573 +Type: 13 +Name: Jump_Loop +ID: 230974023 +Type: 13 +Name: Jump_End +ID: 228134756 +Type: 13 diff --git a/SHADE_Engine/src/Animation/SHRawAnimation.cpp b/SHADE_Engine/src/Animation/SHRawAnimation.cpp index 2f30a91e..6f77f958 100644 --- a/SHADE_Engine/src/Animation/SHRawAnimation.cpp +++ b/SHADE_Engine/src/Animation/SHRawAnimation.cpp @@ -60,6 +60,8 @@ namespace SHADE // Compute fps ticksPerSecond = static_cast(maxFrames / totalTime); } + + totalFrames = maxFrames; } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h index bac68579..3905ddd8 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h @@ -30,6 +30,6 @@ namespace SHADE struct SH_API SHAnimClipContainerAsset final : SHAssetData { AssetID animRawDataAssetId; - std::vector clips; + std::vector clips{}; }; } diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 4784560b..f12cc56f 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -82,7 +82,7 @@ constexpr std::string_view FONT_COMPILER_EXE{ "FontCompiler.exe" }; constexpr std::string_view SCENE_FOLDER{ "/Scenes/" }; constexpr std::string_view PREFAB_FOLDER{ "/Prefabs/" }; constexpr std::string_view MATERIAL_FOLDER{ "/Materials/" }; -constexpr std::string_view ANIM_CLIP_FOLDER{ "/Animations/" }; +constexpr std::string_view ANIM_CLIP_FOLDER{ "/Animation Clips/" }; constexpr std::string_view ANIM_CONTROLLER_FOLDER{ "/Animation Controllers/" }; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 660fe6d9..fcd9c5b1 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -254,13 +254,11 @@ namespace SHADE newPath += ANIM_CONTAINER_EXTENSION; { - auto animClip = new SHAnimClipAsset(); - animClip->name = name; + auto animClip = new SHAnimClipContainerAsset(); data = animClip; } break; - default: SHLOG_ERROR("[Asset Manager] Asset type of {} not an internal parent asset type, cannot be created", name); return 0; @@ -338,7 +336,7 @@ namespace SHADE asset.type == AssetType::SCENE || asset.type == AssetType::PREFAB || asset.type == AssetType::MATERIAL || - asset.type == AssetType::ANIM_CLIP + asset.type == AssetType::ANIM_CONTAINER ) { if (assetData.contains(id)) @@ -531,9 +529,9 @@ namespace SHADE //Reload data auto result = GetAsset(target); - if (result.has_value()) + if (result) { - auto const& asset{ result.value() }; + auto const& asset{ *result }; auto newData = loaders[static_cast(asset.type)]->Load(asset.path); delete assetData[target]; assetData[target] = newData; @@ -656,16 +654,37 @@ namespace SHADE else { assetData.emplace(parent.id, parentData); - if (parent.type == AssetType::MODEL) + switch(parent.type) { - auto parentModel = reinterpret_cast(parentData); - for (auto i {0}; i < parent.subAssets.size(); ++i) + case AssetType::MODEL: { - assetData.emplace( - parent.subAssets[i]->id, - parentModel->meshes[i] - ); + const auto parentModel = reinterpret_cast(parentData); + for (auto i {0}; i < parent.subAssets.size(); ++i) + { + assetData.emplace( + parent.subAssets[i]->id, + parentModel->meshes[i] + ); + } } + break; + + case AssetType::ANIM_CONTAINER: + { + const auto parentContainer = reinterpret_cast(parentData); + for (auto i {0}; i < parent.subAssets.size(); ++i) + { + assetData.emplace( + parent.subAssets[i]->id, + &parentContainer->clips[i] + ); + } + } + break; + + default: + SHLOG_WARNING("[Asset Manager] Parent type not supported to load sub assets, aborting..."); + return nullptr; } return assetData[asset.id]; diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index c5652c5f..b45f1e3c 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -22,6 +22,9 @@ #include "Assets/Asset Types/SHPrefabAsset.h" #include "Serialization/SHSerialization.h" #include + +#include "Assets/Asset Types/SHAnimClipContainerAsset.h" +#include "Assets/Asset Types/Models/SHModelAsset.h" #include "Serialization/Prefab/SHPrefabManager.h" #include "Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h" @@ -368,17 +371,12 @@ namespace SHADE { switch (asset->type) { - case AssetType::INVALID: break; - case AssetType::SHADER: break; - case AssetType::SHADER_BUILT_IN: break; - case AssetType::TEXTURE: break; - case AssetType::MODEL: - if (auto animInspector = SHEditorWindowManager::GetEditorWindow()) - { - animInspector->Open(asset->id); - } - break; - case AssetType::MESH: break; + case AssetType::INVALID: break; + case AssetType::SHADER: break; + case AssetType::SHADER_BUILT_IN: break; + case AssetType::TEXTURE: break; + case AssetType::MODEL: break; + case AssetType::MESH: break; case AssetType::SCENE: { if(editor->LoadScene(asset->id)) @@ -389,7 +387,7 @@ namespace SHADE } } break; - case AssetType::PREFAB: break; + case AssetType::PREFAB: break; case AssetType::MATERIAL: if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) { @@ -402,6 +400,12 @@ namespace SHADE scriptEngine->OpenFile(asset->path); } break; + case AssetType::ANIM_CONTAINER: + if (auto animInspector = SHEditorWindowManager::GetEditorWindow()) + { + animInspector->Open(asset->id); + } + break; case AssetType::MAX_COUNT: break; default:; } @@ -487,6 +491,48 @@ namespace SHADE isAssetBeingCreated = false; ImGui::CloseCurrentPopup(); } + + { + auto const models {SHAssetManager::GetAllRecordOfType(AssetType::MODEL)}; + + ImGui::RadioButton("Animation Clip Container", true); + ImGui::SameLine(); + static char const* const modelPrompt = "Select a model with animations"; + char const* currentItem = modelPrompt; + AssetID selected {0}; + if (ImGui::BeginCombo("##combo", currentItem, ImGuiComboFlags_None)) + { + for (auto const& model : models) + { + bool isSelected = currentItem == model.name; + if (ImGui::Selectable(model.name.data(), isSelected)) + { + auto const data {SHAssetManager::GetConstData(model.id)}; + if (!data->anims.empty()) + { + const auto animContainerId = SHAssetManager::CreateNewAsset(AssetType::ANIM_CONTAINER, model.name + "Anims"); + auto data = SHAssetManager::GetData(animContainerId); + data->animRawDataAssetId = model.id; + SHAssetManager::SaveAsset(animContainerId); + if (auto animInspector = SHEditorWindowManager::GetEditorWindow()) + { + animInspector->Open(animContainerId); + } + QueueRefresh(); + isAssetBeingCreated = false; + ImGui::CloseCurrentPopup(); + } + } + + if (isSelected) + { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + } + ImGui::EndPopup(); } //if (ImGui::BeginMenu("Create Asset")) diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index f587a554..75ab7945 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -38,8 +38,15 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* SHAnimClipCreatePrompt - Lifecycle Functions */ /*---------------------------------------------------------------------------------*/ - void SHAnimClipCreatePrompt::Init(Handle rawAnim, std::function onClose) + void SHAnimClipCreatePrompt::Init( + SHAsset* contAsset, + SHAnimClipContainerAsset* cont, + Handle rawAnim, + std::function onClose + ) { + containerAsset = contAsset; + container = cont; rawAnimation = rawAnim; // Set default parameters @@ -61,10 +68,10 @@ namespace SHADE // Properties SHEditorUI::InputTextField("Name", newAssetName); SHEditorUI::PushID(0); - SHEditorUI::InputSlider("First Frame Index", 0, rawAnimation->GetTotalFrames(), firstIndex); + SHEditorUI::InputUnsignedInt("First Frame Index", firstIndex); SHEditorUI::PopID(); SHEditorUI::PushID(1); - SHEditorUI::InputSlider("Last Frame Index", 0, rawAnimation->GetTotalFrames(), lastIndex); + SHEditorUI::InputUnsignedInt("Last Frame Index", lastIndex); SHEditorUI::PopID(); // Invalid values @@ -76,11 +83,12 @@ namespace SHADE if (ImGui::Button("Save")) { // Generate new asset - const AssetID NEW_ASSET_ID = SHAssetManager::CreateNewAsset(AssetType::ANIM_CLIP, newAssetName); + const AssetID NEW_ASSET_ID = SHAssetManager::CreateNewSubAsset(AssetType::ANIM_CLIP, newAssetName, containerAsset->id); auto animClip = SHAssetManager::GetData(NEW_ASSET_ID); + animClip->name = newAssetName; animClip->firstIndex = firstIndex; animClip->lastIndex = lastIndex; - SHAssetManager::SaveAsset(NEW_ASSET_ID); + SHAssetManager::SaveAsset(containerAsset->id); // Close isOpen = false; @@ -128,7 +136,7 @@ namespace SHADE if (Begin()) { // Ignore if no asset - if (currRawAnim) + if (container) { drawMenuBar(); @@ -136,7 +144,7 @@ namespace SHADE if (ImGui::Button(std::format("{} Create Animation Clip", ICON_MD_ADD).data())) { auto prompt = SHEditorWindowManager::GetPopupWindow(); - prompt->Init(currRawAnim, [this](AssetID createdAssetId) + prompt->Init(containerAsset, container, currRawAnim, [this](AssetID createdAssetId) { if (createdAssetId != INVALID_ASSET_ID) { @@ -216,11 +224,13 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ void SHRawAnimInspector::Open(AssetID assetId) { - currRawAnim = SHResourceManager::LoadOrGet(assetId); + containerAsset = SHAssetManager::GetAsset(assetId); + container = SHAssetManager::GetData(assetId); // Load anim clips - if (currRawAnim) + if (container) { + currRawAnim = SHResourceManager::LoadOrGet(container->animRawDataAssetId); childAnimClips = getChildAnimClips(assetId); } else @@ -248,31 +258,14 @@ namespace SHADE } } - std::vector> SHRawAnimInspector::getChildAnimClips(AssetID rawAnimId) + std::vector> SHRawAnimInspector::getChildAnimClips(AssetID containerId) { + auto const containerAsset {*SHAssetManager::GetAsset(containerId)}; std::vector> animClips; - //const auto ALL_ANIM_CLIPS = SHAssetManager::GetAllRecordOfType(AssetType::ANIM_CLIP); - //for (auto asset : ALL_ANIM_CLIPS) - //{ - // const SHAnimClipAsset* ANIM_CLIP = SHAssetManager::GetData(asset.id); - // if (ANIM_CLIP->animRawDataAssetId == rawAnimId) - // { - // animClips.emplace_back(SHResourceManager::LoadOrGet(asset.id)); - // } - //} - - const auto ALL_ANIM_CLIPS = SHAssetManager::GetAllRecordOfType(AssetType::ANIM_CONTAINER); - for (auto const& asset : ALL_ANIM_CLIPS) + for (auto const& asset : containerAsset.subAssets) { - auto const ANIM_CLIP {SHAssetManager::GetData(asset.id)}; - if (ANIM_CLIP->animRawDataAssetId == rawAnimId) - { - for (auto const& subAsset : asset.subAssets) - { - animClips.emplace_back(SHResourceManager::LoadOrGet(subAsset->id)); - } - } + animClips.emplace_back(SHResourceManager::LoadOrGet(asset->id)); } return animClips; diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h index b6857568..6790cded 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h @@ -16,6 +16,8 @@ of DigiPen Institute of Technology is prohibited. #include "Editor/EditorWindow/SHEditorWindow.h" #include "Resource/SHHandle.h" #include "Animation/SHRawAnimation.h" +#include "Assets/SHAsset.h" +#include "Assets/Asset Types/SHAnimClipContainerAsset.h" #include "Editor/EditorWindow/SHPopUpWindow.h" namespace SHADE @@ -45,7 +47,12 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*---------------------------------------------------------------------------------*/ - void Init(Handle rawAnim, std::function onClose = nullptr); + void Init( + SHAsset* contAsset, + SHAnimClipContainerAsset* cont, + Handle rawAnim, + std::function onClose = nullptr + ); void Draw() override; private: @@ -53,9 +60,11 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ std::string newAssetName; - int firstIndex = 0; - int lastIndex = 0; + uint32_t firstIndex = 0; + uint32_t lastIndex = 0; Handle rawAnimation; + SHAsset* containerAsset{nullptr}; + SHAnimClipContainerAsset* container{nullptr}; std::function onClose; }; @@ -87,6 +96,8 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ + SHAsset* containerAsset{nullptr}; + SHAnimClipContainerAsset* container {nullptr}; Handle currRawAnim; std::vector> childAnimClips; @@ -94,6 +105,6 @@ namespace SHADE /* Helper Functions */ /*---------------------------------------------------------------------------------*/ void drawMenuBar(); - std::vector> getChildAnimClips(AssetID rawAnimId); + std::vector> getChildAnimClips(AssetID containerId); }; }