diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index ef15f223..9da907bf 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -118,8 +118,8 @@ namespace SHADE nodes.emplace_back(node); // If there is no start node, this is the first node so make it the starting node - if (!StartingNode) - StartingNode = node; + if (!startNode) + startNode = node; return node; } @@ -132,8 +132,8 @@ namespace SHADE throw std::invalid_argument("[SHAnimationController] Attempted to delete a node that doesn't belong."); // Remove if it is a start node - if (StartingNode == node) - StartingNode = {}; + if (startNode == node) + startNode = {}; // Remove from nodes nodes.erase(iter); diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index 7708d0c9..64210481 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -145,11 +145,6 @@ namespace SHADE std::unordered_map Params; float ClipPlaybackTime; }; - - /*---------------------------------------------------------------------------------*/ - /* Data Members */ - /*---------------------------------------------------------------------------------*/ - Handle StartingNode; /*---------------------------------------------------------------------------------*/ /* Lifecycle Functions */ @@ -191,11 +186,11 @@ namespace SHADE /// /// Name of the parameter. void RemoveParameter(const std::string& name); - void SetStartingNode(Handle node); /*---------------------------------------------------------------------------------*/ /* Getters */ /*---------------------------------------------------------------------------------*/ + Handle GetStartingNode() const noexcept { return startNode; } const std::unordered_map& GetParams() const noexcept { return parameters; } const std::vector>& GetNodes() const noexcept { return nodes; } @@ -204,6 +199,7 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ // State machine + Handle startNode; std::vector> nodes; std::unordered_map parameters; diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 0059d721..1ab5c894 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -169,7 +169,7 @@ namespace SHADE animInstanceData.Params.emplace(param.first, SHAnimationController::AnimParam(param.second)); } // First Node - animInstanceData.CurrentNode = animController->StartingNode; + animInstanceData.CurrentNode = animController->GetStartingNode(); // Playback Time animInstanceData.ClipPlaybackTime = 0.0f; diff --git a/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h b/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h index d7128977..6e98c661 100644 --- a/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h @@ -82,7 +82,5 @@ namespace SHADE double ticksPerSecond; std::vector nodeChannels; - //std::vector meshChannels; - //std::vector morphMeshChannels; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h similarity index 81% rename from SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h rename to SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h index c6887316..bac68579 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h @@ -12,17 +12,24 @@ of DigiPen Institute of Technology is prohibited. #pragma once #include "SH_API.h" -#include "SHAssetData.h" #include +#include "Assets/SHAssetMacros.h" +#include "SHAssetData.h" + namespace SHADE { - struct SH_API SHAnimClipAsset : SHAssetData + struct SHAnimClipAsset : SHAssetData { std::string name; - AssetID animRawDataAssetId; uint32_t firstIndex; uint32_t lastIndex; }; -} \ No newline at end of file + + struct SH_API SHAnimClipContainerAsset final : SHAssetData + { + AssetID animRawDataAssetId; + std::vector clips; + }; +} diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp index 8ea85811..ad2a7f2c 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp @@ -1,7 +1,7 @@ #include "SHpch.h" #include "SHBinaryLoader.h" -#include "Assets/Asset Types/SHAnimClipAsset.h" +#include "Assets/Asset Types/SHAnimClipContainerAsset.h" #include @@ -19,15 +19,9 @@ namespace SHADE auto const extension = path.extension().string(); SHAssetData* result{nullptr}; - if (extension == ANIM_CLIP_EXTENSION) + if (extension == ANIM_CONTAINER_EXTENSION) { - const auto data = new SHAnimClipAsset(); - file.read( - reinterpret_cast(&data->animRawDataAssetId), - sizeof(uint32_t) * 3 - ); - data->name = path.stem().string(); - result = data; + LoadAnimClipContainer(file, result, path); } file.close(); @@ -47,15 +41,84 @@ namespace SHADE auto const extension = path.extension().string(); - if (extension == ANIM_CLIP_EXTENSION) + if (extension == ANIM_CONTAINER_EXTENSION) { - auto animClip = dynamic_cast(data); - file.write( - reinterpret_cast(&animClip->animRawDataAssetId), - sizeof(uint32_t) * 3 - ); + WriteAnimClipContainer(file, data, path); } file.close(); } + + void SHBinaryLoader::WriteAnimClipContainer(std::ofstream& file, SHAssetData const* data, AssetPath path) + { + auto const& anim = *dynamic_cast(data); + file.write( + reinterpret_cast(&anim.animRawDataAssetId), + sizeof(uint32_t) + ); + + uint32_t const size {static_cast(anim.clips.size())}; + + file.write( + reinterpret_cast(&size), + sizeof(uint32_t) + ); + + for (auto const& clip : anim.clips) + { + uint32_t charCount {static_cast(clip.name.size())}; + file.write( + reinterpret_cast(&charCount), + sizeof(uint32_t) + ); + + file.write( + clip.name.data(), + charCount + ); + + file.write( + reinterpret_cast(&clip.firstIndex), + sizeof(uint32_t) * 2 + ); + } + } + + void SHBinaryLoader::LoadAnimClipContainer(std::ifstream& file, SHAssetData* result, AssetPath path) + { + auto const data = new SHAnimClipContainerAsset(); + + file.read( + reinterpret_cast(&data->animRawDataAssetId), + sizeof(uint32_t) + ); + + uint32_t size; + + file.read( + reinterpret_cast(&size), + sizeof(uint32_t) + ); + + for (auto i{0}; i < size; ++i) + { + auto& clip {data->clips.emplace_back()}; + uint32_t charCount; + file.read( + reinterpret_cast(&charCount), + sizeof(uint32_t) + ); + + clip.name.resize(charCount); + file.read( + clip.name.data(), + charCount + ); + + file.read( + reinterpret_cast(&clip.firstIndex), + sizeof(uint32_t) * 2 + ); + } + } } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h index db2316e8..7cf50d51 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h @@ -8,5 +8,10 @@ namespace SHADE { SHAssetData* Load(AssetPath path) override; void Write(SHAssetData const* data, AssetPath path) override; + + private: + //Individual functions to write files + void WriteAnimClipContainer(std::ofstream& file,SHAssetData const* data, AssetPath path); + void LoadAnimClipContainer(std::ifstream& file,SHAssetData* result, AssetPath path); }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 510bc35a..f9e21f15 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -57,6 +57,7 @@ enum class AssetType : AssetTypeMeta MESH, SCRIPT, FONT, + ANIM_CONTAINER, ANIM_CLIP, MAX_COUNT }; @@ -79,7 +80,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{ "/Animation Clips/" }; +constexpr std::string_view ANIM_CLIP_FOLDER{ "/Animations/" }; // ASSET EXTENSIONS @@ -95,7 +96,8 @@ constexpr std::string_view PREFAB_EXTENSION {".shprefab"}; constexpr std::string_view MATERIAL_EXTENSION {".shmat"}; constexpr std::string_view TEXTURE_EXTENSION {".shtex"}; constexpr std::string_view MODEL_EXTENSION{ ".shmodel" }; -constexpr std::string_view ANIM_CLIP_EXTENSION{ ".shanimclip" }; +constexpr std::string_view ANIM_CONTAINER_EXTENSION{ ".shanimcontainer" }; +constexpr std::string_view FILLER_EXTENSION{"dummy"}; constexpr std::string_view EXTENSIONS[] = { AUDIO_EXTENSION, @@ -106,14 +108,15 @@ constexpr std::string_view EXTENSIONS[] = { SCENE_EXTENSION, PREFAB_EXTENSION, MATERIAL_EXTENSION, - "dummy", + FILLER_EXTENSION, SCRIPT_EXTENSION, FONT_EXTENSION, AUDIO_WAV_EXTENSION, - ANIM_CLIP_EXTENSION + ANIM_CONTAINER_EXTENSION, + FILLER_EXTENSION }; -constexpr size_t EXTENSIONS_COUNT{ 11 }; +constexpr size_t EXTENSIONS_COUNT{ static_cast(AssetType::MAX_COUNT) }; // EXTERNAL EXTENSIONS constexpr std::string_view GLSL_EXTENSION{ ".glsl" }; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 503f9082..5ad2bbd4 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -26,7 +26,7 @@ #include "Asset Types/SHPrefabAsset.h" #include "Asset Types/SHMaterialAsset.h" #include "Asset Types/SHSceneAsset.h" -#include "Asset Types/SHAnimClipAsset.h" +#include "Asset Types/SHAnimClipContainerAsset.h" #include "Libraries/Compilers/SHTextureCompiler.h" #include "Libraries/Compilers/SHShaderSourceCompiler.h" @@ -238,10 +238,10 @@ namespace SHADE } break; - case AssetType::ANIM_CLIP: + case AssetType::ANIM_CONTAINER: newPath += ANIM_CLIP_FOLDER; newPath += name; - newPath += ANIM_CLIP_EXTENSION; + newPath += ANIM_CONTAINER_EXTENSION; { auto animClip = new SHAnimClipAsset(); @@ -252,7 +252,7 @@ namespace SHADE default: - SHLOG_ERROR("[Asset Manager] Asset type of {} not an internal asset type, cannot be created", name); + SHLOG_ERROR("[Asset Manager] Asset type of {} not an internal parent asset type, cannot be created", name); return 0; } @@ -267,13 +267,13 @@ namespace SHADE auto result = assetCollection.emplace( id, - SHAsset( - name, - id, - type, - newPath, - false - ) + SHAsset( + name, + id, + type, + newPath, + false + ) ); assetData.emplace(id, data); @@ -284,6 +284,40 @@ namespace SHADE return id; } + AssetID SHAssetManager::CreateNewSubAsset(AssetType type, AssetName name, AssetID parent) + { + if (!assetData.contains(parent)) + { + SHLOG_ERROR("[Asset Manager] Failed to create new sub asset, parent does not exist: {}", name); + return 0; + } + + switch(type) + { + case AssetType::ANIM_CLIP: + { + auto const animContainer {dynamic_cast(assetData[parent])}; + auto id = GenerateAssetID(type); + SHAsset asset{ + .name = name, + .id = id, + .type = type, + .isSubAsset = true, + .parent = parent + }; + auto& newClip {animContainer->clips.emplace_back()}; + newClip.name = name; + assetCollection.emplace(id, asset); + assetData.emplace(id, &newClip); + return id; + } + + default: + SHLOG_ERROR("[Asset Manager] Asset type of {} not an internal sub asset type, cannot be created", name); + return 0; + } + } + bool SHAssetManager::SaveAsset(AssetID id) noexcept { if (assetCollection.contains(id)) @@ -547,7 +581,8 @@ namespace SHADE loaders[static_cast(AssetType::MESH)] = nullptr; loaders[static_cast(AssetType::SCRIPT)] = nullptr; loaders[static_cast(AssetType::FONT)] = dynamic_cast(new SHFontLoader()); - loaders[static_cast(AssetType::ANIM_CLIP)] = dynamic_cast(new SHBinaryLoader()); + loaders[static_cast(AssetType::ANIM_CONTAINER)] = dynamic_cast(new SHBinaryLoader()); + loaders[static_cast(AssetType::ANIM_CLIP)] = nullptr; } /**************************************************************************** @@ -758,6 +793,38 @@ namespace SHADE return newAsset.id; } + else if(ext==ANIM_CONTAINER_EXTENSION) + { + SHAsset newAsset{ + path.stem().string(), + GenerateAssetID(AssetType::ANIM_CONTAINER), + AssetType::ANIM_CONTAINER, + path, + false + }; + + assetCollection.emplace(newAsset.id, newAsset); + + SHAnimClipContainerAsset* const data = reinterpret_cast(LoadData(newAsset)); + assetData.emplace(newAsset.id, data); + for(auto& clip : data->clips) + { + SHAsset subAsset{ + .name = clip.name, + .id = GenerateAssetID(AssetType::ANIM_CLIP), + .type = AssetType::ANIM_CLIP, + .isSubAsset = true, + .parent = newAsset.id + }; + + assetCollection.emplace(subAsset.id, subAsset); + assetCollection[newAsset.id].subAssets.push_back(&assetCollection[subAsset.id]); + + assetData.emplace(subAsset.id, &clip); + } + + SHAssetMetaHandler::WriteMetaData(assetCollection[newAsset.id]); + } } void SHAssetManager::BuildAssetCollection() noexcept @@ -814,7 +881,9 @@ namespace rttr value("Material", AssetType::MATERIAL), value("Mesh", AssetType::MESH), value("Script", AssetType::SCRIPT), - value("Font", AssetType::FONT) + value("Font", AssetType::FONT), + value("Animation Container", AssetType::ANIM_CONTAINER), + value("Animation Clip", AssetType::ANIM_CLIP) ); } } diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index e5cd0359..6a8f91ef 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -63,6 +63,7 @@ namespace SHADE * \return resource id generated for new asset ****************************************************************************/ static AssetID CreateNewAsset(AssetType type, AssetName name) noexcept; + static AssetID CreateNewSubAsset(AssetType type, AssetName name, AssetID parent); static bool SaveAsset(AssetID id) noexcept; static bool DeleteAsset(AssetID id) noexcept; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index a67c6a67..33372760 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -3,7 +3,7 @@ \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Mar 1, 2023 -\brief Contains the definition of SHAnimationControllerEditor's functions. +\brief Contains the definition of SHAnimationControllerEditor's functions. Copyright (C) 2023 DigiPen Institute of Technology. @@ -23,8 +23,7 @@ of DigiPen Institute of Technology is prohibited. #include "Animation/SHAnimationController.h" #include "Editor/SHEditorUI.h" #include "Editor/SHEditorWidgets.hpp" -#include "Editor/Command/SHCommand.hpp" -#include "Input/SHInputManager.h" +#include "../../Command/SHCommand.hpp" namespace SHADE { @@ -145,9 +144,8 @@ namespace SHADE SHEditorWindow::Exit(); } - void SHAnimationControllerEditor::Open(SHAnimationController& controllerHandle) + void SHAnimationControllerEditor::Open(const SHAnimationController& controller) { - controller = controllerHandle; controllerData = deserialise(controller); } /*-----------------------------------------------------------------------------------*/ @@ -160,12 +158,12 @@ namespace SHADE // Save Button if (ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) { - controller = serialise(controllerData.value()); // TODO: Actually save the resource + // TODO } // Discard Button if (ImGui::Button(std::format("{} Discard Changes", ICON_MD_CANCEL).data())) { - Open(controller); // TODO: Actually load the resource + // TODO } ImGui::EndMenuBar(); @@ -213,6 +211,7 @@ namespace SHADE // Put into the new controllerData->Params[val] = TYPE; + // TODO: This needs to be handled in a custom command // Update all links for (auto& link : controllerData->Links) { @@ -294,11 +293,10 @@ namespace SHADE ImGui::SameLine(); // Delete Node Button - ImGui::BeginDisabled((ImNodes::NumSelectedNodes() + ImNodes::NumSelectedLinks()) < 1); - if (ImGui::Button(std::format("{} Delete Objects", ICON_MD_DELETE).data())) + ImGui::BeginDisabled(ImNodes::NumSelectedNodes() < 1); + if (ImGui::Button(std::format("{} Delete Nodes", ICON_MD_ADD).data())) { - deleteSelectedLinks(); - deleteSelectedNodes(); + } ImGui::EndDisabled(); ImGui::SameLine(); @@ -307,10 +305,7 @@ namespace SHADE ImGui::BeginDisabled(ImNodes::NumSelectedNodes() != 1); if (ImGui::Button(std::format("{} Set Starting Node", ICON_MD_HOME).data())) { - // Get id of selected node - int selectedNode = 0; - ImNodes::GetSelectedNodes(&selectedNode); - controllerData->StartingNode = selectedNode; // We can do this as the ImNodes node index is the same + } ImGui::EndDisabled(); } @@ -330,15 +325,6 @@ namespace SHADE // Title ImNodes::BeginNodeTitleBar(); { - // Starting node marker - if (node.Index == controllerData->StartingNode) - { - const float INDENT = NODE_WIDTH * 0.6f; - ImGui::Indent(INDENT); - ImGui::Text(ICON_MD_HOME); - ImGui::Unindent(INDENT); - } - if (node.EditingName) { if (ImGui::Button(ICON_MD_DONE)) @@ -425,13 +411,6 @@ namespace SHADE ); } } - - // Delete - if (SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::DEL)) - { - deleteSelectedLinks(); - deleteSelectedNodes(); - } } void SHAnimationControllerEditor::drawPropertiesMenuBar() @@ -683,34 +662,6 @@ namespace SHADE ImGui::Text(TITLE); ImNodes::EndOutputAttribute(); } - void SHAnimationControllerEditor::deleteSelectedNodes() - { - const int NUM_SELECTED_NODES= ImNodes::NumSelectedNodes(); - if (NUM_SELECTED_NODES > 0) - { - std::vector selectedNodes(NUM_SELECTED_NODES); - ImNodes::GetSelectedNodes(selectedNodes.data()); - - for (auto nodeId : selectedNodes) - { - deleteNode(controllerData.value(), nodeId); - } - } - } - void SHAnimationControllerEditor::deleteSelectedLinks() - { - const int NUM_SELECTED_LINKS = ImNodes::NumSelectedLinks(); - if (NUM_SELECTED_LINKS > 0) - { - std::vector selectedLinks(NUM_SELECTED_LINKS); - ImNodes::GetSelectedLinks(selectedLinks.data()); - - for (auto linkId : selectedLinks) - { - deleteLink(controllerData.value(), linkId); - } - } - } std::list::iterator SHAnimationControllerEditor::createNode(AnimControllerData& data) { const NodeIndex NEW_NODE_IDX = data.NextNodeIndex++; @@ -753,62 +704,6 @@ namespace SHADE return EMPLACE_DATA.first; } - void SHAnimationControllerEditor::deleteLink(AnimControllerData& data, LinkIndex link) - { - const NodeLinkIndex LINK_IDX { link }; - - // Error check, don't do anything if they don't exist - if (!data.IndexToNodeMap.contains(LINK_IDX.SourceAttribute.OwnerNodeIndex) || - !data.IndexToNodeMap.contains(LINK_IDX.DestinationAttribute.OwnerNodeIndex)) - return; - - // Get source node and attributes - auto& sourceNode = *data.IndexToNodeMap[LINK_IDX.SourceAttribute.OwnerNodeIndex]; - auto& destNode = *data.IndexToNodeMap[LINK_IDX.DestinationAttribute.OwnerNodeIndex]; - - // Remove attributes - std::erase(sourceNode.OutputAttribs, LINK_IDX.SourceAttribute); - std::erase(destNode.InputAttribs, LINK_IDX.DestinationAttribute); - - // Remove link - std::erase(sourceNode.Transitions, LINK_IDX); - data.Links.erase(link); - } - void SHAnimationControllerEditor::deleteNode(AnimControllerData& data, NodeIndex nodeIndex) - { - // Get node to delete - if (!data.IndexToNodeMap.contains(nodeIndex)) - return; - auto nodeToDeleteIter = data.IndexToNodeMap[nodeIndex]; - - // Remove all links to other nodes - for (auto link : nodeToDeleteIter->Transitions) - { - deleteLink(data, link.Raw); - } - - // Remove all links from other nodes - for (auto node : data.Nodes) - { - for (NodeLinkIndex link : node.Transitions) - { - if (link.DestinationAttribute.OwnerNodeIndex == nodeIndex) - { - deleteLink(data, link.Raw); - } - } - } - - // Then finally, delete this node - data.IndexToNodeMap.erase(nodeIndex); - data.Nodes.erase(nodeToDeleteIter); - - // If the starting node was this node, we need to reassign - if (data.StartingNode == nodeIndex) - { - data.StartingNode = data.Nodes.empty() ? data.NextNodeIndex : data.Nodes.front().Index; - } - } /*-----------------------------------------------------------------------------------*/ /* Static Helper Functions */ /*-----------------------------------------------------------------------------------*/ @@ -854,73 +749,10 @@ namespace SHADE } } - // Mark starting node - if (nodeMap.contains(controller.StartingNode)) - { - data.StartingNode = nodeMap[controller.StartingNode]->Index; - } - return data; } SHAnimationController SHAnimationControllerEditor::serialise(const AnimControllerData& data) { - SHAnimationController controller; - - // Maps data nodes to controller nodes - std::unordered_map> nodeMap; - - // Create all nodes first - for (const auto& node : data.Nodes) - { - auto newNode = controller.CreateNode(); - newNode->Name = node.Name; - newNode->Clip = node.Clip; - - nodeMap[node.Index] = newNode; - } - - // Create links - for (const auto& node : data.Nodes) - { - // Get controller node - auto controllerNode = nodeMap[node.Index]; - - for (auto link : node.Transitions) - { - // Ignore invalid link - if (!nodeMap.contains(link.SourceAttribute.OwnerNodeIndex) || !nodeMap.contains(link.DestinationAttribute.OwnerNodeIndex)) - continue; - - // Get link data - const LinkData& LINK_DATA = data.Links.at(link.Raw); - - SHAnimationController::Transition transition; - transition.Target = nodeMap[link.DestinationAttribute.OwnerNodeIndex]; - - if (data.Params.contains(LINK_DATA.ParamName)) - { - transition.Condition = LINK_DATA.Condition; - transition.ParamName = LINK_DATA.ParamName; - transition.Param.ParamType = data.Params.at(LINK_DATA.ParamName); - transition.Param.Value = LINK_DATA.ParamThresholdValue; - } - - controllerNode->Transitions.emplace_back(std::move(transition)); - } - } - - // Starting Node - if (nodeMap.contains(data.StartingNode)) - { - controller.StartingNode = nodeMap[data.StartingNode]; - } - - // Parameters - for (auto param : data.Params) - { - controller.AddParameter(param.first, param.second); - } - - return controller; + return {}; } } \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h index 1066fc7b..bafbe4a9 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h @@ -45,7 +45,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Usage Functions */ /*---------------------------------------------------------------------------------*/ - void Open(SHAnimationController& controller); + void Open(const SHAnimationController& controller); private: /*---------------------------------------------------------------------------------*/ @@ -61,8 +61,6 @@ namespace SHADE NodeIndex OwnerNodeIndex; int8_t AttributeIndex; // Negative is input, positive is output }; - - bool operator==(NodeAttributeIndex rhs) const noexcept { return Raw == rhs.Raw; } }; union NodeLinkIndex { @@ -72,8 +70,6 @@ namespace SHADE NodeAttributeIndex SourceAttribute; NodeAttributeIndex DestinationAttribute; }; - - bool operator==(NodeLinkIndex rhs) const noexcept { return Raw != rhs.Raw; } }; struct Node @@ -104,7 +100,7 @@ namespace SHADE struct AnimControllerData { - NodeIndex StartingNode = 0; + std::list Nodes; std::unordered_map Params; LinkMap Links; @@ -115,7 +111,6 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ - SHAnimationController controller; std::optional controllerData; // Persistent Cached Data std::vector conditionsList; @@ -135,16 +130,12 @@ namespace SHADE NodeAttributeIndex getExtraOutputAttrib(uint32_t nodeIndex); void drawInputNode(int id, ImNodesPinShape_ pinShape); void drawOutputNode(int id, int parentNodeId, ImNodesPinShape_ pinShape); - void deleteSelectedNodes(); - void deleteSelectedLinks(); /*---------------------------------------------------------------------------------*/ /* Static Helper Functions */ /*---------------------------------------------------------------------------------*/ static std::list::iterator createNode(AnimControllerData& data); static LinkMap::iterator createLink(AnimControllerData& data, std::list::iterator sourceNode, std::list::iterator destNode); - static void deleteLink(AnimControllerData& data, LinkIndex link); - static void deleteNode(AnimControllerData& data, NodeIndex nodeIndex); static AnimControllerData deserialise(const SHAnimationController& controller); static SHAnimationController serialise(const AnimControllerData& data); }; diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index 21303982..2dfc7dac 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -21,7 +21,7 @@ of DigiPen Institute of Technology is prohibited. #include "Assets/Asset Types/Models/SHModelAsset.h" #include "Assets/Asset Types/SHTextureAsset.h" #include "Assets/Asset Types/SHShaderAsset.h" -#include "Assets/Asset Types/SHAnimClipAsset.h" +#include "Assets/Asset Types/SHAnimClipContainerAsset.h" #include "Assets/Asset Types/SHAnimControllerAsset.h" #include "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"