Implemented Animation Clip asset and animation controller #410
Binary file not shown.
|
@ -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
|
|
@ -60,6 +60,8 @@ namespace SHADE
|
|||
// Compute fps
|
||||
ticksPerSecond = static_cast<int>(maxFrames / totalTime);
|
||||
}
|
||||
|
||||
totalFrames = maxFrames;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -30,6 +30,6 @@ namespace SHADE
|
|||
struct SH_API SHAnimClipContainerAsset final : SHAssetData
|
||||
{
|
||||
AssetID animRawDataAssetId;
|
||||
std::vector<SHAnimClipAsset> clips;
|
||||
std::vector<SHAnimClipAsset> clips{};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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/" };
|
||||
|
||||
|
||||
|
|
|
@ -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<size_t>(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<SHModelAsset*>(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<SHModelAsset*>(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<SHAnimClipContainerAsset*>(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];
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include "Assets/Asset Types/SHPrefabAsset.h"
|
||||
#include "Serialization/SHSerialization.h"
|
||||
#include <Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h>
|
||||
|
||||
#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<SHRawAnimInspector>())
|
||||
{
|
||||
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<SHMaterialInspector>())
|
||||
{
|
||||
|
@ -402,6 +400,12 @@ namespace SHADE
|
|||
scriptEngine->OpenFile(asset->path);
|
||||
}
|
||||
break;
|
||||
case AssetType::ANIM_CONTAINER:
|
||||
if (auto animInspector = SHEditorWindowManager::GetEditorWindow<SHRawAnimInspector>())
|
||||
{
|
||||
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<SHModelAsset>(model.id)};
|
||||
if (!data->anims.empty())
|
||||
{
|
||||
const auto animContainerId = SHAssetManager::CreateNewAsset(AssetType::ANIM_CONTAINER, model.name + "Anims");
|
||||
auto data = SHAssetManager::GetData<SHAnimClipContainerAsset>(animContainerId);
|
||||
data->animRawDataAssetId = model.id;
|
||||
SHAssetManager::SaveAsset(animContainerId);
|
||||
if (auto animInspector = SHEditorWindowManager::GetEditorWindow<SHRawAnimInspector>())
|
||||
{
|
||||
animInspector->Open(animContainerId);
|
||||
}
|
||||
QueueRefresh();
|
||||
isAssetBeingCreated = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
if (isSelected)
|
||||
{
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
//if (ImGui::BeginMenu("Create Asset"))
|
||||
|
|
|
@ -38,8 +38,15 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* SHAnimClipCreatePrompt - Lifecycle Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHAnimClipCreatePrompt::Init(Handle<SHRawAnimation> rawAnim, std::function<void(AssetID)> onClose)
|
||||
void SHAnimClipCreatePrompt::Init(
|
||||
SHAsset* contAsset,
|
||||
SHAnimClipContainerAsset* cont,
|
||||
Handle<SHRawAnimation> rawAnim,
|
||||
std::function<void(AssetID)> 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<SHAnimClipAsset>(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<SHAnimClipCreatePrompt>();
|
||||
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<SHRawAnimation>(assetId);
|
||||
containerAsset = SHAssetManager::GetAsset(assetId);
|
||||
container = SHAssetManager::GetData<SHAnimClipContainerAsset>(assetId);
|
||||
|
||||
// Load anim clips
|
||||
if (currRawAnim)
|
||||
if (container)
|
||||
{
|
||||
currRawAnim = SHResourceManager::LoadOrGet<SHRawAnimation>(container->animRawDataAssetId);
|
||||
childAnimClips = getChildAnimClips(assetId);
|
||||
}
|
||||
else
|
||||
|
@ -248,31 +258,14 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<Handle<SHAnimationClip>> SHRawAnimInspector::getChildAnimClips(AssetID rawAnimId)
|
||||
std::vector<Handle<SHAnimationClip>> SHRawAnimInspector::getChildAnimClips(AssetID containerId)
|
||||
{
|
||||
auto const containerAsset {*SHAssetManager::GetAsset(containerId)};
|
||||
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));
|
||||
// }
|
||||
//}
|
||||
|
||||
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<SHAnimClipContainerAsset>(asset.id)};
|
||||
if (ANIM_CLIP->animRawDataAssetId == rawAnimId)
|
||||
{
|
||||
for (auto const& subAsset : asset.subAssets)
|
||||
{
|
||||
animClips.emplace_back(SHResourceManager::LoadOrGet<SHAnimationClip>(subAsset->id));
|
||||
}
|
||||
}
|
||||
animClips.emplace_back(SHResourceManager::LoadOrGet<SHAnimationClip>(asset->id));
|
||||
}
|
||||
|
||||
return animClips;
|
||||
|
|
|
@ -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<SHRawAnimation> rawAnim, std::function<void(AssetID)> onClose = nullptr);
|
||||
void Init(
|
||||
SHAsset* contAsset,
|
||||
SHAnimClipContainerAsset* cont,
|
||||
Handle<SHRawAnimation> rawAnim,
|
||||
std::function<void(AssetID)> 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<SHRawAnimation> rawAnimation;
|
||||
SHAsset* containerAsset{nullptr};
|
||||
SHAnimClipContainerAsset* container{nullptr};
|
||||
std::function<void(AssetID)> onClose;
|
||||
};
|
||||
|
||||
|
@ -87,6 +96,8 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SHAsset* containerAsset{nullptr};
|
||||
SHAnimClipContainerAsset* container {nullptr};
|
||||
Handle<SHRawAnimation> currRawAnim;
|
||||
std::vector<Handle<SHAnimationClip>> childAnimClips;
|
||||
|
||||
|
@ -94,6 +105,6 @@ namespace SHADE
|
|||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void drawMenuBar();
|
||||
std::vector<Handle<SHAnimationClip>> getChildAnimClips(AssetID rawAnimId);
|
||||
std::vector<Handle<SHAnimationClip>> getChildAnimClips(AssetID containerId);
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue