From c85298db88f6e5a4f1b08139865214541872e794 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 20 Feb 2023 16:55:08 +0800 Subject: [PATCH 01/69] Added initial stubs for SHAnimationController --- .../src/Animation/SHAnimationController.cpp | 19 +++ .../src/Animation/SHAnimationController.h | 115 ++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 SHADE_Engine/src/Animation/SHAnimationController.cpp create mode 100644 SHADE_Engine/src/Animation/SHAnimationController.h diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp new file mode 100644 index 00000000..3af70309 --- /dev/null +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -0,0 +1,19 @@ +/************************************************************************************//*! +\file SHAnimationController.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Feb 22, 2023 +\brief Contains the definition of SHAnimationController's functions. + + +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. +*//*************************************************************************************/ +#include "SHpch.h" +#include "SHAnimationController.h" + +namespace SHADE +{ + +} diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h new file mode 100644 index 00000000..d21c5c01 --- /dev/null +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -0,0 +1,115 @@ +/************************************************************************************//*! +\file SHAnimationController.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Feb 22, 2023 +\brief Contains the definition of SHAnimationController. + +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 + +// STL Includes +#include +#include +// Project Includes +#include "SH_API.h" +#include "Resource/SHHandle.h" +#include "SHAnimationClip.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + /// + /// Object that controls the animation that is played by an animator through the use + /// of an internal state machine. + /// + class SH_API SHAnimationController + { + public: + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class Node; + + /*---------------------------------------------------------------------------------*/ + /* Type Definition */ + /*---------------------------------------------------------------------------------*/ + /// + /// Describes a parameter for the AnimationController that can be used to control + /// the flow of animations. + /// + struct AnimParam + { + /*-------------------------------------------------------------------------------*/ + /* Type Definition */ + /*-------------------------------------------------------------------------------*/ + /// + /// Type of animation parameter. + /// + enum class Type + { + Bool, + Trigger, + Float, + Int + }; + + /*-------------------------------------------------------------------------------*/ + /* Data Members */ + /*-------------------------------------------------------------------------------*/ + Type ParamType; + std::variant Value; + }; + + /// + /// Describes a transition between nodes of the animation controller. + /// + struct Transition + { + /*-------------------------------------------------------------------------------*/ + /* Type Definition */ + /*-------------------------------------------------------------------------------*/ + /// + /// Types of conditions for the transition. + /// + enum class ConditionType + { + None, + Equals, + NotEquals, + LessThan, + LessThanOrEqual, + GreaterThan, + GreaterThanOrEqual + }; + + /*-------------------------------------------------------------------------------*/ + /* Data Members */ + /*-------------------------------------------------------------------------------*/ + ConditionType Condition; + Handle Target; + }; + + /// + /// Describes a node in the animation controller. + /// + struct Node + { + Handle Clip; + std::vector Transitions; + }; + + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + Handle currentNode; + std::vector> nodes; + }; +} From ecc88dc142d20c29a35728f32631ce37b4ffc19d Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 22 Feb 2023 23:45:42 +0800 Subject: [PATCH 02/69] Fleshed out SHAnimationController more --- .../src/Animation/SHAnimationController.cpp | 59 +++++++++++++++++++ .../src/Animation/SHAnimationController.h | 36 ++++++++++- .../src/Animation/SHAnimationSystem.h | 11 ++++ .../src/Animation/SHAnimatorComponent.cpp | 19 +++++- .../src/Animation/SHAnimatorComponent.h | 8 ++- 5 files changed, 129 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 3af70309..86c665fd 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -12,8 +12,67 @@ of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ #include "SHpch.h" #include "SHAnimationController.h" +#include "SHAnimationSystem.h" +#include "ECS_Base/Managers/SHSystemManager.h" namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHAnimationController::Update() + { + // Is there a valid node + if (!currentNode) + return; + // Update + for (const auto& transition : currentNode->Transitions) + { + + } + } + void SHAnimationController::Reset() + { + currentNode = startNode; + } + + /*-----------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------------*/ + Handle SHAnimationController::CreateNode() + { + // Get system + auto system = SHSystemManager::GetSystem(); + if (system == nullptr) + throw std::runtime_error("[SHAnimationController] No SHAnimationSystem found!"); + + // Construct + auto node = system->GetResourceHub().Create(); + nodes.emplace_back(node); + + // If there is no start node, this is the first node so make it the starting node + if (!startNode) + startNode = node; + + return node; + } + + void SHAnimationController::DestroyNode(Handle node) + { + // Remove from storage + auto iter = std::find(nodes.begin(), nodes.end(), node); + if (iter == nodes.end()) + throw std::invalid_argument("[SHAnimationController] Attempted to delete a node that doesn't belong."); + + // Remove if it is a start node + if (startNode == node) + startNode = {}; + + // Remove from nodes + nodes.erase(iter); + + // Clear node + node.Free(); + } } diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index d21c5c01..c6d353e6 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -92,7 +92,7 @@ namespace SHADE /* Data Members */ /*-------------------------------------------------------------------------------*/ ConditionType Condition; - Handle Target; + Handle Target; }; /// @@ -103,13 +103,47 @@ namespace SHADE Handle Clip; std::vector Transitions; }; + + /*---------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Runs a single update for the animation controller. + /// + void Update(); + /// + /// Resets the animation controller to its starting node. + /// + void Reset(); + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Creates a node in the state machine. Created nodes must be destroyed using + /// DestroyNode(). + /// + /// Node that was created. + Handle CreateNode(); + /// + /// Destroys the node that was created in the state machine. + /// + /// Node to destroy. + void DestroyNode(Handle node); + + /*---------------------------------------------------------------------------------*/ + /* Getters */ + /*---------------------------------------------------------------------------------*/ + Handle GetCurrentNode() const noexcept { return currentNode; } private: /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ + // State machine Handle currentNode; + Handle startNode; std::vector> nodes; + std::unordered_map parameters; }; } diff --git a/SHADE_Engine/src/Animation/SHAnimationSystem.h b/SHADE_Engine/src/Animation/SHAnimationSystem.h index 3d46edc2..81b012d3 100644 --- a/SHADE_Engine/src/Animation/SHAnimationSystem.h +++ b/SHADE_Engine/src/Animation/SHAnimationSystem.h @@ -51,5 +51,16 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ virtual void Init(void) override final; virtual void Exit(void) override final; + + /*---------------------------------------------------------------------------------*/ + /* Getters */ + /*---------------------------------------------------------------------------------*/ + SHResourceHub& GetResourceHub() { return resources; } + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + SHResourceHub resources; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 71db24db..5a6e78ce 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -34,6 +34,7 @@ namespace SHADE void SHAnimatorComponent::Play() { isPlaying = false; + playOnce = false; } void SHAnimatorComponent::Play(Handle clip) @@ -43,6 +44,12 @@ namespace SHADE Play(); } + void SHAnimatorComponent::PlayOneShot(Handle clip) + { + Play(clip); + playOnce = true; + } + void SHAnimatorComponent::PlayFromStart() { isPlaying = true; @@ -110,7 +117,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ void SHAnimatorComponent::Update(float dt) { - //Reset matrices + // Reset matrices std::fill(boneMatrices.begin(), boneMatrices.end(), SHMatrix::Identity); // Nothing to animate @@ -121,7 +128,15 @@ namespace SHADE currPlaybackTime += dt; if (currPlaybackTime > currClip->GetTotalTime()) { - currPlaybackTime = currPlaybackTime - currClip->GetTotalTime(); + if (playOnce) + { + playOnce = false; + isPlaying = false; + } + else + { + currPlaybackTime = currPlaybackTime - currClip->GetTotalTime(); + } } // Play the clip diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index b47106f8..01f1c2eb 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -54,9 +54,14 @@ namespace SHADE /// /// Plays the specified animation clip from the start. /// - /// + /// Animation clip to play. void Play(Handle clip); /// + /// Plays the specified animation clip from the start one time only. + /// + /// Animation clip to play. + void PlayOneShot(Handle clip); + /// /// Plays the currently loaded animation clip from the start. /// void PlayFromStart(); @@ -130,6 +135,7 @@ namespace SHADE // Playback Tracking float currPlaybackTime = 0.0f; bool isPlaying = true; + bool playOnce = false; // Useful Cached Data float secsPerTick = 0.0f; // Buffer From ba226385206ec04719fe61d1d1686744c4b7cb6b Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 27 Feb 2023 16:17:36 +0800 Subject: [PATCH 03/69] Renamed SHAnimationClip to SHAnimationData --- .../src/Application/SBApplication.cpp | 2 +- .../src/Animation/SHAnimationController.h | 4 ++-- .../{SHAnimationClip.cpp => SHAnimationData.cpp} | 8 ++++---- .../{SHAnimationClip.h => SHAnimationData.h} | 8 ++++---- SHADE_Engine/src/Animation/SHAnimationSystem.h | 1 + .../src/Animation/SHAnimatorComponent.cpp | 8 ++++---- SHADE_Engine/src/Animation/SHAnimatorComponent.h | 16 ++++++++-------- .../src/Animation/SHAnimatorComponent.hpp | 2 +- .../Inspector/SHEditorComponentView.hpp | 14 +++++++------- SHADE_Engine/src/Resource/SHResourceManager.h | 4 ++-- SHADE_Engine/src/Resource/SHResourceManager.hpp | 4 ++-- .../src/Serialization/SHYAMLConverters.h | 4 ++-- 12 files changed, 38 insertions(+), 37 deletions(-) rename SHADE_Engine/src/Animation/{SHAnimationClip.cpp => SHAnimationData.cpp} (95%) rename SHADE_Engine/src/Animation/{SHAnimationClip.h => SHAnimationData.h} (94%) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 3ebcc904..b5e4ef04 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -181,7 +181,7 @@ namespace Sandbox // Link up SHDebugDraw SHDebugDraw::Init(SHSystemManager::GetSystem()); - auto clip = SHResourceManager::LoadOrGet(77816045); + auto clip = SHResourceManager::LoadOrGet(77816045); auto rig = SHResourceManager::LoadOrGet(77816045); int i = 0; } diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index c6d353e6..29c8226d 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SH_API.h" #include "Resource/SHHandle.h" -#include "SHAnimationClip.h" +#include "SHAnimationData.h" namespace SHADE { @@ -100,7 +100,7 @@ namespace SHADE /// struct Node { - Handle Clip; + Handle Clip; std::vector Transitions; }; diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.cpp b/SHADE_Engine/src/Animation/SHAnimationData.cpp similarity index 95% rename from SHADE_Engine/src/Animation/SHAnimationClip.cpp rename to SHADE_Engine/src/Animation/SHAnimationData.cpp index 939275d3..07454e4a 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationData.cpp @@ -1,9 +1,9 @@ /************************************************************************************//*! -\file SHAnimationClip.cpp +\file SHAnimationData.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. +\brief Contains the function definitions of the SHAnimationData class. Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or disclosure of this file or its contents without the prior written consent @@ -12,14 +12,14 @@ of DigiPen Institute of Technology is prohibited. // Pre-compiled Header #include "SHpch.h" // Primary Header -#include "SHAnimationClip.h" +#include "SHAnimationData.h" namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------------------*/ - SHAnimationClip::SHAnimationClip(const SHAnimAsset& asset) + SHAnimationData::SHAnimationData(const SHAnimAsset& asset) : ticksPerSecond { static_cast(asset.ticksPerSecond) } , totalTime { static_cast(asset.duration) / static_cast(asset.ticksPerSecond) } { diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationData.h similarity index 94% rename from SHADE_Engine/src/Animation/SHAnimationClip.h rename to SHADE_Engine/src/Animation/SHAnimationData.h index 8a10ce3a..d770fc0f 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationData.h @@ -1,9 +1,9 @@ /************************************************************************************//*! -\file SHAnimationClip.h +\file SHAnimationData.h \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Dec 12, 2022 -\brief Contains the definition of the SHAnimationClip struct and related types. +\brief Contains the definition of the SHAnimationData struct and related types. Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or disclosure of this file or its contents without the prior written consent @@ -35,7 +35,7 @@ namespace SHADE /// Represents a animation clip of a 3D animation that is made for a specific model /// rig. /// - class SH_API SHAnimationClip + class SH_API SHAnimationData { public: /*---------------------------------------------------------------------------------*/ @@ -60,7 +60,7 @@ namespace SHADE /// Constructs an SHAnimation Clip from a specified SHAnimAsset. /// /// Animation asset to load. - explicit SHAnimationClip(const SHAnimAsset& asset); + explicit SHAnimationData(const SHAnimAsset& asset); /*---------------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Animation/SHAnimationSystem.h b/SHADE_Engine/src/Animation/SHAnimationSystem.h index 81b012d3..9c2cd073 100644 --- a/SHADE_Engine/src/Animation/SHAnimationSystem.h +++ b/SHADE_Engine/src/Animation/SHAnimationSystem.h @@ -15,6 +15,7 @@ of DigiPen Institute of Technology is prohibited. #include "SH_API.h" #include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystemRoutine.h" +#include "Resource/SHResourceLibrary.h" namespace SHADE { diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 5a6e78ce..6bb42576 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -19,7 +19,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SHRig.h" #include "Math/SHMatrix.h" -#include "SHAnimationClip.h" +#include "SHAnimationData.h" #include "Graphics/SHVkUtil.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "ECS_Base/Managers/SHSystemManager.h" @@ -37,14 +37,14 @@ namespace SHADE playOnce = false; } - void SHAnimatorComponent::Play(Handle clip) + void SHAnimatorComponent::Play(Handle clip) { currClip = clip; currPlaybackTime = 0.0f; Play(); } - void SHAnimatorComponent::PlayOneShot(Handle clip) + void SHAnimatorComponent::PlayOneShot(Handle clip) { Play(clip); playOnce = true; @@ -86,7 +86,7 @@ namespace SHADE } } - void SHAnimatorComponent::SetClip(Handle newClip) + void SHAnimatorComponent::SetClip(Handle newClip) { // No change if (currClip == newClip) diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index 01f1c2eb..c23ada1e 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -22,7 +22,7 @@ of DigiPen Institute of Technology is prohibited. #include "Math/SHMatrix.h" #include "Math/Vector/SHVec3.h" #include "Math/SHQuaternion.h" -#include "SHAnimationClip.h" +#include "SHAnimationData.h" namespace SHADE { @@ -31,7 +31,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ class SHRig; struct SHRigNode; - class SHAnimationClip; + class SHAnimationData; class SHVkBuffer; /*-----------------------------------------------------------------------------------*/ @@ -55,12 +55,12 @@ namespace SHADE /// Plays the specified animation clip from the start. /// /// Animation clip to play. - void Play(Handle clip); + void Play(Handle clip); /// /// Plays the specified animation clip from the start one time only. /// /// Animation clip to play. - void PlayOneShot(Handle clip); + void PlayOneShot(Handle clip); /// /// Plays the currently loaded animation clip from the start. /// @@ -88,7 +88,7 @@ namespace SHADE /// If the clip is the same as the current clip, nothing happens. /// /// Clip to use. - void SetClip(Handle newClip); + void SetClip(Handle newClip); /*---------------------------------------------------------------------------------*/ /* Getter Functions */ @@ -108,7 +108,7 @@ namespace SHADE /// Retrieve the currently set animation clip. /// /// Handle to the currently set animation clip. - Handle GetCurrentClip() const noexcept { return currClip; } + Handle GetCurrentClip() const noexcept { return currClip; } /// /// Checks if an animation is currently playing. /// @@ -131,7 +131,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ // Resources Handle rig; - Handle currClip; + Handle currClip; // Playback Tracking float currPlaybackTime = 0.0f; bool isPlaying = true; @@ -141,7 +141,7 @@ namespace SHADE // Buffer std::vector boneMatrices; // Caches - std::unordered_map channelMap; + std::unordered_map channelMap; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp index 9c6a5d3a..cf8f573b 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp @@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SHRig.h" #include "Math/SHMatrix.h" -#include "SHAnimationClip.h" +#include "SHAnimationData.h" #include "Graphics/SHVkUtil.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "ECS_Base/Managers/SHSystemManager.h" diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 561adcf4..ad91a9a1 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -644,13 +644,13 @@ namespace SHADE SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); } } - Handle const& clip = component->GetCurrentClip(); - const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName(clip).value_or("") : ""; + Handle const& clip = component->GetCurrentClip(); + const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName(clip).value_or("") : ""; SHEditorWidgets::DragDropReadOnlyField("Clip", CLIP_NAME, [component]() { - Handle const& clip = component->GetCurrentClip(); - return SHResourceManager::GetAssetID(clip).value_or(0); + Handle const& clip = component->GetCurrentClip(); + return SHResourceManager::GetAssetID(clip).value_or(0); }, [component](AssetID const& id) { @@ -659,13 +659,13 @@ namespace SHADE SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!") return; } - component->SetClip(SHResourceManager::LoadOrGet(id)); + component->SetClip(SHResourceManager::LoadOrGet(id)); }, SHDragDrop::DRAG_RESOURCE); if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { - if (Handle const& clip = component->GetCurrentClip()) + if (Handle const& clip = component->GetCurrentClip()) { - AssetID assetID = SHResourceManager::GetAssetID(clip).value_or(0); + AssetID assetID = SHResourceManager::GetAssetID(clip).value_or(0); SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); } } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index 4188bde9..499ded4b 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -28,7 +28,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Assets/Asset Types/SHMaterialAsset.h" #include "Graphics/MiddleEnd/TextRendering/SHFont.h" -#include "Animation/SHAnimationClip.h" +#include "Animation/SHAnimationData.h" #include "Animation/SHRig.h" namespace SHADE @@ -53,7 +53,7 @@ namespace SHADE template<> struct SHResourceLoader { using AssetType = SHMaterialAsset; }; template<> struct SHResourceLoader { using AssetType = SHMaterialSpec; }; template<> struct SHResourceLoader { using AssetType = SHFontAsset; }; - template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; + template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; /// diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index 231615a5..82a4eb01 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -41,7 +41,7 @@ namespace SHADE !std::is_same_v && !std::is_same_v && !std::is_same_v && - !std::is_same_v && + !std::is_same_v && !std::is_same_v ) { @@ -355,7 +355,7 @@ namespace SHADE loadedAssetData.emplace_back(assetId); return resourceHub.Create(assetData.rig, rigNodeStore); } - else if constexpr (std::is_same_v) + else if constexpr (std::is_same_v) { loadedAssetData.emplace_back(assetId); return resourceHub.Create(*assetData.anims[0]); diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index 9fceb10d..658faddc 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -400,7 +400,7 @@ namespace YAML { YAML::Node node; node[RIG_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetRig()).value_or(0); - node[CLIP_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetCurrentClip()).value_or(0); + node[CLIP_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetCurrentClip()).value_or(0); return node; } static bool decode(YAML::Node const& node, SHAnimatorComponent& rhs) @@ -411,7 +411,7 @@ namespace YAML } if (node[CLIP_YAML_TAG.data()].IsDefined()) { - rhs.SetClip(SHResourceManager::LoadOrGet(node[CLIP_YAML_TAG.data()].as())); + rhs.SetClip(SHResourceManager::LoadOrGet(node[CLIP_YAML_TAG.data()].as())); } return true; } From 7839bd21f208a5e86396fd899168d7b27f9dbd52 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 27 Feb 2023 16:51:02 +0800 Subject: [PATCH 04/69] Renamed SHAnimationData to SHRawAnimation --- .../src/Application/SBApplication.cpp | 2 +- .../src/Animation/SHAnimationController.h | 4 ++-- .../src/Animation/SHAnimatorComponent.cpp | 8 ++++---- SHADE_Engine/src/Animation/SHAnimatorComponent.h | 16 ++++++++-------- .../src/Animation/SHAnimatorComponent.hpp | 2 +- .../{SHAnimationData.cpp => SHRawAnimation.cpp} | 4 ++-- .../{SHAnimationData.h => SHRawAnimation.h} | 4 ++-- .../Inspector/SHEditorComponentView.hpp | 14 +++++++------- SHADE_Engine/src/Resource/SHResourceManager.h | 4 ++-- SHADE_Engine/src/Resource/SHResourceManager.hpp | 4 ++-- .../src/Serialization/SHYAMLConverters.h | 4 ++-- 11 files changed, 33 insertions(+), 33 deletions(-) rename SHADE_Engine/src/Animation/{SHAnimationData.cpp => SHRawAnimation.cpp} (96%) rename SHADE_Engine/src/Animation/{SHAnimationData.h => SHRawAnimation.h} (97%) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index b5e4ef04..5c9bd2c8 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -181,7 +181,7 @@ namespace Sandbox // Link up SHDebugDraw SHDebugDraw::Init(SHSystemManager::GetSystem()); - auto clip = SHResourceManager::LoadOrGet(77816045); + auto clip = SHResourceManager::LoadOrGet(77816045); auto rig = SHResourceManager::LoadOrGet(77816045); int i = 0; } diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index 29c8226d..b06065ed 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SH_API.h" #include "Resource/SHHandle.h" -#include "SHAnimationData.h" +#include "SHRawAnimation.h" namespace SHADE { @@ -100,7 +100,7 @@ namespace SHADE /// struct Node { - Handle Clip; + Handle Clip; std::vector Transitions; }; diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 6bb42576..63cec09c 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -19,7 +19,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SHRig.h" #include "Math/SHMatrix.h" -#include "SHAnimationData.h" +#include "SHRawAnimation.h" #include "Graphics/SHVkUtil.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "ECS_Base/Managers/SHSystemManager.h" @@ -37,14 +37,14 @@ namespace SHADE playOnce = false; } - void SHAnimatorComponent::Play(Handle clip) + void SHAnimatorComponent::Play(Handle clip) { currClip = clip; currPlaybackTime = 0.0f; Play(); } - void SHAnimatorComponent::PlayOneShot(Handle clip) + void SHAnimatorComponent::PlayOneShot(Handle clip) { Play(clip); playOnce = true; @@ -86,7 +86,7 @@ namespace SHADE } } - void SHAnimatorComponent::SetClip(Handle newClip) + void SHAnimatorComponent::SetClip(Handle newClip) { // No change if (currClip == newClip) diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index c23ada1e..feec443d 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -22,7 +22,7 @@ of DigiPen Institute of Technology is prohibited. #include "Math/SHMatrix.h" #include "Math/Vector/SHVec3.h" #include "Math/SHQuaternion.h" -#include "SHAnimationData.h" +#include "SHRawAnimation.h" namespace SHADE { @@ -31,7 +31,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ class SHRig; struct SHRigNode; - class SHAnimationData; + class SHRawAnimation; class SHVkBuffer; /*-----------------------------------------------------------------------------------*/ @@ -55,12 +55,12 @@ namespace SHADE /// Plays the specified animation clip from the start. /// /// Animation clip to play. - void Play(Handle clip); + void Play(Handle clip); /// /// Plays the specified animation clip from the start one time only. /// /// Animation clip to play. - void PlayOneShot(Handle clip); + void PlayOneShot(Handle clip); /// /// Plays the currently loaded animation clip from the start. /// @@ -88,7 +88,7 @@ namespace SHADE /// If the clip is the same as the current clip, nothing happens. /// /// Clip to use. - void SetClip(Handle newClip); + void SetClip(Handle newClip); /*---------------------------------------------------------------------------------*/ /* Getter Functions */ @@ -108,7 +108,7 @@ namespace SHADE /// Retrieve the currently set animation clip. /// /// Handle to the currently set animation clip. - Handle GetCurrentClip() const noexcept { return currClip; } + Handle GetCurrentClip() const noexcept { return currClip; } /// /// Checks if an animation is currently playing. /// @@ -131,7 +131,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ // Resources Handle rig; - Handle currClip; + Handle currClip; // Playback Tracking float currPlaybackTime = 0.0f; bool isPlaying = true; @@ -141,7 +141,7 @@ namespace SHADE // Buffer std::vector boneMatrices; // Caches - std::unordered_map channelMap; + std::unordered_map channelMap; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp index cf8f573b..e8c52073 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp @@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SHRig.h" #include "Math/SHMatrix.h" -#include "SHAnimationData.h" +#include "SHRawAnimation.h" #include "Graphics/SHVkUtil.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "ECS_Base/Managers/SHSystemManager.h" diff --git a/SHADE_Engine/src/Animation/SHAnimationData.cpp b/SHADE_Engine/src/Animation/SHRawAnimation.cpp similarity index 96% rename from SHADE_Engine/src/Animation/SHAnimationData.cpp rename to SHADE_Engine/src/Animation/SHRawAnimation.cpp index 07454e4a..5a39fb08 100644 --- a/SHADE_Engine/src/Animation/SHAnimationData.cpp +++ b/SHADE_Engine/src/Animation/SHRawAnimation.cpp @@ -12,14 +12,14 @@ of DigiPen Institute of Technology is prohibited. // Pre-compiled Header #include "SHpch.h" // Primary Header -#include "SHAnimationData.h" +#include "SHRawAnimation.h" namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------------------*/ - SHAnimationData::SHAnimationData(const SHAnimAsset& asset) + SHRawAnimation::SHRawAnimation(const SHAnimAsset& asset) : ticksPerSecond { static_cast(asset.ticksPerSecond) } , totalTime { static_cast(asset.duration) / static_cast(asset.ticksPerSecond) } { diff --git a/SHADE_Engine/src/Animation/SHAnimationData.h b/SHADE_Engine/src/Animation/SHRawAnimation.h similarity index 97% rename from SHADE_Engine/src/Animation/SHAnimationData.h rename to SHADE_Engine/src/Animation/SHRawAnimation.h index d770fc0f..05d95238 100644 --- a/SHADE_Engine/src/Animation/SHAnimationData.h +++ b/SHADE_Engine/src/Animation/SHRawAnimation.h @@ -35,7 +35,7 @@ namespace SHADE /// Represents a animation clip of a 3D animation that is made for a specific model /// rig. /// - class SH_API SHAnimationData + class SH_API SHRawAnimation { public: /*---------------------------------------------------------------------------------*/ @@ -60,7 +60,7 @@ namespace SHADE /// Constructs an SHAnimation Clip from a specified SHAnimAsset. /// /// Animation asset to load. - explicit SHAnimationData(const SHAnimAsset& asset); + explicit SHRawAnimation(const SHAnimAsset& asset); /*---------------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index ad91a9a1..7f6192f1 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -644,13 +644,13 @@ namespace SHADE SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); } } - Handle const& clip = component->GetCurrentClip(); - const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName(clip).value_or("") : ""; + Handle const& clip = component->GetCurrentClip(); + const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName(clip).value_or("") : ""; SHEditorWidgets::DragDropReadOnlyField("Clip", CLIP_NAME, [component]() { - Handle const& clip = component->GetCurrentClip(); - return SHResourceManager::GetAssetID(clip).value_or(0); + Handle const& clip = component->GetCurrentClip(); + return SHResourceManager::GetAssetID(clip).value_or(0); }, [component](AssetID const& id) { @@ -659,13 +659,13 @@ namespace SHADE SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!") return; } - component->SetClip(SHResourceManager::LoadOrGet(id)); + component->SetClip(SHResourceManager::LoadOrGet(id)); }, SHDragDrop::DRAG_RESOURCE); if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { - if (Handle const& clip = component->GetCurrentClip()) + if (Handle const& clip = component->GetCurrentClip()) { - AssetID assetID = SHResourceManager::GetAssetID(clip).value_or(0); + AssetID assetID = SHResourceManager::GetAssetID(clip).value_or(0); SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); } } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index 499ded4b..e3766cf0 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -28,7 +28,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Assets/Asset Types/SHMaterialAsset.h" #include "Graphics/MiddleEnd/TextRendering/SHFont.h" -#include "Animation/SHAnimationData.h" +#include "Animation/SHRawAnimation.h" #include "Animation/SHRig.h" namespace SHADE @@ -53,7 +53,7 @@ namespace SHADE template<> struct SHResourceLoader { using AssetType = SHMaterialAsset; }; template<> struct SHResourceLoader { using AssetType = SHMaterialSpec; }; template<> struct SHResourceLoader { using AssetType = SHFontAsset; }; - template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; + template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; /// diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index 82a4eb01..a53249f7 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -41,7 +41,7 @@ namespace SHADE !std::is_same_v && !std::is_same_v && !std::is_same_v && - !std::is_same_v && + !std::is_same_v && !std::is_same_v ) { @@ -355,7 +355,7 @@ namespace SHADE loadedAssetData.emplace_back(assetId); return resourceHub.Create(assetData.rig, rigNodeStore); } - else if constexpr (std::is_same_v) + else if constexpr (std::is_same_v) { loadedAssetData.emplace_back(assetId); return resourceHub.Create(*assetData.anims[0]); diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index 658faddc..132e44b5 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -400,7 +400,7 @@ namespace YAML { YAML::Node node; node[RIG_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetRig()).value_or(0); - node[CLIP_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetCurrentClip()).value_or(0); + node[CLIP_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetCurrentClip()).value_or(0); return node; } static bool decode(YAML::Node const& node, SHAnimatorComponent& rhs) @@ -411,7 +411,7 @@ namespace YAML } if (node[CLIP_YAML_TAG.data()].IsDefined()) { - rhs.SetClip(SHResourceManager::LoadOrGet(node[CLIP_YAML_TAG.data()].as())); + rhs.SetClip(SHResourceManager::LoadOrGet(node[CLIP_YAML_TAG.data()].as())); } return true; } From f061e8ed43a39c0c205fd4c6045a199608152790 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 27 Feb 2023 16:52:41 +0800 Subject: [PATCH 05/69] Updated comments to use SHRawAnimation instead of SHAnimationData --- SHADE_Engine/src/Animation/SHRawAnimation.cpp | 4 ++-- SHADE_Engine/src/Animation/SHRawAnimation.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHRawAnimation.cpp b/SHADE_Engine/src/Animation/SHRawAnimation.cpp index 5a39fb08..86d0af18 100644 --- a/SHADE_Engine/src/Animation/SHRawAnimation.cpp +++ b/SHADE_Engine/src/Animation/SHRawAnimation.cpp @@ -1,9 +1,9 @@ /************************************************************************************//*! -\file SHAnimationData.cpp +\file SHRawAnimation.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 SHAnimationData class. +\brief Contains the function definitions of the SHRawAnimation class. Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or disclosure of this file or its contents without the prior written consent diff --git a/SHADE_Engine/src/Animation/SHRawAnimation.h b/SHADE_Engine/src/Animation/SHRawAnimation.h index 05d95238..cb1b0ebe 100644 --- a/SHADE_Engine/src/Animation/SHRawAnimation.h +++ b/SHADE_Engine/src/Animation/SHRawAnimation.h @@ -1,9 +1,9 @@ /************************************************************************************//*! -\file SHAnimationData.h +\file SHRawAnimation.h \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Dec 12, 2022 -\brief Contains the definition of the SHAnimationData struct and related types. +\brief Contains the definition of the SHRawAnimation struct and related types. Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or disclosure of this file or its contents without the prior written consent From 33b5b84fd4e41c5d0b8ccf28c750748ea98fd204 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 27 Feb 2023 17:04:16 +0800 Subject: [PATCH 06/69] add anim clip --- .../src/Animation/SHAnimationClip.cpp | 65 +++++++++++++++++++ SHADE_Engine/src/Animation/SHAnimationClip.h | 64 ++++++++++++++++++ .../src/Animation/SHAnimationController.h | 4 +- .../src/Animation/SHAnimatorComponent.cpp | 17 +++-- .../src/Animation/SHAnimatorComponent.h | 12 ++-- SHADE_Engine/src/Animation/SHRawAnimation.h | 3 +- 6 files changed, 149 insertions(+), 16 deletions(-) create mode 100644 SHADE_Engine/src/Animation/SHAnimationClip.cpp create mode 100644 SHADE_Engine/src/Animation/SHAnimationClip.h diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.cpp b/SHADE_Engine/src/Animation/SHAnimationClip.cpp new file mode 100644 index 00000000..86d0af18 --- /dev/null +++ b/SHADE_Engine/src/Animation/SHAnimationClip.cpp @@ -0,0 +1,65 @@ +/************************************************************************************//*! +\file SHRawAnimation.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 SHRawAnimation 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 "SHRawAnimation.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------------*/ + SHRawAnimation::SHRawAnimation(const SHAnimAsset& asset) + : ticksPerSecond { static_cast(asset.ticksPerSecond) } + , totalTime { static_cast(asset.duration) / static_cast(asset.ticksPerSecond) } + { + // Populate keyframes + for (const auto& channel : asset.nodeChannels) + { + // Create a channel + Channel newChannel; + newChannel.Name = std::string(channel.name); + newChannel.PositionKeyFrames.reserve(channel.positionKeys.size()); + newChannel.RotationKeyFrames.reserve(channel.rotationKeys.size()); + newChannel.ScaleKeyFrames.reserve(channel.scaleKeys.size()); + + // Populate Keyframes + for (const auto& posKey : channel.positionKeys) + { + newChannel.PositionKeyFrames.emplace_back(SHAnimationKeyFrame{ static_cast(posKey.time), posKey.value}); + } + for (const auto& rotKey : channel.rotationKeys) + { + newChannel.RotationKeyFrames.emplace_back(SHAnimationKeyFrame{ static_cast(rotKey.time), rotKey.value}); + } + for (const auto& scaleKey : channel.scaleKeys) + { + newChannel.ScaleKeyFrames.emplace_back(SHAnimationKeyFrame{ static_cast(scaleKey.time), scaleKey.value}); + } + + newChannel.MaxFrames = std::max({ newChannel.PositionKeyFrames.size(), newChannel.RotationKeyFrames.size(), newChannel.ScaleKeyFrames.size() }); + + // Insert the channel + channels.emplace_back(std::move(newChannel)); + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------------*/ + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h new file mode 100644 index 00000000..a6ec923f --- /dev/null +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -0,0 +1,64 @@ +/************************************************************************************//*! +\file SHAnimationClip.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Dec 12, 2022 +\brief Contains the definition of the SHAnimationClip struct and related types. + +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. +*//*************************************************************************************/ +#pragma once + +// Project Includes +#include "SH_API.h" +#include "Math/SHMatrix.h" +#include "Assets/Asset Types/Models/SHAnimationAsset.h" +#include "Resource/SHHandle.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + class SHRawAnimation; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + /// + /// Represents a snippet of 3D animation that is stored in a SHRawAnimation object. + /// + class SH_API SHAnimationClip + { + public: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + inline Handle GetRawAnimation() const noexcept { return rawAnim; } + inline float GetTotalTime() const noexcept { } + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + Handle rawAnim; + int startFrameIndex; // First Frame + int endFrameIndex; // Last Frame (inclusive) + float totalTime; // Time to take from first to last frame + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index b06065ed..c6d353e6 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SH_API.h" #include "Resource/SHHandle.h" -#include "SHRawAnimation.h" +#include "SHAnimationClip.h" namespace SHADE { @@ -100,7 +100,7 @@ namespace SHADE /// struct Node { - Handle Clip; + Handle Clip; std::vector Transitions; }; diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 63cec09c..2f886c75 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -19,7 +19,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SHRig.h" #include "Math/SHMatrix.h" -#include "SHRawAnimation.h" +#include "SHAnimationClip.h" #include "Graphics/SHVkUtil.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "ECS_Base/Managers/SHSystemManager.h" @@ -37,14 +37,14 @@ namespace SHADE playOnce = false; } - void SHAnimatorComponent::Play(Handle clip) + void SHAnimatorComponent::Play(Handle clip) { currClip = clip; currPlaybackTime = 0.0f; Play(); } - void SHAnimatorComponent::PlayOneShot(Handle clip) + void SHAnimatorComponent::PlayOneShot(Handle clip) { Play(clip); playOnce = true; @@ -86,7 +86,7 @@ namespace SHADE } } - void SHAnimatorComponent::SetClip(Handle newClip) + void SHAnimatorComponent::SetClip(Handle newClip) { // No change if (currClip == newClip) @@ -124,9 +124,14 @@ namespace SHADE if (!currClip || !isPlaying || !rig || !rig->GetRootNode()) return; + // Get animation data + auto animData = currClip->GetRawAnimation(); + if (!animData) + return; + // Update time on the playback currPlaybackTime += dt; - if (currPlaybackTime > currClip->GetTotalTime()) + if (currPlaybackTime > animData->GetTotalTime()) { if (playOnce) { @@ -135,7 +140,7 @@ namespace SHADE } else { - currPlaybackTime = currPlaybackTime - currClip->GetTotalTime(); + currPlaybackTime = currPlaybackTime - animData->GetTotalTime(); } } diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index feec443d..b5ea02b0 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -31,7 +31,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ class SHRig; struct SHRigNode; - class SHRawAnimation; + class SHAnimationClip; class SHVkBuffer; /*-----------------------------------------------------------------------------------*/ @@ -55,12 +55,12 @@ namespace SHADE /// Plays the specified animation clip from the start. /// /// Animation clip to play. - void Play(Handle clip); + void Play(Handle clip); /// /// Plays the specified animation clip from the start one time only. /// /// Animation clip to play. - void PlayOneShot(Handle clip); + void PlayOneShot(Handle clip); /// /// Plays the currently loaded animation clip from the start. /// @@ -88,7 +88,7 @@ namespace SHADE /// If the clip is the same as the current clip, nothing happens. /// /// Clip to use. - void SetClip(Handle newClip); + void SetClip(Handle newClip); /*---------------------------------------------------------------------------------*/ /* Getter Functions */ @@ -108,7 +108,7 @@ namespace SHADE /// Retrieve the currently set animation clip. /// /// Handle to the currently set animation clip. - Handle GetCurrentClip() const noexcept { return currClip; } + Handle GetCurrentClip() const noexcept { return currClip; } /// /// Checks if an animation is currently playing. /// @@ -131,7 +131,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ // Resources Handle rig; - Handle currClip; + Handle currClip; // Playback Tracking float currPlaybackTime = 0.0f; bool isPlaying = true; diff --git a/SHADE_Engine/src/Animation/SHRawAnimation.h b/SHADE_Engine/src/Animation/SHRawAnimation.h index cb1b0ebe..ee5d3769 100644 --- a/SHADE_Engine/src/Animation/SHRawAnimation.h +++ b/SHADE_Engine/src/Animation/SHRawAnimation.h @@ -32,8 +32,7 @@ namespace SHADE }; /// - /// Represents a animation clip of a 3D animation that is made for a specific model - /// rig. + /// Represents the raw 3D animation data for a rigged 3D model. /// class SH_API SHRawAnimation { From 36af939c6714fe509ce5450158906bc68b8c7ea4 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 28 Feb 2023 19:19:06 +0800 Subject: [PATCH 07/69] Added reworked AnimationClip and SHAnimClipAsset --- .../src/Animation/SHAnimationClip.cpp | 58 ++++--------------- SHADE_Engine/src/Animation/SHAnimationClip.h | 26 ++++----- .../src/Animation/SHAnimatorComponent.cpp | 26 ++++++--- .../src/Animation/SHAnimatorComponent.h | 1 + .../src/Assets/Asset Types/SHAnimClipAsset.h | 28 +++++++++ .../Inspector/SHEditorComponentView.hpp | 10 ++-- SHADE_Engine/src/Resource/SHResourceManager.h | 7 ++- .../src/Resource/SHResourceManager.hpp | 11 ++++ .../src/Serialization/SHYAMLConverters.h | 4 +- 9 files changed, 94 insertions(+), 77 deletions(-) create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.cpp b/SHADE_Engine/src/Animation/SHAnimationClip.cpp index 86d0af18..2678b95b 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationClip.cpp @@ -1,65 +1,27 @@ /************************************************************************************//*! -\file SHRawAnimation.cpp +\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 SHRawAnimation class. +\date Feb 27, 2023 +\brief Contains the function definitions of the SHAnimationClip class. -Copyright (C) 2022 DigiPen Institute of Technology. +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. *//*************************************************************************************/ // Pre-compiled Header #include "SHpch.h" // Primary Header -#include "SHRawAnimation.h" +#include "SHAnimationClip.h" namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------------------*/ - SHRawAnimation::SHRawAnimation(const SHAnimAsset& asset) - : ticksPerSecond { static_cast(asset.ticksPerSecond) } - , totalTime { static_cast(asset.duration) / static_cast(asset.ticksPerSecond) } - { - // Populate keyframes - for (const auto& channel : asset.nodeChannels) - { - // Create a channel - Channel newChannel; - newChannel.Name = std::string(channel.name); - newChannel.PositionKeyFrames.reserve(channel.positionKeys.size()); - newChannel.RotationKeyFrames.reserve(channel.rotationKeys.size()); - newChannel.ScaleKeyFrames.reserve(channel.scaleKeys.size()); - - // Populate Keyframes - for (const auto& posKey : channel.positionKeys) - { - newChannel.PositionKeyFrames.emplace_back(SHAnimationKeyFrame{ static_cast(posKey.time), posKey.value}); - } - for (const auto& rotKey : channel.rotationKeys) - { - newChannel.RotationKeyFrames.emplace_back(SHAnimationKeyFrame{ static_cast(rotKey.time), rotKey.value}); - } - for (const auto& scaleKey : channel.scaleKeys) - { - newChannel.ScaleKeyFrames.emplace_back(SHAnimationKeyFrame{ static_cast(scaleKey.time), scaleKey.value}); - } - - newChannel.MaxFrames = std::max({ newChannel.PositionKeyFrames.size(), newChannel.RotationKeyFrames.size(), newChannel.ScaleKeyFrames.size() }); - - // Insert the channel - channels.emplace_back(std::move(newChannel)); - } - } - - /*-----------------------------------------------------------------------------------*/ - /* Usage Functions */ - /*-----------------------------------------------------------------------------------*/ - - /*-----------------------------------------------------------------------------------*/ - /* Helper Functions */ - /*-----------------------------------------------------------------------------------*/ - + SHAnimationClip::SHAnimationClip(Handle rawAnimHandle, int firstFrame, int lastFrame) + : rawAnim { rawAnimHandle } + , startFrameIndex { firstFrame } + , endFrameIndex { lastFrame } + {} } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h index a6ec923f..547acf92 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -2,10 +2,10 @@ \file SHAnimationClip.h \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu -\date Dec 12, 2022 +\date Feb 27, 2023 \brief Contains the definition of the SHAnimationClip struct and related types. -Copyright (C) 2022 DigiPen Institute of Technology. +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. *//*************************************************************************************/ @@ -33,19 +33,23 @@ namespace SHADE class SH_API SHAnimationClip { public: - /*---------------------------------------------------------------------------------*/ - /* Type Definitions */ - /*---------------------------------------------------------------------------------*/ - /*---------------------------------------------------------------------------------*/ /* Constructors */ /*---------------------------------------------------------------------------------*/ - + /// + /// Constructs an animation clip that contains the following parameters. + /// + /// Handle to the raw animation data. + /// First frame to be played. + /// Last frame to be played. + SHAnimationClip(Handle rawAnimHandle, int firstFrame, int lastFrame); + /*---------------------------------------------------------------------------------*/ /* Getter Functions */ /*---------------------------------------------------------------------------------*/ inline Handle GetRawAnimation() const noexcept { return rawAnim; } - inline float GetTotalTime() const noexcept { } + inline int GetStartFrameIndex() const noexcept { return startFrameIndex; } + inline int GetEndFrameIndex() const noexcept { return endFrameIndex; } private: /*---------------------------------------------------------------------------------*/ @@ -54,11 +58,5 @@ namespace SHADE Handle rawAnim; int startFrameIndex; // First Frame int endFrameIndex; // Last Frame (inclusive) - float totalTime; // Time to take from first to last frame - - /*---------------------------------------------------------------------------------*/ - /* Helper Functions */ - /*---------------------------------------------------------------------------------*/ - }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 2f886c75..eee7fd51 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -92,15 +92,27 @@ namespace SHADE if (currClip == newClip) return; + // Get animation data + auto animData = currClip->GetRawAnimation(); + if (!animData) + return; + // Set parameters currClip = newClip; - secsPerTick = 1.0f / currClip->GetTicksPerSecond(); + secsPerTick = 1.0f / animData->GetTicksPerSecond(); - // Build channel map - channelMap.clear(); + // Calculate total time for the clip if (currClip) { - for (const auto& channel : currClip->GetChannels()) + const int ONE_PAST_LAST_FRAME = currClip->GetEndFrameIndex() + 1; + currClipTotalTime = (ONE_PAST_LAST_FRAME - currClip->GetStartFrameIndex()) / animData->GetTicksPerSecond(); + } + + // Build channel map and clip-specific data + channelMap.clear(); + if (animData) + { + for (const auto& channel : animData->GetChannels()) { channelMap.emplace(channel.Name, &channel); } @@ -131,7 +143,7 @@ namespace SHADE // Update time on the playback currPlaybackTime += dt; - if (currPlaybackTime > animData->GetTotalTime()) + if (currPlaybackTime > currClipTotalTime) { if (playOnce) { @@ -140,7 +152,7 @@ namespace SHADE } else { - currPlaybackTime = currPlaybackTime - animData->GetTotalTime(); + currPlaybackTime = currPlaybackTime - currClipTotalTime; } } @@ -154,7 +166,7 @@ namespace SHADE void SHAnimatorComponent::updatePoseWithClip(float poseTime) { // Get closest frame index - const int CLOSEST_FRAME_IDX = static_cast(std::floorf(poseTime * currClip->GetTicksPerSecond())); + const int CLOSEST_FRAME_IDX = currClip->GetStartFrameIndex() + static_cast(std::floorf(poseTime * currClip->GetRawAnimation()->GetTicksPerSecond())); updatePoseWithClip(CLOSEST_FRAME_IDX, poseTime, rig->GetRootNode(), SHMatrix::Identity); } diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index b5ea02b0..12d377fe 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -136,6 +136,7 @@ namespace SHADE float currPlaybackTime = 0.0f; bool isPlaying = true; bool playOnce = false; + float currClipTotalTime = 0.0f; // Useful Cached Data float secsPerTick = 0.0f; // Buffer diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h new file mode 100644 index 00000000..a1bd87a6 --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h @@ -0,0 +1,28 @@ +/************************************************************************************//*! +\file SHAnimClipAsset.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Feb 27, 2023 +\brief Contains the definition of the SHAnimationClip struct 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 + +#include + +#include "SH_API.h" +#include "SHAssetData.h" + +namespace SHADE +{ + struct SH_API SHAnimClipAsset : SHAssetData + { + std::string name; + AssetID animRawDataAssetId; + int firstIndex; + int lastIndex; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 7f6192f1..3ceb7166 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -27,6 +27,8 @@ #include "Physics/Collision/Shapes/SHSphere.h" #include "../SHEditorWindowManager.h" #include "../AssetBrowser/SHAssetBrowser.h" +#include "Animation/SHAnimationClip.h" + namespace SHADE { template @@ -644,12 +646,12 @@ namespace SHADE SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); } } - Handle const& clip = component->GetCurrentClip(); + Handle const clip = (component->GetCurrentClip() ? component->GetCurrentClip()->GetRawAnimation() : Handle{}); const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName(clip).value_or("") : ""; SHEditorWidgets::DragDropReadOnlyField("Clip", CLIP_NAME, [component]() { - Handle const& clip = component->GetCurrentClip(); + Handle const clip = (component->GetCurrentClip() ? component->GetCurrentClip()->GetRawAnimation() : Handle{}); return SHResourceManager::GetAssetID(clip).value_or(0); }, [component](AssetID const& id) @@ -659,11 +661,11 @@ namespace SHADE SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!") return; } - component->SetClip(SHResourceManager::LoadOrGet(id)); + component->SetClip(SHResourceManager::LoadOrGet(id)); }, SHDragDrop::DRAG_RESOURCE); if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { - if (Handle const& clip = component->GetCurrentClip()) + if (Handle const clip = component->GetCurrentClip()->GetRawAnimation()) { AssetID assetID = SHResourceManager::GetAssetID(clip).value_or(0); SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index e3766cf0..1f26bf2a 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -21,6 +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 "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" #include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h" @@ -38,6 +39,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ class SHMaterial; struct SHRigNode; + class SHAnimationClip; /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -53,8 +55,9 @@ namespace SHADE template<> struct SHResourceLoader { using AssetType = SHMaterialAsset; }; template<> struct SHResourceLoader { using AssetType = SHMaterialSpec; }; template<> struct SHResourceLoader { using AssetType = SHFontAsset; }; - template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; - template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; + template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; + template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; + template<> struct SHResourceLoader { using AssetType = SHAnimClipAsset; }; /// /// Static class responsible for loading and caching runtime resources from their diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index a53249f7..da557748 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -25,6 +25,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Serialization/SHYAMLConverters.h" +#include "Animation/SHAnimationClip.h" namespace SHADE { @@ -360,5 +361,15 @@ namespace SHADE loadedAssetData.emplace_back(assetId); return resourceHub.Create(*assetData.anims[0]); } + else if constexpr (std::is_same_v) + { + loadedAssetData.emplace_back(assetId); + return resourceHub.Create + ( + LoadOrGet(assetData->animRawDataAssetId), + assetData->firstIndex, + assetData->lastIndex + ); + } } } diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index 132e44b5..9fceb10d 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -400,7 +400,7 @@ namespace YAML { YAML::Node node; node[RIG_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetRig()).value_or(0); - node[CLIP_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetCurrentClip()).value_or(0); + node[CLIP_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetCurrentClip()).value_or(0); return node; } static bool decode(YAML::Node const& node, SHAnimatorComponent& rhs) @@ -411,7 +411,7 @@ namespace YAML } if (node[CLIP_YAML_TAG.data()].IsDefined()) { - rhs.SetClip(SHResourceManager::LoadOrGet(node[CLIP_YAML_TAG.data()].as())); + rhs.SetClip(SHResourceManager::LoadOrGet(node[CLIP_YAML_TAG.data()].as())); } return true; } From e97f5747cba58ab9fcea84102226fef7496eefd0 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 1 Mar 2023 01:30:34 +0800 Subject: [PATCH 08/69] Modified SHAnimatorComponent to support manual and animation controller modes. Fleshed out SHAnimationController. Added SHAnimControllerAsset stub. --- .../src/Animation/SHAnimationClip.cpp | 12 +- SHADE_Engine/src/Animation/SHAnimationClip.h | 2 + .../src/Animation/SHAnimationController.cpp | 44 +++- .../src/Animation/SHAnimationController.h | 50 ++-- .../src/Animation/SHAnimatorComponent.cpp | 231 +++++++++++++----- .../src/Animation/SHAnimatorComponent.h | 71 +++--- .../Asset Types/SHAnimControllerAsset.h | 27 ++ SHADE_Engine/src/Assets/SHAssetMacros.h | 40 +-- .../Inspector/SHEditorComponentView.hpp | 25 -- SHADE_Engine/src/Resource/SHResourceManager.h | 23 +- .../src/Resource/SHResourceManager.hpp | 28 ++- .../src/Serialization/SHYAMLConverters.h | 8 +- 12 files changed, 374 insertions(+), 187 deletions(-) create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHAnimControllerAsset.h diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.cpp b/SHADE_Engine/src/Animation/SHAnimationClip.cpp index 2678b95b..130503af 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationClip.cpp @@ -13,6 +13,7 @@ of DigiPen Institute of Technology is prohibited. #include "SHpch.h" // Primary Header #include "SHAnimationClip.h" +#include "SHRawAnimation.h" namespace SHADE { @@ -20,8 +21,15 @@ namespace SHADE /* Constructors */ /*-----------------------------------------------------------------------------------*/ SHAnimationClip::SHAnimationClip(Handle rawAnimHandle, int firstFrame, int lastFrame) - : rawAnim { rawAnimHandle } + : rawAnim { rawAnimHandle } , startFrameIndex { firstFrame } , endFrameIndex { lastFrame } - {} + , duration { 0.0f } + { + if (!rawAnim) + return; + + const int ONE_PAST_LAST_FRAME = lastFrame + 1; + duration = (ONE_PAST_LAST_FRAME - firstFrame) / rawAnim->GetTicksPerSecond(); + } } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h index 547acf92..9b93a7a3 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -50,6 +50,7 @@ namespace SHADE inline Handle GetRawAnimation() const noexcept { return rawAnim; } inline int GetStartFrameIndex() const noexcept { return startFrameIndex; } inline int GetEndFrameIndex() const noexcept { return endFrameIndex; } + inline float GetTotalDuration() const noexcept { return duration; } private: /*---------------------------------------------------------------------------------*/ @@ -58,5 +59,6 @@ namespace SHADE Handle rawAnim; int startFrameIndex; // First Frame int endFrameIndex; // Last Frame (inclusive) + float duration; // Total playback time }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 86c665fd..3230b2d9 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -20,22 +20,28 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*-----------------------------------------------------------------------------------*/ - void SHAnimationController::Update() + void SHAnimationController::Update(InstanceData& instData, float dt) { // Is there a valid node - if (!currentNode) + if (!instData.CurrentNode) return; - // Update - for (const auto& transition : currentNode->Transitions) - { + // Update the current playback + instData.ClipPlaybackTime += dt; + // Check if we finished playing + if (instData.ClipPlaybackTime > instData.CurrentNode->Clip->GetTotalDuration()) + { + // Clamp + instData.ClipPlaybackTime = instData.CurrentNode->Clip->GetTotalDuration(); + + // Go to next state + for (const auto& transition : instData.CurrentNode->Transitions) + { + // TODO + } } } - void SHAnimationController::Reset() - { - currentNode = startNode; - } /*-----------------------------------------------------------------------------------*/ /* Usage Functions */ @@ -75,4 +81,24 @@ namespace SHADE // Clear node node.Free(); } + + /*-----------------------------------------------------------------------------------*/ + /* AnimParam Functions */ + /*-----------------------------------------------------------------------------------*/ + SHAnimationController::AnimParam::AnimParam(Type type) + : ParamType { type } + { + switch (ParamType) + { + case Type::Bool: + Value = false; + break; + case Type::Float: + Value = 0.0f; + break; + case Type::Int: + Value = 0; + break; + } + } } diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index c6d353e6..4efb1116 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -27,6 +27,7 @@ namespace SHADE /// /// Object that controls the animation that is played by an animator through the use /// of an internal state machine. + /// This should never be modified once it has been attached to a SHAnimatorComponent! /// class SH_API SHAnimationController { @@ -58,12 +59,23 @@ namespace SHADE Float, Int }; + using ValueType = std::variant; + + /*-------------------------------------------------------------------------------*/ + /* Constructor */ + /*-------------------------------------------------------------------------------*/ + /// + /// Constructs an AnimParam with the default value set for the Value field based + /// on the specified type. + /// + /// Type of AnimParam. + explicit AnimParam(Type type); /*-------------------------------------------------------------------------------*/ /* Data Members */ /*-------------------------------------------------------------------------------*/ - Type ParamType; - std::variant Value; + Type ParamType; + ValueType Value; }; /// @@ -91,10 +103,11 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ /* Data Members */ /*-------------------------------------------------------------------------------*/ - ConditionType Condition; - Handle Target; + ConditionType Condition; + AnimParam::ValueType Threshold; + Handle Target; }; - + /// /// Describes a node in the animation controller. /// @@ -103,6 +116,16 @@ namespace SHADE Handle Clip; std::vector Transitions; }; + + /// + /// Describes a node in the animation controller. + /// + struct InstanceData + { + Handle CurrentNode; + std::unordered_map Params; + float ClipPlaybackTime; + }; /*---------------------------------------------------------------------------------*/ /* Lifecycle Functions */ @@ -110,11 +133,7 @@ namespace SHADE /// /// Runs a single update for the animation controller. /// - void Update(); - /// - /// Resets the animation controller to its starting node. - /// - void Reset(); + void Update(InstanceData& instData, float dt); /*---------------------------------------------------------------------------------*/ /* Usage Functions */ @@ -130,20 +149,23 @@ namespace SHADE /// /// Node to destroy. void DestroyNode(Handle node); - + void AddTransition(Handle source, const Transition& transition); + void AddParameter(const std::string& name, AnimParam::Type type); + /*---------------------------------------------------------------------------------*/ /* Getters */ /*---------------------------------------------------------------------------------*/ - Handle GetCurrentNode() const noexcept { return currentNode; } + Handle GetStartingNode() const noexcept { return startNode; } + const std::unordered_map& GetParams() const noexcept { return parameters; } + const std::vector>& GetNodes() const noexcept { return nodes; } private: /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ // State machine - Handle currentNode; Handle startNode; std::vector> nodes; - std::unordered_map parameters; + std::unordered_map parameters; }; } diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index eee7fd51..1ab5c894 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -39,9 +39,42 @@ namespace SHADE void SHAnimatorComponent::Play(Handle clip) { + // Ignore if nothing is specified + if (!clip) + { + SHLOG_WARNING("[SHAnimatorComponent] Attempted to play an null SHAnimationClip. Use Stop() if stopping animation instead."); + return; + } + + // Remove animation controller as we switch to manual play mode + animController = {}; + animInstanceData.CurrentNode = {}; + animInstanceData.Params.clear(); + animInstanceData.ClipPlaybackTime = 0.0f; + + // Set accordingly currClip = clip; currPlaybackTime = 0.0f; - Play(); + channelMaps.clear(); + auto RAW_ANIM = clip->GetRawAnimation(); + + // Set up if valid + if (currClip && RAW_ANIM) + { + // Create channel maps + channelMaps.emplace(RAW_ANIM, createChannelMap(RAW_ANIM)); + // Calculate secs for the clip + secsPerTick = 1.0f / RAW_ANIM->GetTicksPerSecond(); + + // Start playback + Play(); + + // Set to initial pose + if (rig && rig->GetRootNode()) + { + updateCurrentAnimatorState(currClip, 0.0f); + } + } } void SHAnimatorComponent::PlayOneShot(Handle clip) @@ -67,6 +100,37 @@ namespace SHADE currPlaybackTime = 0.0f; } + /*-----------------------------------------------------------------------------------*/ + /* Update Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHAnimatorComponent::Update(float dt) + { + // Reset matrices + std::fill(boneMatrices.begin(), boneMatrices.end(), SHMatrix::Identity); + + // Do not do anything if is not playing or there's nothing to animate + if (!isPlaying || !rig || !rig->GetRootNode()) + return; + + // Update the animation controller if any, this will set the currClip + if (animController) + { + updateAnimController(dt); + + // Only update the animation state if there is a clip + if (animInstanceData.CurrentNode && animInstanceData.CurrentNode->Clip) + { + updateCurrentAnimatorState(animInstanceData.CurrentNode->Clip, animInstanceData.ClipPlaybackTime); + } + } + // Otherwise, a single clip was provided, then we'll use it + else if (currClip) + { + updateManualClipState(dt); + updateCurrentAnimatorState(currClip, currPlaybackTime); + } + } + /*-----------------------------------------------------------------------------------*/ /* Setter Functions */ /*-----------------------------------------------------------------------------------*/ @@ -86,104 +150,143 @@ namespace SHADE } } - void SHAnimatorComponent::SetClip(Handle newClip) + void SHAnimatorComponent::SetAnimationController(Handle ac) { // No change - if (currClip == newClip) + if (animController == ac) return; - // Get animation data - auto animData = currClip->GetRawAnimation(); - if (!animData) - return; + // Set the controller + animController = ac; - // Set parameters - currClip = newClip; - secsPerTick = 1.0f / animData->GetTicksPerSecond(); - - // Calculate total time for the clip - if (currClip) + // If valid, we want to initialize it + if (animController) { - const int ONE_PAST_LAST_FRAME = currClip->GetEndFrameIndex() + 1; - currClipTotalTime = (ONE_PAST_LAST_FRAME - currClip->GetStartFrameIndex()) / animData->GetTicksPerSecond(); - } - - // Build channel map and clip-specific data - channelMap.clear(); - if (animData) - { - for (const auto& channel : animData->GetChannels()) + // Parameters + animInstanceData.Params.clear(); + for (auto param : animController->GetParams()) { - channelMap.emplace(channel.Name, &channel); + animInstanceData.Params.emplace(param.first, SHAnimationController::AnimParam(param.second)); + } + // First Node + animInstanceData.CurrentNode = animController->GetStartingNode(); + // Playback Time + animInstanceData.ClipPlaybackTime = 0.0f; + + // Get set of unique SHRawAnimation used by the animController + std::unordered_set> rawAnims; + for (auto node : animController->GetNodes()) + { + // Ensure no null handles + if (!node) + continue; + const Handle CLIP = node->Clip; + if (!CLIP) + continue; + const Handle RAW_ANIM = CLIP->GetRawAnimation(); + if (!RAW_ANIM) + continue; + + // Store + rawAnims.emplace(RAW_ANIM); + } + + // Load channel maps + for (auto anim : rawAnims) + { + channelMaps.emplace(anim, createChannelMap(anim)); } } - - if (rig && rig->GetRootNode() && currClip) + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions - Loading */ + /*-----------------------------------------------------------------------------------*/ + SHAnimatorComponent::ChannelMap SHAnimatorComponent::createChannelMap(Handle rawAnimData) + { + ChannelMap channelMap; + for (const auto& channel : rawAnimData->GetChannels()) { - updatePoseWithClip(0.0f); + channelMap.emplace(channel.Name, &channel); + } + return channelMap; + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions - Update */ + /*-----------------------------------------------------------------------------------*/ + void SHAnimatorComponent::updateAnimController(float dt) + { + // No animation controller + if (!animInstanceData.CurrentNode) + return; + + // Update the animation controller + animController->Update(animInstanceData, dt); + + // Get current clip + currClip = animInstanceData.CurrentNode->Clip; + if (currClip && currClip->GetRawAnimation()) + { + secsPerTick = 1.0f / currClip->GetRawAnimation(); } } - - /*-----------------------------------------------------------------------------------*/ - /* Update Functions */ - /*-----------------------------------------------------------------------------------*/ - void SHAnimatorComponent::Update(float dt) + void SHAnimatorComponent::updateManualClipState(float dt) { - // Reset matrices - std::fill(boneMatrices.begin(), boneMatrices.end(), SHMatrix::Identity); - - // Nothing to animate - if (!currClip || !isPlaying || !rig || !rig->GetRootNode()) - return; - - // Get animation data - auto animData = currClip->GetRawAnimation(); - if (!animData) - return; - - // Update time on the playback currPlaybackTime += dt; - if (currPlaybackTime > currClipTotalTime) + if (currPlaybackTime > currClip->GetTotalDuration()) { if (playOnce) { playOnce = false; isPlaying = false; + currPlaybackTime = currClip->GetTotalDuration(); } else { - currPlaybackTime = currPlaybackTime - currClipTotalTime; + currPlaybackTime = currPlaybackTime - currClip->GetTotalDuration(); } } + } + void SHAnimatorComponent::updateCurrentAnimatorState(Handle clip, float playbackTime) + { + // Nothing to animate + if (!clip || !isPlaying || !rig || !rig->GetRootNode()) + return; + + // Check that we have animation data + if (!clip->GetRawAnimation()) + return; // Play the clip - updatePoseWithClip(currPlaybackTime); + updatePoseWithClip(clip, currPlaybackTime); } - - /*-----------------------------------------------------------------------------------*/ - /* Helper Functions */ - /*-----------------------------------------------------------------------------------*/ - void SHAnimatorComponent::updatePoseWithClip(float poseTime) + void SHAnimatorComponent::updatePoseWithClip(Handle clip, float poseTime) { // Get closest frame index - const int CLOSEST_FRAME_IDX = currClip->GetStartFrameIndex() + static_cast(std::floorf(poseTime * currClip->GetRawAnimation()->GetTicksPerSecond())); - updatePoseWithClip(CLOSEST_FRAME_IDX, poseTime, rig->GetRootNode(), SHMatrix::Identity); + const int CLOSEST_FRAME_IDX = clip->GetStartFrameIndex() + static_cast(std::floorf(poseTime / secsPerTick)); + updatePoseWithClip(CLOSEST_FRAME_IDX, poseTime, clip->GetRawAnimation(), rig->GetRootNode(), SHMatrix::Identity); } - void SHAnimatorComponent::updatePoseWithClip(int closestFrameIndex, float poseTime, Handle node, const SHMatrix& parentMatrix) + void SHAnimatorComponent::updatePoseWithClip(int closestFrameIndex, float poseTime, Handle rawAnimData, Handle node, const SHMatrix& parentMatrix) { // Check if there is a channel for this node const std::string& BONE_NAME = rig->GetName(node); SHMatrix transformMatrix = node->TransformMatrix; - if (channelMap.contains(BONE_NAME)) + + if (channelMaps.contains(rawAnimData)) { - const auto CHANNEL = channelMap[BONE_NAME]; - transformMatrix = SHMatrix::Transform - ( - getInterpolatedValue(CHANNEL->PositionKeyFrames, closestFrameIndex, poseTime), - getInterpolatedValue(CHANNEL->RotationKeyFrames, closestFrameIndex, poseTime), - getInterpolatedValue(CHANNEL->ScaleKeyFrames, closestFrameIndex, poseTime) - ); + auto channelMap = channelMaps[rawAnimData]; + if (channelMap.contains(BONE_NAME)) + { + const auto CHANNEL = channelMap[BONE_NAME]; + transformMatrix = SHMatrix::Transform + ( + getInterpolatedValue(CHANNEL->PositionKeyFrames, closestFrameIndex, poseTime), + getInterpolatedValue(CHANNEL->RotationKeyFrames, closestFrameIndex, poseTime), + getInterpolatedValue(CHANNEL->ScaleKeyFrames, closestFrameIndex, poseTime) + ); + } } // Apply parent's transformation @@ -200,7 +303,7 @@ namespace SHADE // Apply pose to children for (auto& child : node->Children) { - updatePoseWithClip(closestFrameIndex, poseTime, child, transformMatrix); + updatePoseWithClip(closestFrameIndex, poseTime, rawAnimData, child, transformMatrix); } } } diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index 12d377fe..d4af2c2b 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited. #include "Math/Vector/SHVec3.h" #include "Math/SHQuaternion.h" #include "SHRawAnimation.h" +#include "SHAnimationController.h" namespace SHADE { @@ -52,12 +53,14 @@ namespace SHADE /// void Play(); /// - /// Plays the specified animation clip from the start. + /// Plays the specified animation clip from the start. This will unset any + /// SHAnimationControllers that have been set. /// /// Animation clip to play. void Play(Handle clip); /// - /// Plays the specified animation clip from the start one time only. + /// Plays the specified animation clip from the start one time only. This will unset + /// any SHAnimationControllers that have been set. /// /// Animation clip to play. void PlayOneShot(Handle clip); @@ -74,6 +77,16 @@ namespace SHADE /// void Stop(); + /*---------------------------------------------------------------------------------*/ + /* Update Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Updates the current state of the animation if one is specified based on the + /// current animation clip and frames. This will update the bone matrices. + /// + /// Time passed since the last frame. + void Update(float dt); + /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ @@ -82,13 +95,7 @@ namespace SHADE /// /// Rig to use. void SetRig(Handle newRig); - /// - /// Sets the animation clip of this animator without playing it. - /// This will set the pose of the model to it's initial pose. - /// If the clip is the same as the current clip, nothing happens. - /// - /// Clip to use. - void SetClip(Handle newClip); + void SetAnimationController(Handle ac); /*---------------------------------------------------------------------------------*/ /* Getter Functions */ @@ -104,51 +111,55 @@ namespace SHADE /// Handle to the currently set rig. Handle GetRig() const noexcept { return rig; } /// - /// - /// Retrieve the currently set animation clip. - /// - /// Handle to the currently set animation clip. - Handle GetCurrentClip() const noexcept { return currClip; } - /// /// Checks if an animation is currently playing. /// /// True if an animation clip is currently playing. bool IsPlaying() const { return isPlaying; } - - /*---------------------------------------------------------------------------------*/ - /* Update Functions */ - /*---------------------------------------------------------------------------------*/ /// - /// Updates the current state of the animation if one is specified based on the - /// current animation clip and frames. This will update the bone matrices. + /// Retrieves the current node for the Animation Controller. This returns a null + /// if there is no Animation Controller currently set. /// - /// Time passed since the last frame. - void Update(float dt); + /// Handle to the current Animation Controller node. + Handle GetCurrentNode() const noexcept { return animInstanceData.CurrentNode; } + Handle GetAnimationController() const noexcept { return animController; } private: + /*---------------------------------------------------------------------------------*/ + /* Type Definition */ + /*---------------------------------------------------------------------------------*/ + using ChannelMap = std::unordered_map; + /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ // Resources Handle rig; + // Playback Tracking for Animation Controller Mode + Handle animController; + SHAnimationController::InstanceData animInstanceData; + // Playback Tracking for Manual Mode Handle currClip; - // Playback Tracking float currPlaybackTime = 0.0f; - bool isPlaying = true; bool playOnce = false; - float currClipTotalTime = 0.0f; - // Useful Cached Data + // Shared Tracking + bool isPlaying = true; float secsPerTick = 0.0f; // Buffer std::vector boneMatrices; // Caches - std::unordered_map channelMap; + std::unordered_map, ChannelMap> channelMaps; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ /*---------------------------------------------------------------------------------*/ - void updatePoseWithClip(float poseTime); - void updatePoseWithClip(int closestFrameIndex, float poseTime, Handle node, const SHMatrix& parentMatrix); + // Loading + ChannelMap createChannelMap(Handle rawAnimData); + // Update + void updateAnimController(float dt); + void updateManualClipState(float dt); + void updateCurrentAnimatorState(Handle clip, float playbackTime); + void updatePoseWithClip(Handle clip, float poseTime); + void updatePoseWithClip(int closestFrameIndex, float poseTime, Handle rawAnimData, Handle node, const SHMatrix& parentMatrix); template T getInterpolatedValue(const std::vector>& keyframes, int closestFrameIndex, float poseTime); diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimControllerAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimControllerAsset.h new file mode 100644 index 00000000..625e4d5c --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimControllerAsset.h @@ -0,0 +1,27 @@ +/************************************************************************************//*! +\file SHAnimControllerAsset.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 1, 2023 +\brief Contains the definition of the SHAnimControllerAsset struct 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 + +#include + +#include "SH_API.h" +#include "SHAssetData.h" + +namespace SHADE +{ + struct SH_API SHAnimControllerAsset : SHAssetData + { + std::string name; + // TODO + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 566e34e2..33891d7f 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -18,10 +18,10 @@ // FMOD Fwd Declare namespace FMOD { - class Sound; - class System; - class ChannelGroup; - class Channel; + class Sound; + class System; + class ChannelGroup; + class Channel; } enum FMOD_RESULT : int; enum FMOD_SPEAKERMODE : int; @@ -45,9 +45,9 @@ constexpr AssetID INVALID_ASSET_ID {0}; // Asset type enum enum class AssetType : AssetTypeMeta { - INVALID, - SHADER, - SHADER_BUILT_IN, + INVALID, + SHADER, + SHADER_BUILT_IN, TEXTURE, MODEL, SCENE, @@ -56,7 +56,7 @@ enum class AssetType : AssetTypeMeta MESH, SCRIPT, FONT, - MAX_COUNT + MAX_COUNT }; constexpr size_t TYPE_COUNT{ static_cast(AssetType::MAX_COUNT) }; @@ -94,18 +94,18 @@ constexpr std::string_view TEXTURE_EXTENSION {".shtex"}; constexpr std::string_view MODEL_EXTENSION{ ".shmodel" }; constexpr std::string_view EXTENSIONS[] = { - AUDIO_EXTENSION, - SHADER_EXTENSION, - SHADER_BUILT_IN_EXTENSION, + AUDIO_EXTENSION, + SHADER_EXTENSION, + SHADER_BUILT_IN_EXTENSION, TEXTURE_EXTENSION, MODEL_EXTENSION, SCENE_EXTENSION, - PREFAB_EXTENSION, + PREFAB_EXTENSION, MATERIAL_EXTENSION, "dummy", SCRIPT_EXTENSION, FONT_EXTENSION, - AUDIO_WAV_EXTENSION, + AUDIO_WAV_EXTENSION, }; constexpr size_t EXTENSIONS_COUNT{ 11 }; @@ -118,10 +118,10 @@ constexpr std::string_view GLTF_EXTENSION{ ".gltf" }; constexpr std::string_view TTF_EXTENSION{ ".ttf" }; constexpr std::string_view EXTERNALS[] = { - GLSL_EXTENSION, - DDS_EXTENSION, - FBX_EXTENSION, - GLTF_EXTENSION, + GLSL_EXTENSION, + DDS_EXTENSION, + FBX_EXTENSION, + GLTF_EXTENSION, TTF_EXTENSION }; @@ -131,9 +131,9 @@ constexpr std::string_view FRAGMENT_SHADER{ "_FS" }; constexpr std::string_view COMPUTER_SHADER{ "_CS" }; constexpr std::pair SHADER_IDENTIFIERS[] = { - std::make_pair(VERTEX_SHADER, SHADE::SH_SHADER_TYPE::VERTEX), - std::make_pair(FRAGMENT_SHADER, SHADE::SH_SHADER_TYPE::FRAGMENT), - std::make_pair(COMPUTER_SHADER, SHADE::SH_SHADER_TYPE::COMPUTE) + std::make_pair(VERTEX_SHADER, SHADE::SH_SHADER_TYPE::VERTEX), + std::make_pair(FRAGMENT_SHADER, SHADE::SH_SHADER_TYPE::FRAGMENT), + std::make_pair(COMPUTER_SHADER, SHADE::SH_SHADER_TYPE::COMPUTE) }; constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 }; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 3ceb7166..5bb2d29d 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -646,31 +646,6 @@ namespace SHADE SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); } } - Handle const clip = (component->GetCurrentClip() ? component->GetCurrentClip()->GetRawAnimation() : Handle{}); - const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName(clip).value_or("") : ""; - SHEditorWidgets::DragDropReadOnlyField("Clip", CLIP_NAME, - [component]() - { - Handle const clip = (component->GetCurrentClip() ? component->GetCurrentClip()->GetRawAnimation() : Handle{}); - return SHResourceManager::GetAssetID(clip).value_or(0); - }, - [component](AssetID const& id) - { - if (SHAssetManager::GetType(id) != AssetType::MODEL) - { - SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!") - return; - } - component->SetClip(SHResourceManager::LoadOrGet(id)); - }, SHDragDrop::DRAG_RESOURCE); - if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) - { - if (Handle const clip = component->GetCurrentClip()->GetRawAnimation()) - { - AssetID assetID = SHResourceManager::GetAssetID(clip).value_or(0); - SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); - } - } } else { diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index 1f26bf2a..21303982 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited. #include "Assets/Asset Types/SHTextureAsset.h" #include "Assets/Asset Types/SHShaderAsset.h" #include "Assets/Asset Types/SHAnimClipAsset.h" +#include "Assets/Asset Types/SHAnimControllerAsset.h" #include "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" #include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h" @@ -40,6 +41,7 @@ namespace SHADE class SHMaterial; struct SHRigNode; class SHAnimationClip; + class SHAnimationController; /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -48,16 +50,17 @@ namespace SHADE /// Template structs that maps a resource to their loaded asset representation type. /// template - struct SHResourceLoader { using AssetType = void; }; - template<> struct SHResourceLoader { using AssetType = SHMeshAsset; }; - template<> struct SHResourceLoader { using AssetType = SHTextureAsset; }; - template<> struct SHResourceLoader { using AssetType = SHShaderAsset; }; - template<> struct SHResourceLoader { using AssetType = SHMaterialAsset; }; - template<> struct SHResourceLoader { using AssetType = SHMaterialSpec; }; - template<> struct SHResourceLoader { using AssetType = SHFontAsset; }; - template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; - template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; - template<> struct SHResourceLoader { using AssetType = SHAnimClipAsset; }; + struct SHResourceLoader { using AssetType = void; }; + template<> struct SHResourceLoader { using AssetType = SHMeshAsset; }; + template<> struct SHResourceLoader { using AssetType = SHTextureAsset; }; + template<> struct SHResourceLoader { using AssetType = SHShaderAsset; }; + template<> struct SHResourceLoader { using AssetType = SHMaterialAsset; }; + template<> struct SHResourceLoader { using AssetType = SHMaterialSpec; }; + template<> struct SHResourceLoader { using AssetType = SHFontAsset; }; + template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; + template<> struct SHResourceLoader { using AssetType = SHModelAsset; }; + template<> struct SHResourceLoader { using AssetType = SHAnimClipAsset; }; + template<> struct SHResourceLoader { using AssetType = SHAnimControllerAsset; }; /// /// Static class responsible for loading and caching runtime resources from their diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index da557748..be6cc5e6 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -36,14 +36,16 @@ namespace SHADE Handle SHResourceManager::LoadOrGet(AssetID assetId) { // Check if it is an unsupported type - if (!std::is_same_v && - !std::is_same_v && - !std::is_same_v && - !std::is_same_v && - !std::is_same_v && - !std::is_same_v && - !std::is_same_v && - !std::is_same_v + if (!std::is_same_v && + !std::is_same_v && + !std::is_same_v && + !std::is_same_v && + !std::is_same_v && + !std::is_same_v && + !std::is_same_v && + !std::is_same_v && + !std::is_same_v && + !std::is_same_v ) { static_assert(true, "Unsupported Resource Type specified for SHResourceManager."); @@ -361,7 +363,7 @@ namespace SHADE loadedAssetData.emplace_back(assetId); return resourceHub.Create(*assetData.anims[0]); } - else if constexpr (std::is_same_v) + else if constexpr (std::is_same_v) { loadedAssetData.emplace_back(assetId); return resourceHub.Create @@ -371,5 +373,13 @@ namespace SHADE assetData->lastIndex ); } + else if constexpr (std::is_same_v) + { + loadedAssetData.emplace_back(assetId); + return resourceHub.Create + ( + // TODO + ); + } } } diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index 9fceb10d..bcc3d792 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -394,13 +394,13 @@ namespace YAML struct convert { static constexpr std::string_view RIG_YAML_TAG = "Rig"; - static constexpr std::string_view CLIP_YAML_TAG = "Clip"; + static constexpr std::string_view AC_YAML_TAG = "AnimationController"; static YAML::Node encode(SHAnimatorComponent const& rhs) { YAML::Node node; node[RIG_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetRig()).value_or(0); - node[CLIP_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetCurrentClip()).value_or(0); + node[AC_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetAnimationController()).value_or(0); return node; } static bool decode(YAML::Node const& node, SHAnimatorComponent& rhs) @@ -409,9 +409,9 @@ namespace YAML { rhs.SetRig(SHResourceManager::LoadOrGet(node[RIG_YAML_TAG.data()].as())); } - if (node[CLIP_YAML_TAG.data()].IsDefined()) + if (node[AC_YAML_TAG.data()].IsDefined()) { - rhs.SetClip(SHResourceManager::LoadOrGet(node[CLIP_YAML_TAG.data()].as())); + rhs.SetAnimationController(SHResourceManager::LoadOrGet(node[AC_YAML_TAG.data()].as())); } return true; } From e878b7b65a9213ebc8e8a9d752aa7de4916bc066 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 1 Mar 2023 20:37:02 +0800 Subject: [PATCH 09/69] Added implementation of SHAnimationController Transition logic --- .../src/Animation/SHAnimationController.cpp | 95 +++++++++++++++---- .../src/Animation/SHAnimationController.h | 35 ++++++- .../src/Animation/SHAnimationController.hpp | 67 +++++++++++++ .../MiddleEnd/Textures/SHTextureLibrary.h | 2 +- 4 files changed, 176 insertions(+), 23 deletions(-) create mode 100644 SHADE_Engine/src/Animation/SHAnimationController.hpp diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 3230b2d9..b3105e64 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -17,6 +17,52 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* AnimParam Functions */ + /*-----------------------------------------------------------------------------------*/ + SHAnimationController::AnimParam::AnimParam(Type type) + : ParamType { type } + { + switch (ParamType) + { + case Type::Bool: + Value = false; + break; + case Type::Float: + Value = 0.0f; + break; + case Type::Int: + Value = 0; + break; + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Transition - Usage Functions */ + /*-----------------------------------------------------------------------------------*/ + bool SHAnimationController::Transition::EvaluateCondition(const AnimParam& testParam) const noexcept + { + // Don't match, instant fail + if (testParam.ParamType != Param.ParamType) + return false; + + // Evaluate them accordingly + switch (Param.ParamType) + { + case AnimParam::Type::Bool: + case AnimParam::Type::Trigger: + return evaluateCondition(std::get(testParam.Value)); + case AnimParam::Type::Float: + return evaluateCondition(std::get(testParam.Value)); + break; + case AnimParam::Type::Int: + return evaluateCondition(std::get(testParam.Value)); + break; + } + + return false; + } + /*-----------------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*-----------------------------------------------------------------------------------*/ @@ -38,7 +84,33 @@ namespace SHADE // Go to next state for (const auto& transition : instData.CurrentNode->Transitions) { - // TODO + // Check for no condition special case + if (transition.Condition == Transition::ConditionType::None) + { + changeNode(instData, transition.Target); + break; + } + else + { + // Check if we have the parameter + if (!instData.Params.contains(transition.ParamName)) + continue; + + // If evaluation success, we transition + AnimParam& param = instData.Params[transition.ParamName]; + if (transition.EvaluateCondition(param)) + { + changeNode(instData, transition.Target); + + // If trigger, we need to unset it + if (param.ParamType == AnimParam::Type::Trigger) + { + param.Value = false; + } + + break; + } + } } } } @@ -81,24 +153,13 @@ namespace SHADE // Clear node node.Free(); } - + /*-----------------------------------------------------------------------------------*/ - /* AnimParam Functions */ + /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ - SHAnimationController::AnimParam::AnimParam(Type type) - : ParamType { type } + void SHAnimationController::changeNode(InstanceData& instData, Handle newNode) { - switch (ParamType) - { - case Type::Bool: - Value = false; - break; - case Type::Float: - Value = 0.0f; - break; - case Type::Int: - Value = 0; - break; - } + instData.CurrentNode = newNode; + instData.ClipPlaybackTime = 0.0f; } } diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index 4efb1116..2aa46f3c 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -55,7 +55,7 @@ namespace SHADE enum class Type { Bool, - Trigger, + Trigger, // Variant of bool that can only be set to true and will be unset when consumed. Float, Int }; @@ -69,7 +69,7 @@ namespace SHADE /// on the specified type. /// /// Type of AnimParam. - explicit AnimParam(Type type); + explicit AnimParam(Type type = Type::Int); /*-------------------------------------------------------------------------------*/ /* Data Members */ @@ -103,9 +103,27 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ /* Data Members */ /*-------------------------------------------------------------------------------*/ - ConditionType Condition; - AnimParam::ValueType Threshold; - Handle Target; + ConditionType Condition; + AnimParam Param; + std::string ParamName; + Handle Target; + + /*-------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-------------------------------------------------------------------------------*/ + /// + /// Checks the condition of this Transition against an animation paramter. + /// + /// Parameter to test with. + /// Whether the condition passed. + bool EvaluateCondition(const AnimParam& testParam) const noexcept; + + private: + /*-------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-------------------------------------------------------------------------------*/ + template + bool evaluateCondition(T value) const noexcept; }; /// @@ -167,5 +185,12 @@ namespace SHADE Handle startNode; std::vector> nodes; std::unordered_map parameters; + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + void changeNode(InstanceData& instData, Handle newNode); }; } + +#include "SHAnimationController.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimationController.hpp b/SHADE_Engine/src/Animation/SHAnimationController.hpp new file mode 100644 index 00000000..054f066e --- /dev/null +++ b/SHADE_Engine/src/Animation/SHAnimationController.hpp @@ -0,0 +1,67 @@ +/************************************************************************************//*! +\file SHAnimationController.hpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 1, 2023 +\brief Contains the definition of template functions SHAnimationController. + +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 +#include "SHAnimationController.h" + +namespace SHADE +{ + template + bool SHAnimationController::Transition::evaluateCondition(T value) const noexcept + { + // Early failure if invalid data + if (!std::holds_alternative(Param.Value)) + return false; + + // Get the value + const T PARAM_VAL = std::get(Param.Value); + + // Handle condition type + switch (Condition) + { + case SHAnimationController::Transition::ConditionType::None: + return true; + case SHAnimationController::Transition::ConditionType::Equals: + if constexpr (std::is_floating_point_v) + { + static constexpr T EPSILON = static_cast(0.001); + return std::abs(std::abs(value) - std::abs(PARAM_VAL)) < EPSILON; + } + else + { + return value == PARAM_VAL; + } + break; + case SHAnimationController::Transition::ConditionType::NotEquals: + if constexpr (std::is_floating_point_v) + { + static constexpr T EPSILON = static_cast(0.001); + return std::abs(std::abs(value) - std::abs(PARAM_VAL)) > EPSILON; + } + else + { + return value != PARAM_VAL; + } + break; + case SHAnimationController::Transition::ConditionType::LessThan: + return PARAM_VAL < value; + case SHAnimationController::Transition::ConditionType::LessThanOrEqual: + return PARAM_VAL <= value; + case SHAnimationController::Transition::ConditionType::GreaterThan: + return PARAM_VAL > value; + case SHAnimationController::Transition::ConditionType::GreaterThanOrEqual: + return PARAM_VAL >= value; + } + + // Neither of the existing cases + return false; + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h index bbc72a1a..e1c93349 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -71,7 +71,7 @@ namespace SHADE //! of the texture library would mean the recreation of the desc set that also //! involves the generic data, which is bad bad bad. Solution is to separate the //! 2 desc sets. - static constexpr uint32_t DEFAULT_MAX_TEXTURES = 2000; + static constexpr uint32_t DEFAULT_MAX_TEXTURES = 1000; /*-----------------------------------------------------------------------------*/ /* Usage Functions */ From d21f9d6c4b53a6bfe6da3b1cce19c78a919d841d Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 1 Mar 2023 22:10:09 +0800 Subject: [PATCH 10/69] Added functions for adding transitions and parameters to an AnimationController --- .../src/Animation/SHAnimationController.cpp | 50 +++++++++++++++++++ .../src/Animation/SHAnimationController.h | 16 ++++++ 2 files changed, 66 insertions(+) diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index b3105e64..3a1f581e 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -154,6 +154,56 @@ namespace SHADE node.Free(); } + void SHAnimationController::AddTransition(Handle source, const Transition& transition) + { + if (!source) + { + SHLOG_ERROR("[SHAnimationController] Attempted to add transition from an invalid node."); + return; + } + + if (!transition.Target) + { + SHLOG_ERROR("[SHAnimationController] Attempted to add transition to an invalid node."); + return; + } + + if (transition.Condition != Transition::ConditionType::None && !parameters.contains(transition.ParamName)) + { + SHLOG_ERROR("[SHAnimationController] Attempted to add a conditional transition for an invalid parameter."); + return; + } + + source->Transitions.emplace_back(transition); + } + void SHAnimationController::AddParameter(const std::string& name, AnimParam::Type type) + { + if (name.empty()) + { + SHLOG_ERROR("[SHAnimationController] Attempted to add a parameter with no name."); + return; + } + + if (parameters.contains(name)) + { + SHLOG_ERROR("[SHAnimationController] Attempted to add a parameter with the same name."); + return; + } + + // Insert + parameters.emplace(name, type); + } + void SHAnimationController::RemoveParameter(const std::string& name) + { + if (!parameters.contains(name)) + { + SHLOG_ERROR("[SHAnimationController] Attempted to reemove a parameter that does not exist."); + return; + } + + parameters.erase(name); + } + /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index 2aa46f3c..90162422 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -167,8 +167,24 @@ namespace SHADE /// /// Node to destroy. void DestroyNode(Handle node); + /// + /// Links two nodes together with a Transition. This performs some additional + /// checking to ensure parameters are valid. + /// + /// Source node to transition from. + /// Describes the transition to add. void AddTransition(Handle source, const Transition& transition); + /// + /// Registers a parameter to the animation controller. + /// + /// Name of the parameter. + /// Type of the parameter. void AddParameter(const std::string& name, AnimParam::Type type); + /// + /// Removes a parameter from the animation controller. + /// + /// Name of the parameter. + void RemoveParameter(const std::string& name); /*---------------------------------------------------------------------------------*/ /* Getters */ From dfb53bf2901f198756c564aa94bf736fb33a412f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 1 Mar 2023 23:49:30 +0800 Subject: [PATCH 11/69] Added WIP AnimationControllerEditor --- .../src/Animation/SHAnimationController.cpp | 2 +- .../src/Animation/SHAnimationController.h | 1 + .../Animation/SHAnimationControllerEditor.cpp | 107 ++++++++++++++++++ .../Animation/SHAnimationControllerEditor.h | 49 ++++++++ .../EditorWindow/SHEditorWindowIncludes.h | 19 ++-- SHADE_Engine/src/Editor/SHEditor.cpp | 7 ++ SHADE_Engine/src/Editor/SHEditorUI.h | 12 +- 7 files changed, 181 insertions(+), 16 deletions(-) create mode 100644 SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp create mode 100644 SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 3a1f581e..557bedb3 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -3,7 +3,7 @@ \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Feb 22, 2023 -\brief Contains the definition of SHAnimationController's functions. +\brief Contains the definition of SHAnimationController's functions. Copyright (C) 2023 DigiPen Institute of Technology. diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index 90162422..ca6fbf70 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -131,6 +131,7 @@ namespace SHADE /// struct Node { + std::string Name = "Unnamed Node"; Handle Clip; std::vector Transitions; }; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp new file mode 100644 index 00000000..c829c985 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -0,0 +1,107 @@ +/************************************************************************************//*! +\file SHAnimationControllerEditor.cpp +\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. + + +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. +*//*************************************************************************************/ +#include "SHpch.h" +#include "SHAnimationControllerEditor.h" + +// STL Includes +#include +// External Dependencies +#include +#include +// Project Includes +#include "Editor/IconsMaterialDesign.h" +#include "Animation/SHAnimationController.h" +#include "../../SHEditorUI.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Cosntructors/Destructors */ + /*-----------------------------------------------------------------------------------*/ + SHAnimationControllerEditor::SHAnimationControllerEditor() + : SHEditorWindow("Animation Controller Editor", ImGuiWindowFlags_MenuBar) + {} + + /*-----------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHAnimationControllerEditor::Init() + { + SHEditorWindow::Init(); + } + + void SHAnimationControllerEditor::Update() + { + SHEditorWindow::Update(); + + if (Begin()) + { + drawMenuBar(); + + ImNodes::BeginNodeEditor(); + { + /* Draw Nodes */ + int id = 0; + for (auto node : controller.GetNodes()) + { + ImNodes::BeginNode(id); + { + // Title + ImNodes::BeginNodeTitleBar(); + { + ImGui::TextUnformatted(node->Name.c_str()); + ImGui::SameLine(); + ImGui::Button(ICON_MD_EDIT); + } + ImNodes::EndNodeTitleBar(); + + // Body + ImGui::Text("Clip"); + ImGui::SameLine(); + std::array buffer = { '\0' }; + ImGui::PushItemWidth(80.0f); + ImGui::InputText("", buffer.data(), buffer.size()); + ImGui::PopItemWidth(); + } + ImNodes::EndNode(); + ++id; + } + } + + ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_BottomRight); + ImNodes::EndNodeEditor(); + } + ImGui::End(); + } + + void SHAnimationControllerEditor::Exit() + { + SHEditorWindow::Exit(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHAnimationControllerEditor::drawMenuBar() + { + if (ImGui::BeginMenuBar()) + { + if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data())) + { + controller.CreateNode(); + } + + ImGui::EndMenuBar(); + } + } +} \ 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 new file mode 100644 index 00000000..7ac7432e --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h @@ -0,0 +1,49 @@ +/************************************************************************************//*! +\file SHAnimationControllerEditor.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 1, 2023 +\brief Contains the definition of SHAnimationControllerEditor. + +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 + +// STL Includes +// Project Includes +#include "Resource/SHHandle.h" +#include "Editor/EditorWindow/SHEditorWindow.h" +#include "Animation/SHAnimationController.h" + +namespace SHADE +{ + class SHAnimationControllerEditor final : public SHEditorWindow + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors/Destructors */ + /*---------------------------------------------------------------------------------*/ + SHAnimationControllerEditor(); + ~SHAnimationControllerEditor() = default; + + /*---------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ + void Init() override; + void Update() override; + void Exit() override; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + SHAnimationController controller; + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + void drawMenuBar(); + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h index 290ed622..829a1871 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h @@ -1,10 +1,11 @@ #pragma once -#include "MenuBar/SHEditorMenuBar.h" //Menu Bar -#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel -#include "Inspector/SHEditorInspector.h" //Inspector -#include "Profiling/SHEditorProfiler.h" //Profiler -#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport -#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser -#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector -#include "ColliderTagPanel/SHColliderTagPanel.h" //Collider Tag Panel -#include "InputBindings/SHInputBindingsPanel.h" //Input Bindings \ No newline at end of file +#include "MenuBar/SHEditorMenuBar.h" // Menu Bar +#include "HierarchyPanel/SHHierarchyPanel.h" // Hierarchy Panel +#include "Inspector/SHEditorInspector.h" // Inspector +#include "Profiling/SHEditorProfiler.h" // Profiler +#include "ViewportWindow/SHEditorViewport.h" // Editor Viewport +#include "AssetBrowser/SHAssetBrowser.h" // Asset Browser +#include "MaterialInspector/SHMaterialInspector.h" // Material Inspector +#include "ColliderTagPanel/SHColliderTagPanel.h" // Collider Tag Panel +#include "InputBindings/SHInputBindingsPanel.h" // Input Bindings +#include "EditorWindow/Animation/SHAnimationControllerEditor.h" // Animation Controller Editor \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 346bfbed..904a239b 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -39,6 +39,7 @@ //|| Library Includes || //#==============================================================# #include +#include #include #include #include @@ -96,6 +97,10 @@ namespace SHADE SHLOG_CRITICAL("Failed to create ImGui Context") } } + if (ImNodes::CreateContext() == nullptr) + { + SHLOG_CRITICAL("Failed to create ImNodes Context") + } #ifdef SHEDITOR editorConfig = &SHConfigurationManager::LoadEditorConfig(); @@ -112,6 +117,7 @@ namespace SHADE SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); //Add popup windows SHEditorWindowManager::CreatePopupWindow(); @@ -339,6 +345,7 @@ namespace SHADE { window->Init(); } + ImNodes::DestroyContext(); ImGui_ImplVulkan_Shutdown(); ImGui_ImplSDL2_Shutdown(); ImGui::DestroyContext(); diff --git a/SHADE_Engine/src/Editor/SHEditorUI.h b/SHADE_Engine/src/Editor/SHEditorUI.h index 23cc2d1a..94804bb9 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.h +++ b/SHADE_Engine/src/Editor/SHEditorUI.h @@ -90,7 +90,7 @@ namespace SHADE /// True if the header is open, false otherwise. static bool CollapsingHeader(const std::string& title, bool* isHovered = nullptr); static void SameLine(); - static void Separator(); + static void Separator(); /*-----------------------------------------------------------------------------*/ /* ImGui Wrapper Functions - Queries */ @@ -98,9 +98,9 @@ namespace SHADE static bool IsItemHovered(); /*-----------------------------------------------------------------------------*/ - /* ImGui Wrapper Functions - Menu */ - /*-----------------------------------------------------------------------------*/ - static bool BeginMenu(const std::string& label); + /* ImGui Wrapper Functions - Menu */ + /*-----------------------------------------------------------------------------*/ + static bool BeginMenu(const std::string& label); static bool BeginMenu(const std::string& label, const char* icon); static void EndMenu(); static void BeginTooltip(); @@ -164,8 +164,8 @@ namespace SHADE /// /// Text to display. /// True if button was pressed. - static bool Button(const std::string& title); - static bool Selectable(const std::string& label); + static bool Button(const std::string& title); + static bool Selectable(const std::string& label); static bool Selectable(const std::string& label, const char* icon); /// /// Creates a checkbox widget for boolean input. From 3a14f0a887141bb71b436e9f3e366cddead13ab5 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 2 Mar 2023 16:54:34 +0800 Subject: [PATCH 12/69] Added SHRawAnimInspector --- SHADE_Engine/src/Animation/SHRawAnimation.cpp | 1 + SHADE_Engine/src/Animation/SHRawAnimation.h | 2 + .../Animation/SHAnimationControllerEditor.cpp | 2 +- .../Animation/SHAnimationControllerEditor.h | 29 +++ .../AssetBrowser/SHAssetBrowser.cpp | 19 +- .../SHRawAnimInspector.cpp | 170 ++++++++++++++++++ .../SHRawAnimInspector.h | 86 +++++++++ .../EditorWindow/SHEditorWindowIncludes.h | 21 +-- SHADE_Engine/src/Editor/SHEditor.cpp | 1 + 9 files changed, 313 insertions(+), 18 deletions(-) create mode 100644 SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp create mode 100644 SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h diff --git a/SHADE_Engine/src/Animation/SHRawAnimation.cpp b/SHADE_Engine/src/Animation/SHRawAnimation.cpp index 86d0af18..712611d4 100644 --- a/SHADE_Engine/src/Animation/SHRawAnimation.cpp +++ b/SHADE_Engine/src/Animation/SHRawAnimation.cpp @@ -22,6 +22,7 @@ namespace SHADE SHRawAnimation::SHRawAnimation(const SHAnimAsset& asset) : ticksPerSecond { static_cast(asset.ticksPerSecond) } , totalTime { static_cast(asset.duration) / static_cast(asset.ticksPerSecond) } + , totalFrames { static_cast(asset.duration) } { // Populate keyframes for (const auto& channel : asset.nodeChannels) diff --git a/SHADE_Engine/src/Animation/SHRawAnimation.h b/SHADE_Engine/src/Animation/SHRawAnimation.h index ee5d3769..e05e1a74 100644 --- a/SHADE_Engine/src/Animation/SHRawAnimation.h +++ b/SHADE_Engine/src/Animation/SHRawAnimation.h @@ -67,6 +67,7 @@ namespace SHADE const std::vector& GetChannels() const noexcept { return channels; } int GetTicksPerSecond() const noexcept { return ticksPerSecond; } float GetTotalTime() const noexcept { return totalTime; } + int GetTotalFrames() const noexcept { return totalFrames; } private: /*---------------------------------------------------------------------------------*/ @@ -75,6 +76,7 @@ namespace SHADE std::vector channels; int ticksPerSecond; float totalTime; + int totalFrames; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index c829c985..65c4d010 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. diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h index 7ac7432e..03da7771 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h @@ -12,6 +12,7 @@ of DigiPen Institute of Technology is prohibited. #pragma once // STL Includes +#include // Project Includes #include "Resource/SHHandle.h" #include "Editor/EditorWindow/SHEditorWindow.h" @@ -19,6 +20,9 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { + /// + /// Editor for modifying the Animation Controller state machine. + /// class SHAnimationControllerEditor final : public SHEditorWindow { public: @@ -36,10 +40,35 @@ namespace SHADE void Exit() override; private: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + union NodeAttributeIndex + { + int16_t Raw; + struct + { + uint8_t OwnerNodeIndex; + uint8_t AttributeIndex; + }; + }; + union NodeLinkIndex + { + int32_t Raw; + struct + { + NodeAttributeIndex SourceAttribute; + NodeAttributeIndex DestinationAttribute; + }; + }; // What about same source and destination but different link? + /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ SHAnimationController controller; + std::vector> inputNodesMap; + std::vector> outputNodesMap; + std::vector linkIndices; // Encodes details of the link in the node index /*---------------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index a0aaf0fa..c1796501 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -23,6 +23,7 @@ #include "Serialization/SHSerialization.h" #include #include "Serialization/Prefab/SHPrefabManager.h" +#include "Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h" namespace SHADE { @@ -371,14 +372,18 @@ namespace SHADE case AssetType::SHADER: break; case AssetType::SHADER_BUILT_IN: break; case AssetType::TEXTURE: break; - case AssetType::MESH: break; + case AssetType::MODEL: + if (auto animInspector = SHEditorWindowManager::GetEditorWindow()) + { + animInspector->Open(asset->id); + } + break; + case AssetType::MESH: break; case AssetType::SCENE: - { - if(editor->LoadScene(asset->id)) - { - editor->editorConfig->workingSceneID = asset->id; - } - } + if (editor->LoadScene(asset->id)) + { + editor->editorConfig->workingSceneID = asset->id; + } break; case AssetType::PREFAB: break; case AssetType::MATERIAL: diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp new file mode 100644 index 00000000..c2ccdb86 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -0,0 +1,170 @@ +/************************************************************************************//*! +\file SHRawAnimInspector.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 1, 2023 +\brief Contains the definition of SHRawAnimInspector's functions. + + +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. +*//*************************************************************************************/ +#include "SHpch.h" +#include "SHRawAnimInspector.h" + +// STL Includes +#include +// External Dependencies +#include +#include +// Project Includes +#include "Editor/IconsMaterialDesign.h" +#include "Animation/SHAnimationClip.h" +#include "Resource/SHResourceManager.h" +#include "Editor/EditorWindow/SHEditorWindowManager.h" +#include "Editor/SHEditorUI.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* SHAnimClipCreatePrompt - Cosntructors/Destructors */ + /*-----------------------------------------------------------------------------------*/ + SHAnimClipCreatePrompt::SHAnimClipCreatePrompt() + : SHPopUpWindow("Create Animation Clip", true, 0, 0) {} + + /*---------------------------------------------------------------------------------*/ + /* SHAnimClipCreatePrompt - Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ + void SHAnimClipCreatePrompt::Init(Handle rawAnim) + { + rawAnimation = rawAnim; + + // Set default parameters + if (rawAnimation) + { + newAssetName.clear(); + firstIndex = 0; + lastIndex = rawAnimation->GetTotalFrames(); + } + } + + void SHAnimClipCreatePrompt::Draw() + { + if (Begin()) + { + // Properties + SHEditorUI::InputTextField("Name", newAssetName); + SHEditorUI::PushID(0); + SHEditorUI::InputSlider("First Frame Index", 0, rawAnimation->GetTotalFrames(), firstIndex); + SHEditorUI::PopID(); + SHEditorUI::PushID(1); + SHEditorUI::InputSlider("Last Frame Index", 0, rawAnimation->GetTotalFrames(), lastIndex); + SHEditorUI::PopID(); + + // Invalid values + const bool INVALID_CONFIG = newAssetName.empty() || firstIndex > lastIndex || lastIndex < firstIndex; + + // Buttons + ImGui::BeginDisabled(INVALID_CONFIG); + { + if (ImGui::Button("Save")) + { + // Generate new asset + + + // Close + isOpen = false; + ImGui::CloseCurrentPopup(); + } + } + ImGui::EndDisabled(); + ImGui::SameLine(); + if (ImGui::Button("Cancel")) + { + // Close + isOpen = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Cosntructors/Destructors */ + /*-----------------------------------------------------------------------------------*/ + SHRawAnimInspector::SHRawAnimInspector() + : SHEditorWindow("Animation Editor", ImGuiWindowFlags_MenuBar) + {} + + /*-----------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHRawAnimInspector::Init() + { + SHEditorWindow::Init(); + + SHEditorWindowManager::CreatePopupWindow(); + } + + void SHRawAnimInspector::Update() + { + SHEditorWindow::Update(); + + // Draw + if (Begin()) + { + + // Ignore if no asset + if (currRawAnim) + { + drawMenuBar(); + + + + // Button to add a new clip + if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data())) + { + auto prompt = SHEditorWindowManager::GetPopupWindow(); + prompt->Init(currRawAnim); + prompt->isOpen = true; + } + + // Render all clips + } + } + ImGui::End(); + } + + void SHRawAnimInspector::Exit() + { + SHEditorWindow::Exit(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHRawAnimInspector::Open(AssetID assetId) + { + currRawAnim = SHResourceManager::LoadOrGet(assetId); + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHRawAnimInspector::drawMenuBar() + { + if (ImGui::BeginMenuBar()) + { + if (ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) + { + + } + + const std::string& ASSET_NAME = SHResourceManager::GetAssetName(currRawAnim).value_or("Unnamed Asset"); + ImGui::Text(ASSET_NAME.c_str()); + + ImGui::EndMenuBar(); + } + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h new file mode 100644 index 00000000..c2006d87 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h @@ -0,0 +1,86 @@ +/************************************************************************************//*! +\file SHRawAnimInspector.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 2, 2023 +\brief Contains the definition of SHRawAnimInspector. + +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 "Assets/SHAssetMacros.h" +#include "Editor/EditorWindow/SHEditorWindow.h" +#include "Resource/SHHandle.h" +#include "Animation/SHRawAnimation.h" +#include "Editor/EditorWindow/SHPopUpWindow.h" + +namespace SHADE +{ + /// + /// Prompt for creating an animation clip. Init() must be called to pass in the correct + /// SHRawAnimation that the created clip will use. + /// + class SHAnimClipCreatePrompt : public SHPopUpWindow + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors/Destructors */ + /*---------------------------------------------------------------------------------*/ + SHAnimClipCreatePrompt(); + + /*---------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ + void Init(Handle rawAnim); + void Draw() override; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + std::string newAssetName; + int firstIndex; + int lastIndex; + Handle rawAnimation; + }; + + /// + /// Editor for generating SHAnimationClips from a single SHRawAnimation object. + /// + class SHRawAnimInspector final : public SHEditorWindow + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors/Destructors */ + /*---------------------------------------------------------------------------------*/ + SHRawAnimInspector(); + ~SHRawAnimInspector() = default; + + /*---------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ + void Init() override; + void Update() override; + void Exit() override; + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void Open(AssetID assetId); + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + Handle currRawAnim; + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + void drawMenuBar(); + }; +} diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h index 829a1871..e0247d69 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h @@ -1,11 +1,12 @@ #pragma once -#include "MenuBar/SHEditorMenuBar.h" // Menu Bar -#include "HierarchyPanel/SHHierarchyPanel.h" // Hierarchy Panel -#include "Inspector/SHEditorInspector.h" // Inspector -#include "Profiling/SHEditorProfiler.h" // Profiler -#include "ViewportWindow/SHEditorViewport.h" // Editor Viewport -#include "AssetBrowser/SHAssetBrowser.h" // Asset Browser -#include "MaterialInspector/SHMaterialInspector.h" // Material Inspector -#include "ColliderTagPanel/SHColliderTagPanel.h" // Collider Tag Panel -#include "InputBindings/SHInputBindingsPanel.h" // Input Bindings -#include "EditorWindow/Animation/SHAnimationControllerEditor.h" // Animation Controller Editor \ No newline at end of file +#include "MenuBar/SHEditorMenuBar.h" // Menu Bar +#include "HierarchyPanel/SHHierarchyPanel.h" // Hierarchy Panel +#include "Inspector/SHEditorInspector.h" // Inspector +#include "Profiling/SHEditorProfiler.h" // Profiler +#include "ViewportWindow/SHEditorViewport.h" // Editor Viewport +#include "AssetBrowser/SHAssetBrowser.h" // Asset Browser +#include "MaterialInspector/SHMaterialInspector.h" // Material Inspector +#include "ColliderTagPanel/SHColliderTagPanel.h" // Collider Tag Panel +#include "InputBindings/SHInputBindingsPanel.h" // Input Bindings +#include "EditorWindow/Animation/SHAnimationControllerEditor.h" // Animation Controller Editor +#include "EditorWindow/RawAnimationInspector/SHRawAnimInspector.h" // Raw Animation Inspector diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 904a239b..1b45073c 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -118,6 +118,7 @@ namespace SHADE SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); //Add popup windows SHEditorWindowManager::CreatePopupWindow(); From 6779f48b5a2f6603fc22c2b42e95a2416a15da91 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 2 Mar 2023 17:33:02 +0800 Subject: [PATCH 13/69] Fixed typo --- .../EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index c2ccdb86..c8b32dff 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -28,7 +28,7 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { /*-----------------------------------------------------------------------------------*/ - /* SHAnimClipCreatePrompt - Cosntructors/Destructors */ + /* SHAnimClipCreatePrompt - Constructors/Destructors */ /*-----------------------------------------------------------------------------------*/ SHAnimClipCreatePrompt::SHAnimClipCreatePrompt() : SHPopUpWindow("Create Animation Clip", true, 0, 0) {} From 69fa0d4da03bc7af71085eaaeed3aa9a77e7a52b Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 2 Mar 2023 17:44:28 +0800 Subject: [PATCH 14/69] Fixed SHRawAnimInspector warnings --- .../EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp | 2 +- .../EditorWindow/RawAnimationInspector/SHRawAnimInspector.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index c8b32dff..0734121e 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -63,7 +63,7 @@ namespace SHADE SHEditorUI::PopID(); // Invalid values - const bool INVALID_CONFIG = newAssetName.empty() || firstIndex > lastIndex || lastIndex < firstIndex; + const bool INVALID_CONFIG = newAssetName.empty() || firstIndex > lastIndex; // Buttons ImGui::BeginDisabled(INVALID_CONFIG); diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h index c2006d87..1b3c4855 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h @@ -43,8 +43,8 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ std::string newAssetName; - int firstIndex; - int lastIndex; + int firstIndex = 0; + int lastIndex = 0; Handle rawAnimation; }; From 184fd4f459390e678e6c9c3d1a544a1eea16dacd Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 3 Mar 2023 17:16:23 +0800 Subject: [PATCH 15/69] [NOT TESTED] Animation Clip asset reading/writing as asset file into binary implemented --- .../src/Assets/Asset Types/SHAnimClipAsset.h | 8 +-- .../Libraries/Loaders/SHBinaryLoader.cpp | 61 +++++++++++++++++++ .../Assets/Libraries/Loaders/SHBinaryLoader.h | 12 ++++ .../Libraries/Loaders/SHTextBasedLoader.cpp | 22 ++++--- .../Libraries/Loaders/SHTextBasedLoader.h | 4 -- SHADE_Engine/src/Assets/SHAssetMacros.h | 9 ++- SHADE_Engine/src/Assets/SHAssetManager.cpp | 24 +++++++- 7 files changed, 118 insertions(+), 22 deletions(-) create mode 100644 SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp create mode 100644 SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h index a1bd87a6..c6887316 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipAsset.h @@ -11,18 +11,18 @@ of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ #pragma once -#include - #include "SH_API.h" #include "SHAssetData.h" +#include + namespace SHADE { struct SH_API SHAnimClipAsset : SHAssetData { std::string name; AssetID animRawDataAssetId; - int firstIndex; - int lastIndex; + uint32_t firstIndex; + uint32_t lastIndex; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp new file mode 100644 index 00000000..8ea85811 --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp @@ -0,0 +1,61 @@ +#include "SHpch.h" +#include "SHBinaryLoader.h" + +#include "Assets/Asset Types/SHAnimClipAsset.h" + +#include + +namespace SHADE +{ + SHAssetData* SHBinaryLoader::Load(AssetPath path) + { + std::ifstream file{ path, std::ios::in | std::ios::binary }; + if (!file.is_open()) + { + SHLOG_ERROR("[Binary Loader] Unable to open file for reading: {}", path.string()); + return nullptr; + } + + auto const extension = path.extension().string(); + SHAssetData* result{nullptr}; + + if (extension == ANIM_CLIP_EXTENSION) + { + const auto data = new SHAnimClipAsset(); + file.read( + reinterpret_cast(&data->animRawDataAssetId), + sizeof(uint32_t) * 3 + ); + data->name = path.stem().string(); + result = data; + } + + file.close(); + + return result; + } + + void SHBinaryLoader::Write(SHAssetData const* data, AssetPath path) + { + std::ofstream file{ path, std::ios::out | std::ios::binary }; + + if (!file.is_open()) + { + SHLOG_ERROR("[Binary Loader] Unable to open file for writing: {}", path.string()); + return; + } + + auto const extension = path.extension().string(); + + if (extension == ANIM_CLIP_EXTENSION) + { + auto animClip = dynamic_cast(data); + file.write( + reinterpret_cast(&animClip->animRawDataAssetId), + sizeof(uint32_t) * 3 + ); + } + + file.close(); + } +} diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h new file mode 100644 index 00000000..db2316e8 --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h @@ -0,0 +1,12 @@ +#pragma once + +#include "SHAssetLoader.h" + +namespace SHADE +{ + struct SHBinaryLoader : SHAssetLoader + { + SHAssetData* Load(AssetPath path) override; + void Write(SHAssetData const* data, AssetPath path) override; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp index 4858e639..d112b9d1 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp @@ -26,32 +26,32 @@ namespace SHADE if (!file.is_open()) { - SHLOG_ERROR("[Text Loader] Unable to open text File: {}", path.string()); + SHLOG_ERROR("[Text Loader] Unable to open text file for reading: {}", path.string()); return nullptr; } + std::stringstream stream; - stream << file.rdbuf(); - std::string content = stream.str(); + auto const extension = path.extension().string(); SHAssetData* result; - if (path.extension().string() == SCENE_EXTENSION) + if (extension == SCENE_EXTENSION) { auto data = new SHSceneAsset(); data->name = path.stem().string(); data->data = std::move(content); result = data; } - else if (path.extension().string() == PREFAB_EXTENSION) + else if (extension == PREFAB_EXTENSION) { auto data = new SHPrefabAsset(); data->name = path.stem().string(); data->data = std::move(content); result = data; } - else if (path.extension().string() == MATERIAL_EXTENSION) + else if (extension == MATERIAL_EXTENSION) { auto data = new SHMaterialAsset(); data->name = path.stem().string(); @@ -70,21 +70,23 @@ namespace SHADE if (!file.is_open()) { - SHLOG_ERROR("[Text Loader] Unable to open text File: {}", path.string()); + SHLOG_ERROR("[Text Loader] Unable to open text file for writing: {}", path.string()); return; } - if (path.extension().string() == SCENE_EXTENSION) + auto const extension = path.extension().string(); + + if (extension == SCENE_EXTENSION) { auto scene = dynamic_cast(data); file << scene->data; } - else if (path.extension().string() == PREFAB_EXTENSION) + else if (extension == PREFAB_EXTENSION) { auto prefab = dynamic_cast(data); file << prefab->data; } - else if (path.extension().string() == MATERIAL_EXTENSION) + else if (extension == MATERIAL_EXTENSION) { auto material = dynamic_cast(data); file << material->data; diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h index b74c6c94..80771058 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h @@ -11,10 +11,6 @@ #pragma once #include "SHAssetLoader.h" -#include "Assets/Asset Types/SHPrefabAsset.h" -#include "Assets/Asset Types/SHSceneAsset.h" -#include "Assets/Asset Types/SHMaterialAsset.h" - namespace SHADE { struct SHTextBasedLoader : SHAssetLoader diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 33891d7f..510bc35a 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -7,6 +7,7 @@ * or disclosure of this file or its contents without the prior * written consent of Digipen Institute of Technology is prohibited ******************************************************************************/ +// ReSharper disable All #ifndef SH_ASSET_MACROS_H #define SH_ASSET_MACROS_H @@ -28,12 +29,12 @@ enum FMOD_SPEAKERMODE : int; // Typedefs typedef uint32_t AssetID; -typedef std::string AssetName; +using AssetName = std::string; typedef std::filesystem::path AssetPath; typedef unsigned char* AssetData; typedef std::string AssetMetaVersion; typedef std::string AssetExtension; -typedef size_t AssetTypeMeta; +typedef size_t AssetTypeMeta; typedef FMOD::Sound* SHSound; @@ -56,6 +57,7 @@ enum class AssetType : AssetTypeMeta MESH, SCRIPT, FONT, + ANIM_CLIP, MAX_COUNT }; constexpr size_t TYPE_COUNT{ static_cast(AssetType::MAX_COUNT) }; @@ -77,6 +79,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/" }; // ASSET EXTENSIONS @@ -92,6 +95,7 @@ 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 EXTENSIONS[] = { AUDIO_EXTENSION, @@ -106,6 +110,7 @@ constexpr std::string_view EXTENSIONS[] = { SCRIPT_EXTENSION, FONT_EXTENSION, AUDIO_WAV_EXTENSION, + ANIM_CLIP_EXTENSION }; constexpr size_t EXTENSIONS_COUNT{ 11 }; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index b7f7fbb4..503f9082 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -21,8 +21,13 @@ #include "Libraries/Loaders/SHShaderSourceLoader.h" #include "Libraries/Loaders/SHTextBasedLoader.h" #include "Libraries/Loaders/SHFontLoader.h" +#include "Libraries/Loaders/SHBinaryLoader.h" + +#include "Asset Types/SHPrefabAsset.h" +#include "Asset Types/SHMaterialAsset.h" +#include "Asset Types/SHSceneAsset.h" +#include "Asset Types/SHAnimClipAsset.h" -//#include "Libraries/Compilers/SHMeshCompiler.h" #include "Libraries/Compilers/SHTextureCompiler.h" #include "Libraries/Compilers/SHShaderSourceCompiler.h" @@ -233,6 +238,19 @@ namespace SHADE } break; + case AssetType::ANIM_CLIP: + newPath += ANIM_CLIP_FOLDER; + newPath += name; + newPath += ANIM_CLIP_EXTENSION; + + { + auto animClip = new SHAnimClipAsset(); + animClip->name = name; + data = animClip; + } + break; + + default: SHLOG_ERROR("[Asset Manager] Asset type of {} not an internal asset type, cannot be created", name); return 0; @@ -274,7 +292,8 @@ namespace SHADE if ( asset.type == AssetType::SCENE || asset.type == AssetType::PREFAB || - asset.type == AssetType::MATERIAL + asset.type == AssetType::MATERIAL || + asset.type == AssetType::ANIM_CLIP ) { if (assetData.contains(id)) @@ -528,6 +547,7 @@ 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()); } /**************************************************************************** From beeeae99ca500c98887210ff05033205c5a4cf36 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 3 Mar 2023 18:53:59 +0800 Subject: [PATCH 16/69] SHRawAnimInspector can now generate incomplete animation clips --- Assets/Animation Clips/Main | Bin 0 -> 289 bytes .../SHRawAnimInspector.cpp | 86 ++++++++++++++++-- .../SHRawAnimInspector.h | 15 ++- .../src/Resource/SHResourceManager.hpp | 6 +- 4 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 Assets/Animation Clips/Main diff --git a/Assets/Animation Clips/Main b/Assets/Animation Clips/Main new file mode 100644 index 0000000000000000000000000000000000000000..ac5a59fa92d3f11764856a8a751c2dab31a24899 GIT binary patch literal 289 vcmeZE%uTgY@J-CjWB5060WX)QiYxGN literal 0 HcmV?d00001 diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index 0734121e..0dc44bc4 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -24,6 +24,7 @@ of DigiPen Institute of Technology is prohibited. #include "Resource/SHResourceManager.h" #include "Editor/EditorWindow/SHEditorWindowManager.h" #include "Editor/SHEditorUI.h" +#include "Assets/SHAssetManager.h" namespace SHADE { @@ -36,7 +37,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* SHAnimClipCreatePrompt - Lifecycle Functions */ /*---------------------------------------------------------------------------------*/ - void SHAnimClipCreatePrompt::Init(Handle rawAnim) + void SHAnimClipCreatePrompt::Init(Handle rawAnim, std::function onClose) { rawAnimation = rawAnim; @@ -47,6 +48,9 @@ namespace SHADE firstIndex = 0; lastIndex = rawAnimation->GetTotalFrames(); } + + // Assign callback + this->onClose = onClose; } void SHAnimClipCreatePrompt::Draw() @@ -71,10 +75,17 @@ namespace SHADE if (ImGui::Button("Save")) { // Generate new asset - + const AssetID NEW_ASSET_ID = SHAssetManager::CreateNewAsset(AssetType::ANIM_CLIP, newAssetName); + auto animClip = SHAssetManager::GetData(NEW_ASSET_ID); + animClip->animRawDataAssetId = SHResourceManager::GetAssetID(rawAnimation).value_or(INVALID_ASSET_ID); + animClip->firstIndex = firstIndex; + animClip->lastIndex = lastIndex; + SHAssetManager::SaveAsset(NEW_ASSET_ID); // Close isOpen = false; + if (onClose) + onClose(NEW_ASSET_ID); ImGui::CloseCurrentPopup(); } } @@ -84,6 +95,8 @@ namespace SHADE { // Close isOpen = false; + if (onClose) + onClose(INVALID_ASSET_ID); ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); @@ -114,26 +127,62 @@ namespace SHADE // Draw if (Begin()) { - // Ignore if no asset if (currRawAnim) { drawMenuBar(); - - // Button to add a new clip if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data())) { auto prompt = SHEditorWindowManager::GetPopupWindow(); - prompt->Init(currRawAnim); + prompt->Init(currRawAnim, [this](AssetID createdAssetId) + { + if (createdAssetId != INVALID_ASSET_ID) + { + childAnimClips.emplace_back(SHResourceManager::LoadOrGet(createdAssetId)); + } + }); prompt->isOpen = true; } // Render all clips + for (auto animClip : childAnimClips) + { + bool changed = false; + std::optional animClipName = SHResourceManager::GetAssetName(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(assetId.value()); + animAsset->firstIndex = firstIndex; + animAsset->lastIndex = endIndex; + SHAssetManager::SaveAsset(assetId.value()); + } + } + } } + ImGui::End(); } - ImGui::End(); } void SHRawAnimInspector::Exit() @@ -147,6 +196,12 @@ namespace SHADE void SHRawAnimInspector::Open(AssetID assetId) { currRawAnim = SHResourceManager::LoadOrGet(assetId); + + // Load anim clips + if (currRawAnim) + { + childAnimClips = getChildAnimClips(assetId); + } } /*-----------------------------------------------------------------------------------*/ @@ -167,4 +222,21 @@ namespace SHADE ImGui::EndMenuBar(); } } + + std::vector> SHRawAnimInspector::getChildAnimClips(AssetID rawAnimId) + { + 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)); + } + } + + return animClips; + } } \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h index 1b3c4855..b6857568 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h @@ -20,6 +20,16 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + struct SHAnimClipAsset; + class SHRawAnimation; + class SHAnimationClip; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ /// /// Prompt for creating an animation clip. Init() must be called to pass in the correct /// SHRawAnimation that the created clip will use. @@ -35,7 +45,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*---------------------------------------------------------------------------------*/ - void Init(Handle rawAnim); + void Init(Handle rawAnim, std::function onClose = nullptr); void Draw() override; private: @@ -46,6 +56,7 @@ namespace SHADE int firstIndex = 0; int lastIndex = 0; Handle rawAnimation; + std::function onClose; }; /// @@ -77,10 +88,12 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ Handle currRawAnim; + std::vector> childAnimClips; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ /*---------------------------------------------------------------------------------*/ void drawMenuBar(); + std::vector> getChildAnimClips(AssetID rawAnimId); }; } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index be6cc5e6..f2469833 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -368,9 +368,9 @@ namespace SHADE loadedAssetData.emplace_back(assetId); return resourceHub.Create ( - LoadOrGet(assetData->animRawDataAssetId), - assetData->firstIndex, - assetData->lastIndex + LoadOrGet(assetData.animRawDataAssetId), + assetData.firstIndex, + assetData.lastIndex ); } else if constexpr (std::is_same_v) From 41784d4c043b82e8515c4b945d89ebdcfab602b6 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 3 Mar 2023 21:28:28 +0800 Subject: [PATCH 17/69] Fixed animation clips list for Raw Animation Inspector --- .../SHRawAnimInspector.cpp | 80 ++++++++++++------- .../src/Resource/SHResourceManager.hpp | 2 + 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index 0dc44bc4..fffc5005 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -25,6 +25,7 @@ of DigiPen Institute of Technology is prohibited. #include "Editor/EditorWindow/SHEditorWindowManager.h" #include "Editor/SHEditorUI.h" #include "Assets/SHAssetManager.h" +#include "Editor/SHEditorWidgets.hpp" namespace SHADE { @@ -133,7 +134,7 @@ namespace SHADE drawMenuBar(); // Button to add a new clip - if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data())) + if (ImGui::Button(std::format("{} Create Animation Clip", ICON_MD_ADD).data())) { auto prompt = SHEditorWindowManager::GetPopupWindow(); prompt->Init(currRawAnim, [this](AssetID createdAssetId) @@ -146,39 +147,56 @@ namespace SHADE prompt->isOpen = true; } - // Render all clips - for (auto animClip : childAnimClips) + // Render all animation clips + if (SHEditorUI::CollapsingHeader("Existing Animation Clips")) { - bool changed = false; - std::optional animClipName = SHResourceManager::GetAssetName(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) + ImGui::Indent(); + for (auto animClip : childAnimClips) { - auto assetId = SHResourceManager::GetAssetID(animClip); - if (assetId.has_value()) + bool changed = false; + std::optional animClipName = SHResourceManager::GetAssetName(animClip); + + int firstIndex = animClip->GetStartFrameIndex(); + int endIndex = animClip->GetEndFrameIndex(); + + ImGui::Separator(); + ImGui::Text(animClipName.has_value() ? animClipName.value().c_str() : ""); + changed |= SHEditorWidgets::SliderInt + ( + "Start", 0, currRawAnim->GetTotalFrames(), + [&]() { return firstIndex; }, + [&](int i) { firstIndex = i; } + ); + changed |= SHEditorWidgets::SliderInt + ( + "End", 0, currRawAnim->GetTotalFrames(), + [&]() { return endIndex; }, + [&](int i) { endIndex = i; } + ); + + // If there's a change we need to commit changes + if (changed && firstIndex < endIndex) { - auto animAsset = SHAssetManager::GetData(assetId.value()); - animAsset->firstIndex = firstIndex; - animAsset->lastIndex = endIndex; - SHAssetManager::SaveAsset(assetId.value()); + // Update runtime asset + *animClip = SHAnimationClip(currRawAnim, firstIndex, endIndex); + + // Update serialized asset + auto assetId = SHResourceManager::GetAssetID(animClip); + if (assetId.has_value()) + { + auto animAsset = SHAssetManager::GetData(assetId.value()); + animAsset->firstIndex = firstIndex; + animAsset->lastIndex = endIndex; + SHAssetManager::SaveAsset(assetId.value()); + } } } + + // Extra separator if there is more than one + if (!childAnimClips.empty()) + ImGui::Separator(); + + ImGui::Unindent(); } } ImGui::End(); @@ -202,6 +220,10 @@ namespace SHADE { childAnimClips = getChildAnimClips(assetId); } + else + { + childAnimClips.clear(); + } } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index f2469833..cdda1ad7 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -361,6 +361,8 @@ namespace SHADE else if constexpr (std::is_same_v) { loadedAssetData.emplace_back(assetId); + if (assetData.anims.empty()) + return {}; return resourceHub.Create(*assetData.anims[0]); } else if constexpr (std::is_same_v) From 97605cc8fe7043171b92d893f6d110f4fd0fd898 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 3 Mar 2023 22:00:42 +0800 Subject: [PATCH 18/69] Added preliminary implementation of animation controller connection attributes --- .../Animation/SHAnimationControllerEditor.cpp | 41 ++++++++++++++++++- .../Animation/SHAnimationControllerEditor.h | 2 +- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 65c4d010..31a38121 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -21,7 +21,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "Editor/IconsMaterialDesign.h" #include "Animation/SHAnimationController.h" -#include "../../SHEditorUI.h" +#include "Editor/SHEditorUI.h" namespace SHADE { @@ -50,10 +50,29 @@ namespace SHADE ImNodes::BeginNodeEditor(); { + /* Pre Process Nodes */ + std::unordered_map, int> inputAttribCount; + std::unordered_map, int> outputAttribCount; + for (auto node : controller.GetNodes()) + { + // Have at least one for each + inputAttribCount[node] = 1; + outputAttribCount[node] = 1; + } + for (auto node : controller.GetNodes()) + { + for (auto transition : node->Transitions) + { + ++inputAttribCount[transition.Target]; + } + outputAttribCount[node] += node->Transitions.size(); + } + /* Draw Nodes */ int id = 0; for (auto node : controller.GetNodes()) { + // Draw the node ImNodes::BeginNode(id); { // Title @@ -72,6 +91,26 @@ namespace SHADE ImGui::PushItemWidth(80.0f); ImGui::InputText("", buffer.data(), buffer.size()); ImGui::PopItemWidth(); + + // Input Nodes + for (int i = 0; i < inputAttribCount[node]; ++i) + { + NodeAttributeIndex nidx; + nidx.OwnerNodeIndex = id; + nidx.AttributeIndex = i; + ImNodes::BeginInputAttribute(nidx.Raw); + ImNodes::EndInputAttribute(); + } + + // Output Nodes + for (int i = 0; i < outputAttribCount[node]; ++i) + { + NodeAttributeIndex nidx; + nidx.OwnerNodeIndex = id; + nidx.AttributeIndex = inputAttribCount[node] + i; + ImNodes::BeginOutputAttribute(nidx.Raw); + ImNodes::EndOutputAttribute(); + } } ImNodes::EndNode(); ++id; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h index 03da7771..a78d2fd6 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h @@ -60,7 +60,7 @@ namespace SHADE NodeAttributeIndex SourceAttribute; NodeAttributeIndex DestinationAttribute; }; - }; // What about same source and destination but different link? + }; /*---------------------------------------------------------------------------------*/ /* Data Members */ From b93a08fa9039a994f6a648e1b86a77d77fde8ce1 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 4 Mar 2023 00:48:10 +0800 Subject: [PATCH 19/69] Fixed ImGui crash with SHRawAnimationInspector --- .../EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index fffc5005..e4b7f94d 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -199,8 +199,8 @@ namespace SHADE ImGui::Unindent(); } } - ImGui::End(); } + ImGui::End(); } void SHRawAnimInspector::Exit() From 32adb0c540ef4c74041f4e7bfc31f72aa0c068d6 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 5 Mar 2023 01:08:39 +0800 Subject: [PATCH 20/69] Reworked how AnimationControllerEditor works --- .../src/Animation/SHAnimationController.h | 2 +- .../Animation/SHAnimationControllerEditor.cpp | 330 ++++++++++++++---- .../Animation/SHAnimationControllerEditor.h | 67 +++- SHADE_Engine/src/Editor/SHEditorUI.cpp | 9 + SHADE_Engine/src/Editor/SHEditorUI.h | 14 +- 5 files changed, 334 insertions(+), 88 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index ca6fbf70..a7acb772 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -103,10 +103,10 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ /* Data Members */ /*-------------------------------------------------------------------------------*/ + Handle Target; ConditionType Condition; AnimParam Param; std::string ParamName; - Handle Target; /*-------------------------------------------------------------------------------*/ /* Usage Functions */ diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 31a38121..84db473c 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -38,6 +38,25 @@ namespace SHADE void SHAnimationControllerEditor::Init() { SHEditorWindow::Init(); + + SHAnimationController controller; + auto n1 = controller.CreateNode(); + auto n2 = controller.CreateNode(); + auto n3 = controller.CreateNode(); + + n1->Name = "N1"; + n2->Name = "N2"; + n3->Name = "N3"; + + SHAnimationController::Transition t; + t.Target = n3; + + n1->Transitions.emplace_back(t); + n2->Transitions.emplace_back(t); + t.Target = n1; + n3->Transitions.emplace_back(t); + + Open(controller); } void SHAnimationControllerEditor::Update() @@ -46,79 +65,17 @@ namespace SHADE if (Begin()) { - drawMenuBar(); - - ImNodes::BeginNodeEditor(); + + // Only render the node editor if there is controller data + if (controllerData.has_value()) { - /* Pre Process Nodes */ - std::unordered_map, int> inputAttribCount; - std::unordered_map, int> outputAttribCount; - for (auto node : controller.GetNodes()) - { - // Have at least one for each - inputAttribCount[node] = 1; - outputAttribCount[node] = 1; - } - for (auto node : controller.GetNodes()) - { - for (auto transition : node->Transitions) - { - ++inputAttribCount[transition.Target]; - } - outputAttribCount[node] += node->Transitions.size(); - } - - /* Draw Nodes */ - int id = 0; - for (auto node : controller.GetNodes()) - { - // Draw the node - ImNodes::BeginNode(id); - { - // Title - ImNodes::BeginNodeTitleBar(); - { - ImGui::TextUnformatted(node->Name.c_str()); - ImGui::SameLine(); - ImGui::Button(ICON_MD_EDIT); - } - ImNodes::EndNodeTitleBar(); - - // Body - ImGui::Text("Clip"); - ImGui::SameLine(); - std::array buffer = { '\0' }; - ImGui::PushItemWidth(80.0f); - ImGui::InputText("", buffer.data(), buffer.size()); - ImGui::PopItemWidth(); - - // Input Nodes - for (int i = 0; i < inputAttribCount[node]; ++i) - { - NodeAttributeIndex nidx; - nidx.OwnerNodeIndex = id; - nidx.AttributeIndex = i; - ImNodes::BeginInputAttribute(nidx.Raw); - ImNodes::EndInputAttribute(); - } - - // Output Nodes - for (int i = 0; i < outputAttribCount[node]; ++i) - { - NodeAttributeIndex nidx; - nidx.OwnerNodeIndex = id; - nidx.AttributeIndex = inputAttribCount[node] + i; - ImNodes::BeginOutputAttribute(nidx.Raw); - ImNodes::EndOutputAttribute(); - } - } - ImNodes::EndNode(); - ++id; - } + drawActiveMenuBar(); + drawNodeEditor(); + } + else + { + SHEditorUI::CenteredText("No animation controller is selected."); } - - ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_BottomRight); - ImNodes::EndNodeEditor(); } ImGui::End(); } @@ -128,19 +85,246 @@ namespace SHADE SHEditorWindow::Exit(); } + void SHAnimationControllerEditor::Open(const SHAnimationController& controller) + { + controllerData = deserialise(controller); + } /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ - void SHAnimationControllerEditor::drawMenuBar() + void SHAnimationControllerEditor::drawActiveMenuBar() { if (ImGui::BeginMenuBar()) { + if (ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) + { + // TODO + } if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data())) { - controller.CreateNode(); + createNode(controllerData.value()); } ImGui::EndMenuBar(); } } + + void SHAnimationControllerEditor::drawNodeEditor() + { + static constexpr float NODE_WIDTH = 80.0f; + + ImNodes::BeginNodeEditor(); + { + /* Draw Nodes */ + for (auto& node : controllerData->Nodes) + { + // Draw the node + ImNodes::BeginNode(node.Index); + { + // Title + ImNodes::BeginNodeTitleBar(); + { + if (node.EditingName) + { + if (ImGui::Button(ICON_MD_DONE)) + { + node.EditingName = false; + } + ImGui::SameLine(); + static constexpr float TEXT_FIELD_PADDING = 15.0f; + ImGui::SetNextItemWidth(std::max(ImGui::CalcTextSize(node.Name.c_str()).x + TEXT_FIELD_PADDING, NODE_WIDTH)); + SHEditorUI::InputTextField("", node.Name); + } + else + { + if (ImGui::Button(ICON_MD_EDIT)) + { + node.EditingName = true; + } + ImGui::SameLine(); + ImGui::Text(node.Name.c_str()); + } + } + ImNodes::EndNodeTitleBar(); + + // Body + ImGui::Text("Clip"); + ImGui::SameLine(); + std::array buffer = { '\0' }; + ImGui::SetNextItemWidth(std::max(NODE_WIDTH, ImGui::CalcTextSize(buffer.data()).x)); + ImGui::InputText("", buffer.data(), buffer.size()); + + // Input Nodes + for (auto inputAttrib : node.InputAttribs) + { + drawInputNode(inputAttrib.Raw, ImNodesPinShape_CircleFilled); + } + + // Render an extra input + drawInputNode(getExtraInputAttrib(node.Index).Raw, ImNodesPinShape_Circle); + + // Output Nodes + for (auto outputAttrib : node.OutputAttribs) + { + drawOutputNode(outputAttrib.Raw, node.Index, ImNodesPinShape_TriangleFilled); + } + + // Render an extra output + drawOutputNode(getExtraOutputAttrib(node.Index).Raw, node.Index, ImNodesPinShape_Triangle); + } + ImNodes::EndNode(); + } + + // Draw links + for (auto link : controllerData->Links) + { + ImNodes::Link(link.first, link.second.SourceAttrib.Raw, link.second.DestAttrib.Raw); + } + } + + ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_BottomRight); + ImNodes::EndNodeEditor(); + + int sourceAttrib, destAttrib; + if (ImNodes::IsLinkCreated(&sourceAttrib, &destAttrib)) + { + // Get the two indices + NodeAttributeIndex sourceAttribIndex, destAttribIndex; + sourceAttribIndex.Raw = static_cast(sourceAttrib); + destAttribIndex.Raw = static_cast(destAttrib); + + // Ensure that we can access the nodes + if (controllerData->IndexToNodeMap.contains(sourceAttribIndex.OwnerNodeIndex) && + controllerData->IndexToNodeMap.contains(destAttribIndex.OwnerNodeIndex)) + { + // Retrieve the nodes + auto inputNodeIter = controllerData->IndexToNodeMap[sourceAttribIndex.OwnerNodeIndex]; + auto outputNodeIter = *controllerData->IndexToNodeMap[destAttribIndex.OwnerNodeIndex]; + + // Create link + createLink + ( + controllerData.value(), + controllerData->IndexToNodeMap[sourceAttribIndex.OwnerNodeIndex], + controllerData->IndexToNodeMap[destAttribIndex.OwnerNodeIndex] + ); + } + } + } + SHAnimationControllerEditor::NodeAttributeIndex SHAnimationControllerEditor::getExtraInputAttrib(uint32_t nodeIndex) + { + NodeAttributeIndex extraInputAttrib; + extraInputAttrib.OwnerNodeIndex = nodeIndex; + extraInputAttrib.AttributeIndex = std::numeric_limits::lowest(); + return extraInputAttrib; + } + SHAnimationControllerEditor::NodeAttributeIndex SHAnimationControllerEditor::getExtraOutputAttrib(uint32_t nodeIndex) + { + NodeAttributeIndex extraOutputAttrib; + extraOutputAttrib.OwnerNodeIndex = nodeIndex; + extraOutputAttrib.AttributeIndex = std::numeric_limits::max(); + return extraOutputAttrib; + } + void SHAnimationControllerEditor::drawInputNode(int id, ImNodesPinShape_ pinShape) + { + ImNodes::BeginInputAttribute(id, pinShape); + ImGui::Text("Input"); + ImNodes::EndInputAttribute(); + } + void SHAnimationControllerEditor::drawOutputNode(int id, int parentNodeId, ImNodesPinShape_ pinShape) + { + static char const* TITLE = "Output"; + static float RIGHT_PADDING = 20.0f; + + ImNodes::BeginOutputAttribute(id, ImNodesPinShape_TriangleFilled); + ImGui::Indent(ImNodes::GetNodeDimensions(parentNodeId).x - ImGui::CalcTextSize(TITLE).x - RIGHT_PADDING); + ImGui::Text(TITLE); + ImNodes::EndOutputAttribute(); + } + std::list::iterator SHAnimationControllerEditor::createNode(AnimControllerData& data) + { + Node localNode; + localNode.Index = data.NextNodeIndex++; + data.Nodes.emplace_back(std::move(localNode)); + + // Update the node map + auto nodeIter = --data.Nodes.end(); + data.IndexToNodeMap[localNode.Index] = nodeIter; + + return nodeIter; + } + void SHAnimationControllerEditor::createLink(AnimControllerData& data, std::list::iterator sourceNode, std::list::iterator destNode) + { + // Update source node's output attributes + NodeAttributeIndex attribIndex; + attribIndex.OwnerNodeIndex = sourceNode->Index; + attribIndex.AttributeIndex = static_cast(sourceNode->OutputAttribs.size() + 1); + sourceNode->OutputAttribs.emplace_back(attribIndex); + + // Update target node's input attributes + attribIndex.OwnerNodeIndex = destNode->Index; + attribIndex.AttributeIndex = static_cast(-(destNode->InputAttribs.size() + 1)); + destNode->InputAttribs.emplace_back(attribIndex); + + // Create link + LinkData link; + link.SourceNode = sourceNode; + link.TargetNode = destNode; + link.SourceAttrib = sourceNode->OutputAttribs.back(); + link.DestAttrib = destNode->InputAttribs.back(); + NodeLinkIndex linkIdx; + linkIdx.SourceAttribute = link.SourceAttrib; + linkIdx.DestinationAttribute = link.DestAttrib; + + data.Links.emplace(linkIdx.Raw, std::move(link)); + sourceNode->Transitions.emplace_back(linkIdx); + } + /*-----------------------------------------------------------------------------------*/ + /* Static Helper Functions */ + /*-----------------------------------------------------------------------------------*/ + SHAnimationControllerEditor::AnimControllerData SHAnimationControllerEditor::deserialise(const SHAnimationController& controller) + { + AnimControllerData data; + + // Maps controller nodes to data nodes + std::unordered_map, std::list::iterator> nodeMap; + + // Load anim parameters + data.Params = controller.GetParams(); + + // Load nodes and links + for (auto node : controller.GetNodes()) + { + auto localNode = createNode(data); + localNode->Name = node->Name; + localNode->Clip = node->Clip; + nodeMap.emplace(node, localNode); + } + + // Load links + for (auto node : controller.GetNodes()) + { + // Get the corresponding data node + auto dataNodeIter = nodeMap[node]; + + for (auto transition : node->Transitions) + { + // Invalid node check + if (!nodeMap.contains(transition.Target)) + continue; + + // Get the target node + auto targetNodeIter = nodeMap[transition.Target]; + + // Create link + createLink(data, dataNodeIter, targetNodeIter); + } + } + + return data; + } + SHAnimationController SHAnimationControllerEditor::serialise(const AnimControllerData& data) + { + 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 a78d2fd6..d12e55cf 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h @@ -13,6 +13,9 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include +#include +// External Dependencies +#include // Project Includes #include "Resource/SHHandle.h" #include "Editor/EditorWindow/SHEditorWindow.h" @@ -38,23 +41,29 @@ namespace SHADE void Init() override; void Update() override; void Exit() override; + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void Open(const SHAnimationController& controller); private: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ + using NodeIndex = uint8_t; union NodeAttributeIndex { - int16_t Raw; + uint16_t Raw; struct { - uint8_t OwnerNodeIndex; - uint8_t AttributeIndex; + NodeIndex OwnerNodeIndex; + int8_t AttributeIndex; // Negative is input, positive is output }; }; union NodeLinkIndex { - int32_t Raw; + uint32_t Raw; struct { NodeAttributeIndex SourceAttribute; @@ -62,17 +71,55 @@ namespace SHADE }; }; + struct Node + { + NodeIndex Index; + std::string Name = "Unnamed Node"; + Handle Clip; + std::vector InputAttribs; + std::vector OutputAttribs; + std::vector Transitions; + bool EditingName = false; + }; + + struct LinkData + { + std::list::iterator SourceNode; + std::list::iterator TargetNode; + NodeAttributeIndex SourceAttrib; + NodeAttributeIndex DestAttrib; + }; + + struct AnimControllerData + { + std::list Nodes; + std::unordered_map Params; + std::unordered_map Links; + int NextNodeIndex = 0; // Index to use for newly created nodes + std::unordered_map::iterator> IndexToNodeMap; + }; + /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ - SHAnimationController controller; - std::vector> inputNodesMap; - std::vector> outputNodesMap; - std::vector linkIndices; // Encodes details of the link in the node index + std::optional controllerData; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ /*---------------------------------------------------------------------------------*/ - void drawMenuBar(); + void drawActiveMenuBar(); + void drawNodeEditor(); + NodeAttributeIndex getExtraInputAttrib(uint32_t nodeIndex); + NodeAttributeIndex getExtraOutputAttrib(uint32_t nodeIndex); + void drawInputNode(int id, ImNodesPinShape_ pinShape); + void drawOutputNode(int id, int parentNodeId, ImNodesPinShape_ pinShape); + + /*---------------------------------------------------------------------------------*/ + /* Static Helper Functions */ + /*---------------------------------------------------------------------------------*/ + static std::list::iterator createNode(AnimControllerData& data); + static void createLink(AnimControllerData& data, std::list::iterator sourceNode, std::list::iterator destNode); + static AnimControllerData deserialise(const SHAnimationController& controller); + static SHAnimationController serialise(const AnimControllerData& data); }; -} \ No newline at end of file +} diff --git a/SHADE_Engine/src/Editor/SHEditorUI.cpp b/SHADE_Engine/src/Editor/SHEditorUI.cpp index b9783020..3096759f 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.cpp +++ b/SHADE_Engine/src/Editor/SHEditorUI.cpp @@ -137,6 +137,15 @@ namespace SHADE { ImGui::Text(title.c_str()); } + void SHEditorUI::CenteredText(const std::string& text) + { + const auto WINDOW_SIZE = ImGui::GetWindowSize(); + const auto TEXT_SIZE = ImGui::CalcTextSize(text.c_str()); + + ImGui::SetCursorPosX((WINDOW_SIZE.x - TEXT_SIZE.x) * 0.5f); + ImGui::SetCursorPosY((WINDOW_SIZE.y - TEXT_SIZE.y) * 0.5f); + ImGui::Text(text.c_str()); + } bool SHEditorUI::SmallButton(const std::string& title) { return ImGui::SmallButton(title.c_str()); diff --git a/SHADE_Engine/src/Editor/SHEditorUI.h b/SHADE_Engine/src/Editor/SHEditorUI.h index 94804bb9..8d4a7b6e 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.h +++ b/SHADE_Engine/src/Editor/SHEditorUI.h @@ -90,7 +90,7 @@ namespace SHADE /// True if the header is open, false otherwise. static bool CollapsingHeader(const std::string& title, bool* isHovered = nullptr); static void SameLine(); - static void Separator(); + static void Separator(); /*-----------------------------------------------------------------------------*/ /* ImGui Wrapper Functions - Queries */ @@ -98,9 +98,9 @@ namespace SHADE static bool IsItemHovered(); /*-----------------------------------------------------------------------------*/ - /* ImGui Wrapper Functions - Menu */ - /*-----------------------------------------------------------------------------*/ - static bool BeginMenu(const std::string& label); + /* ImGui Wrapper Functions - Menu */ + /*-----------------------------------------------------------------------------*/ + static bool BeginMenu(const std::string& label); static bool BeginMenu(const std::string& label, const char* icon); static void EndMenu(); static void BeginTooltip(); @@ -150,6 +150,12 @@ namespace SHADE /// Text to display. static void Text(const std::string& title); /// + /// Renders a text widget that is vertically and horizontally centered in the current + /// window. + /// + /// Text to display. + static void CenteredText(const std::string& text); + /// /// Creates a small inline button widget. ///
/// Wraps up ImGui::SmallButton(). From 066d060b29c8a3a65bd00223be43047e7bb9bcc2 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 5 Mar 2023 01:45:26 +0800 Subject: [PATCH 21/69] Split main animation controller panel into 3 segments --- .../Animation/SHAnimationControllerEditor.cpp | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 84db473c..2965ad8a 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -64,13 +64,34 @@ namespace SHADE SHEditorWindow::Update(); if (Begin()) - { - + { // Only render the node editor if there is controller data if (controllerData.has_value()) { - drawActiveMenuBar(); - drawNodeEditor(); + // Calculate size of each portion + const float MAIN_PANEL_COLUMN_WIDTH = ImGui::GetWindowSize().x * 0.7f; + + // Draw + drawActiveMenuBar(); + ImGui::BeginTable("base_table", 3); + { + // Set up Columns + ImGui::TableSetupColumn("params_panel", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("main_panel", ImGuiTableColumnFlags_WidthFixed, MAIN_PANEL_COLUMN_WIDTH); + ImGui::TableSetupColumn("prop_panel", ImGuiTableColumnFlags_WidthStretch); + + // Render contents + ImGui::TableNextRow(); + { + ImGui::TableSetColumnIndex(0); + ImGui::Text("Parameters"); + ImGui::TableSetColumnIndex(1); + drawNodeEditor(); + ImGui::TableSetColumnIndex(2); + ImGui::Text("Properties"); + } + } + ImGui::EndTable(); } else { From f8cc1fe2dc79f5b4fa0ef41d9b2dceec35bb1774 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 6 Mar 2023 11:47:30 +0800 Subject: [PATCH 22/69] Size of animation controller editor is now adjustable --- .../Animation/SHAnimationControllerEditor.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 2965ad8a..6285ffbd 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -69,16 +69,18 @@ namespace SHADE if (controllerData.has_value()) { // Calculate size of each portion - const float MAIN_PANEL_COLUMN_WIDTH = ImGui::GetWindowSize().x * 0.7f; + const float WINDOW_WIDTH = ImGui::GetWindowSize().x; + const float MAIN_PANEL_COLUMN_WIDTH = WINDOW_WIDTH * 0.7f; + const float SIDE_PANELS_COLUMN_WIDTH = (WINDOW_WIDTH - MAIN_PANEL_COLUMN_WIDTH) * 0.5f; // Draw drawActiveMenuBar(); - ImGui::BeginTable("base_table", 3); + ImGui::BeginTable("base_table", 3, ImGuiTableFlags_Resizable); { // Set up Columns - ImGui::TableSetupColumn("params_panel", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("params_panel", ImGuiTableColumnFlags_WidthStretch, SIDE_PANELS_COLUMN_WIDTH); ImGui::TableSetupColumn("main_panel", ImGuiTableColumnFlags_WidthFixed, MAIN_PANEL_COLUMN_WIDTH); - ImGui::TableSetupColumn("prop_panel", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("prop_panel", ImGuiTableColumnFlags_WidthStretch, SIDE_PANELS_COLUMN_WIDTH); // Render contents ImGui::TableNextRow(); From d16f807a8aa3e7b0384581a7ed38e00d9308a90b Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 6 Mar 2023 16:17:05 +0800 Subject: [PATCH 23/69] Added links properties panel --- .../Animation/SHAnimationControllerEditor.cpp | 216 +++++++++++++++++- .../Animation/SHAnimationControllerEditor.h | 26 ++- 2 files changed, 229 insertions(+), 13 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 6285ffbd..b062e591 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -22,6 +22,8 @@ of DigiPen Institute of Technology is prohibited. #include "Editor/IconsMaterialDesign.h" #include "Animation/SHAnimationController.h" #include "Editor/SHEditorUI.h" +#include "Editor/SHEditorWidgets.hpp" +#include "../../Command/SHCommand.hpp" namespace SHADE { @@ -39,6 +41,19 @@ namespace SHADE { SHEditorWindow::Init(); + // Set up caches + conditionsList = + { + "None", + "=", + "!=", + "<", + "<=", + ">", + ">=" + }; + + // Set up sample animation controller for testing SHAnimationController controller; auto n1 = controller.CreateNode(); auto n2 = controller.CreateNode(); @@ -90,7 +105,7 @@ namespace SHADE ImGui::TableSetColumnIndex(1); drawNodeEditor(); ImGui::TableSetColumnIndex(2); - ImGui::Text("Properties"); + drawPropertiesPanel(); } } ImGui::EndTable(); @@ -234,6 +249,188 @@ namespace SHADE } } } + + void SHAnimationControllerEditor::drawPropertiesPanel() + { + const int SELECTED_LINKS_COUNT = ImNodes::NumSelectedLinks(); + + if (SELECTED_LINKS_COUNT > 0) + { + std::vector selectedLinks(SELECTED_LINKS_COUNT); + ImNodes::GetSelectedLinks(selectedLinks.data()); + + // Go through all links and display them + int index = 0; + for (int link : selectedLinks) + { + // Get LinkData + NodeLinkIndex nodeLinkIndex; + nodeLinkIndex.Raw = link; + if (!controllerData->Links.contains(nodeLinkIndex.Raw)) + continue; + + LinkData& linkData = controllerData->Links[nodeLinkIndex.Raw]; + + // Ensure that the link is valid + if (!controllerData->IndexToNodeMap.contains(nodeLinkIndex.SourceAttribute.OwnerNodeIndex) || + !controllerData->IndexToNodeMap.contains(nodeLinkIndex.DestinationAttribute.OwnerNodeIndex)) + { + continue; + } + + // Create name of the link + std::ostringstream oss; + oss << controllerData->IndexToNodeMap[nodeLinkIndex.SourceAttribute.OwnerNodeIndex]->Name + << " " << ICON_MD_ARROW_RIGHT_ALT << " " + << controllerData->IndexToNodeMap[nodeLinkIndex.DestinationAttribute.OwnerNodeIndex]->Name; + + ImGui::PushID(index++); + + // Display each link + if (SHEditorUI::CollapsingHeader(oss.str())) + { + const bool IS_PARAM_SET = !linkData.ParamName.empty(); + + // Anim Parameter + ImGui::Text("Parameter"); + ImGui::SameLine(); + if (ImGui::BeginCombo("##Parameter", IS_PARAM_SET ? linkData.ParamName.c_str() : "None", ImGuiComboFlags_None)) + { + // Initial "None" option + if (ImGui::Selectable("None", !IS_PARAM_SET)) + { + SHCommandManager::PerformCommand + ( + std::reinterpret_pointer_cast + ( + std::make_shared> + ( + linkData.ParamName, + std::string{}, + [&](const std::string& val) { linkData.ParamName = val; } + ) + ), + false + ); + } + if (!IS_PARAM_SET) + { + ImGui::SetItemDefaultFocus(); + } + + // All other options + for (const auto& param : controllerData->Params) + { + const bool IS_SELECTED = param.first == linkData.ParamName; + if (ImGui::Selectable(param.first.c_str(), IS_SELECTED)) + { + linkData.ParamName = param.first; + SHCommandManager::PerformCommand + ( + std::reinterpret_pointer_cast + ( + std::make_shared> + ( + linkData.ParamName, + param.first, + [&](const std::string& val) { linkData.ParamName = val; } + ) + ), + false + ); + } + + if (IS_SELECTED) + { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + + // Properties for an Animation Parameter + if (IS_PARAM_SET && controllerData->Params.contains(linkData.ParamName)) + { + const SHAnimationController::AnimParam::Type PARAM_TYPE = controllerData->Params[linkData.ParamName]; + + // Comparison Type + const auto& CURR_COMPARISON = conditionsList[static_cast(linkData.Condition)]; + ImGui::Text("Condition Type"); + ImGui::SameLine(); + if (ImGui::BeginCombo("##ConditionType", CURR_COMPARISON.c_str(), ImGuiComboFlags_None)) + { + // We only show equal and not equal for bool + const int LAST_ELEM = PARAM_TYPE == SHAnimationController::AnimParam::Type::Bool ? static_cast(SHAnimationController::Transition::ConditionType::NotEquals) + : static_cast(conditionsList.size() - 1); + // Comparisons + for (int i = 0; i <= LAST_ELEM; ++i) + { + const bool IS_SELECTED = i == static_cast(linkData.Condition); + if (ImGui::Selectable(conditionsList[i].c_str(), IS_SELECTED)) + { + SHCommandManager::PerformCommand + ( + std::reinterpret_pointer_cast + ( + std::make_shared> + ( + linkData.Condition, + static_cast(i), + [&](SHAnimationController::Transition::ConditionType val) { linkData.Condition = val; } + ) + ), + false + ); + } + + if (IS_SELECTED) + { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + + // Parameter Value + switch (PARAM_TYPE) + { + case SHAnimationController::AnimParam::Type::Bool: + SHEditorWidgets::CheckBox + ( + "Threshold", + [&](){ return std::get(linkData.ParamThresholdValue); }, + [&](bool val) { linkData.ParamThresholdValue = val; } + ); + break; + case SHAnimationController::AnimParam::Type::Float: + SHEditorWidgets::DragFloat + ( + "Threshold", + [&]() { return std::get(linkData.ParamThresholdValue); }, + [&](float val) { linkData.ParamThresholdValue = val; } + ); + break; + case SHAnimationController::AnimParam::Type::Int: + SHEditorWidgets::DragInt + ( + "Threshold", + [&]() { return std::get(linkData.ParamThresholdValue); }, + [&](int val) { linkData.ParamThresholdValue = val; } + ); + break; + } + } + } + + ImGui::PopID(); + } + } + else + { + ImGui::Text("Select an object to view properties."); + } + } + SHAnimationControllerEditor::NodeAttributeIndex SHAnimationControllerEditor::getExtraInputAttrib(uint32_t nodeIndex) { NodeAttributeIndex extraInputAttrib; @@ -266,17 +463,19 @@ namespace SHADE } std::list::iterator SHAnimationControllerEditor::createNode(AnimControllerData& data) { + const NodeIndex NEW_NODE_IDX = data.NextNodeIndex++; + Node localNode; - localNode.Index = data.NextNodeIndex++; + localNode.Index = NEW_NODE_IDX; data.Nodes.emplace_back(std::move(localNode)); // Update the node map auto nodeIter = --data.Nodes.end(); - data.IndexToNodeMap[localNode.Index] = nodeIter; + data.IndexToNodeMap[NEW_NODE_IDX] = nodeIter; return nodeIter; } - void SHAnimationControllerEditor::createLink(AnimControllerData& data, std::list::iterator sourceNode, std::list::iterator destNode) + SHAnimationControllerEditor::LinkMap::iterator SHAnimationControllerEditor::createLink(AnimControllerData& data, std::list::iterator sourceNode, std::list::iterator destNode) { // Update source node's output attributes NodeAttributeIndex attribIndex; @@ -299,8 +498,10 @@ namespace SHADE linkIdx.SourceAttribute = link.SourceAttrib; linkIdx.DestinationAttribute = link.DestAttrib; - data.Links.emplace(linkIdx.Raw, std::move(link)); + const auto EMPLACE_DATA = data.Links.emplace(linkIdx.Raw, std::move(link)); sourceNode->Transitions.emplace_back(linkIdx); + + return EMPLACE_DATA.first; } /*-----------------------------------------------------------------------------------*/ /* Static Helper Functions */ @@ -340,7 +541,10 @@ namespace SHADE auto targetNodeIter = nodeMap[transition.Target]; // Create link - createLink(data, dataNodeIter, targetNodeIter); + auto& linkData = createLink(data, dataNodeIter, targetNodeIter)->second; + linkData.Condition = transition.Condition; + linkData.ParamName = transition.ParamName; + linkData.ParamThresholdValue = transition.Param.Value; } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h index d12e55cf..0b566270 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h @@ -52,6 +52,7 @@ namespace SHADE /* Type Definitions */ /*---------------------------------------------------------------------------------*/ using NodeIndex = uint8_t; + using LinkIndex = int32_t; union NodeAttributeIndex { uint16_t Raw; @@ -63,7 +64,7 @@ namespace SHADE }; union NodeLinkIndex { - uint32_t Raw; + LinkIndex Raw; struct { NodeAttributeIndex SourceAttribute; @@ -84,17 +85,25 @@ namespace SHADE struct LinkData { - std::list::iterator SourceNode; - std::list::iterator TargetNode; - NodeAttributeIndex SourceAttrib; - NodeAttributeIndex DestAttrib; + // Source/Dest Data + std::list::iterator SourceNode; + std::list::iterator TargetNode; + NodeAttributeIndex SourceAttrib; + NodeAttributeIndex DestAttrib; + // Conditional Data + SHAnimationController::Transition::ConditionType Condition; + std::string ParamName; + SHAnimationController::AnimParam::ValueType ParamThresholdValue; }; + + using LinkMap = std::unordered_map; struct AnimControllerData { + std::list Nodes; std::unordered_map Params; - std::unordered_map Links; + LinkMap Links; int NextNodeIndex = 0; // Index to use for newly created nodes std::unordered_map::iterator> IndexToNodeMap; }; @@ -103,12 +112,15 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ std::optional controllerData; + // Persistent Cached Data + std::vector conditionsList; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ /*---------------------------------------------------------------------------------*/ void drawActiveMenuBar(); void drawNodeEditor(); + void drawPropertiesPanel(); NodeAttributeIndex getExtraInputAttrib(uint32_t nodeIndex); NodeAttributeIndex getExtraOutputAttrib(uint32_t nodeIndex); void drawInputNode(int id, ImNodesPinShape_ pinShape); @@ -118,7 +130,7 @@ namespace SHADE /* Static Helper Functions */ /*---------------------------------------------------------------------------------*/ static std::list::iterator createNode(AnimControllerData& data); - static void createLink(AnimControllerData& data, std::list::iterator sourceNode, std::list::iterator destNode); + static LinkMap::iterator createLink(AnimControllerData& data, std::list::iterator sourceNode, std::list::iterator destNode); static AnimControllerData deserialise(const SHAnimationController& controller); static SHAnimationController serialise(const AnimControllerData& data); }; From 9a8114f5dd404042310273b68e5e7b4fd0844eff Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 6 Mar 2023 16:43:15 +0800 Subject: [PATCH 24/69] Added work in progress animation parameter panel --- .../Animation/SHAnimationControllerEditor.cpp | 83 ++++++++++++++++++- .../Animation/SHAnimationControllerEditor.h | 2 + 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index b062e591..8dd98057 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -52,6 +52,13 @@ namespace SHADE ">", ">=" }; + typesList = + { + "Boolean", + "Trigger", + "Float", + "Integer" + }; // Set up sample animation controller for testing SHAnimationController controller; @@ -101,7 +108,7 @@ namespace SHADE ImGui::TableNextRow(); { ImGui::TableSetColumnIndex(0); - ImGui::Text("Parameters"); + drawParamsPanel(); ImGui::TableSetColumnIndex(1); drawNodeEditor(); ImGui::TableSetColumnIndex(2); @@ -147,6 +154,79 @@ namespace SHADE } } + void SHAnimationControllerEditor::drawParamsPanel() + { + // Add Parameter Button + if (ImGui::BeginCombo("##Type", "Add Parameter", ImGuiComboFlags_None)) + { + // All other options + for (int i = 0; i < static_cast(typesList.size()); ++i) + { + if (ImGui::Selectable(typesList[i].c_str())) + { + controllerData->Params.emplace("New", static_cast(i)); + } + } + ImGui::EndCombo(); + } + + int paramId = 0; + for (auto param : controllerData->Params) + { + ImGui::PushID(paramId++); + if (SHEditorWidgets::InputText + ( + "", + [&]() { return param.first; }, + [&](const std::string& val) + { + // Remove from previous + const SHAnimationController::AnimParam::Type TYPE = param.second; + controllerData->Params.erase(param.first); + // Put into the new + controllerData->Params[val] = TYPE; + } + )) + { + ImGui::PopID(); + break; // Map was modified + } + ImGui::SameLine(); + if (ImGui::BeginCombo("##Type", typesList[static_cast(param.second)].c_str(), ImGuiComboFlags_None)) + { + // All other options + for (int i = 0; i < static_cast(typesList.size()); ++i) + { + const bool IS_SELECTED = static_cast(param.second) == i; + + if (ImGui::Selectable(typesList[i].c_str(), IS_SELECTED)) + { + SHCommandManager::PerformCommand + ( + std::reinterpret_pointer_cast + ( + std::make_shared> + ( + param.second, + static_cast(i), + [&](SHAnimationController::AnimParam::Type val) { controllerData->Params[param.first] = val; } + ) + ), + false + ); + } + + if (IS_SELECTED) + { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + ImGui::PopID(); + } + } + void SHAnimationControllerEditor::drawNodeEditor() { static constexpr float NODE_WIDTH = 80.0f; @@ -324,7 +404,6 @@ namespace SHADE const bool IS_SELECTED = param.first == linkData.ParamName; if (ImGui::Selectable(param.first.c_str(), IS_SELECTED)) { - linkData.ParamName = param.first; SHCommandManager::PerformCommand ( std::reinterpret_pointer_cast diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h index 0b566270..adc0887d 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h @@ -114,11 +114,13 @@ namespace SHADE std::optional controllerData; // Persistent Cached Data std::vector conditionsList; + std::vector typesList; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ /*---------------------------------------------------------------------------------*/ void drawActiveMenuBar(); + void drawParamsPanel(); void drawNodeEditor(); void drawPropertiesPanel(); NodeAttributeIndex getExtraInputAttrib(uint32_t nodeIndex); From 493f2c3cfe9e7efadc8d0930c27533a5d300ae01 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 7 Mar 2023 16:38:00 +0800 Subject: [PATCH 25/69] Fixed parameters panel for animation controller editor and added menu bar --- .../src/Animation/SHAnimationController.cpp | 22 +- .../src/Animation/SHAnimationController.h | 4 +- .../src/Animation/SHAnimationController.hpp | 12 +- .../Animation/SHAnimationControllerEditor.cpp | 260 +++++++++++++----- .../Animation/SHAnimationControllerEditor.h | 5 +- 5 files changed, 209 insertions(+), 94 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 557bedb3..9da907bf 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -22,20 +22,8 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHAnimationController::AnimParam::AnimParam(Type type) : ParamType { type } - { - switch (ParamType) - { - case Type::Bool: - Value = false; - break; - case Type::Float: - Value = 0.0f; - break; - case Type::Int: - Value = 0; - break; - } - } + , Value { 0.0f } + {} /*-----------------------------------------------------------------------------------*/ /* Transition - Usage Functions */ @@ -51,12 +39,12 @@ namespace SHADE { case AnimParam::Type::Bool: case AnimParam::Type::Trigger: - return evaluateCondition(std::get(testParam.Value)); + return evaluateCondition(testParam.Value != 0.0f); case AnimParam::Type::Float: - return evaluateCondition(std::get(testParam.Value)); + return evaluateCondition(testParam.Value); break; case AnimParam::Type::Int: - return evaluateCondition(std::get(testParam.Value)); + return evaluateCondition(static_cast(testParam.Value)); break; } diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index a7acb772..64210481 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -59,7 +59,7 @@ namespace SHADE Float, Int }; - using ValueType = std::variant; + using ValueType = float; /*-------------------------------------------------------------------------------*/ /* Constructor */ @@ -104,7 +104,7 @@ namespace SHADE /* Data Members */ /*-------------------------------------------------------------------------------*/ Handle Target; - ConditionType Condition; + ConditionType Condition = ConditionType::None; AnimParam Param; std::string ParamName; diff --git a/SHADE_Engine/src/Animation/SHAnimationController.hpp b/SHADE_Engine/src/Animation/SHAnimationController.hpp index 054f066e..f040b8d4 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.hpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.hpp @@ -17,12 +17,14 @@ namespace SHADE template bool SHAnimationController::Transition::evaluateCondition(T value) const noexcept { - // Early failure if invalid data - if (!std::holds_alternative(Param.Value)) - return false; - // Get the value - const T PARAM_VAL = std::get(Param.Value); + const T PARAM_VAL = [&]() + { + if constexpr (std::is_floating_point_v) + return Param.Value; + else + return Param.Value != 0.0f; + }(); // Handle condition type switch (Condition) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 8dd98057..33372760 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -97,12 +97,26 @@ namespace SHADE // Draw drawActiveMenuBar(); - ImGui::BeginTable("base_table", 3, ImGuiTableFlags_Resizable); + ImGui::BeginTable("base_table", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable); { // Set up Columns - ImGui::TableSetupColumn("params_panel", ImGuiTableColumnFlags_WidthStretch, SIDE_PANELS_COLUMN_WIDTH); - ImGui::TableSetupColumn("main_panel", ImGuiTableColumnFlags_WidthFixed, MAIN_PANEL_COLUMN_WIDTH); - ImGui::TableSetupColumn("prop_panel", ImGuiTableColumnFlags_WidthStretch, SIDE_PANELS_COLUMN_WIDTH); + ImGui::TableSetupColumn(" Parameters", ImGuiTableColumnFlags_WidthStretch, SIDE_PANELS_COLUMN_WIDTH); + ImGui::TableSetupColumn("State Machine", ImGuiTableColumnFlags_WidthFixed, MAIN_PANEL_COLUMN_WIDTH); + ImGui::TableSetupColumn("Properties", ImGuiTableColumnFlags_WidthStretch, SIDE_PANELS_COLUMN_WIDTH); + + // Header + ImGui::TableHeadersRow(); + + // Render menu bars + ImGui::TableNextRow(); + { + ImGui::TableSetColumnIndex(0); + drawParamsMenuBar(); + ImGui::TableSetColumnIndex(1); + drawNodeEditorMenuBar(); + ImGui::TableSetColumnIndex(2); + drawPropertiesMenuBar(); + } // Render contents ImGui::TableNextRow(); @@ -141,37 +155,48 @@ namespace SHADE { if (ImGui::BeginMenuBar()) { + // Save Button if (ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) { // TODO } - if (ImGui::Button(std::format("{} Add", ICON_MD_ADD).data())) + // Discard Button + if (ImGui::Button(std::format("{} Discard Changes", ICON_MD_CANCEL).data())) { - createNode(controllerData.value()); + // TODO } ImGui::EndMenuBar(); } } - void SHAnimationControllerEditor::drawParamsPanel() + void SHAnimationControllerEditor::drawParamsMenuBar() { // Add Parameter Button - if (ImGui::BeginCombo("##Type", "Add Parameter", ImGuiComboFlags_None)) + if (ImGui::BeginCombo("##Type", std::format("{} Add Parameter", ICON_MD_ADD).data(), ImGuiComboFlags_None)) { // All other options for (int i = 0; i < static_cast(typesList.size()); ++i) { if (ImGui::Selectable(typesList[i].c_str())) { - controllerData->Params.emplace("New", static_cast(i)); + int count = 0; + std::string paramName = "New Param"; + while (controllerData->Params.contains(paramName)) + { + paramName = "New Param " + std::to_string(++count); + } + controllerData->Params.emplace(paramName, static_cast(i)); } } ImGui::EndCombo(); } + } + void SHAnimationControllerEditor::drawParamsPanel() + { int paramId = 0; - for (auto param : controllerData->Params) + for (const auto& param : controllerData->Params) { ImGui::PushID(paramId++); if (SHEditorWidgets::InputText @@ -185,7 +210,15 @@ namespace SHADE controllerData->Params.erase(param.first); // 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) + { + link.second.ParamName = val; + } + }, + {}, ImGuiInputTextFlags_EnterReturnsTrue )) { ImGui::PopID(); @@ -209,7 +242,30 @@ namespace SHADE ( param.second, static_cast(i), - [&](SHAnimationController::AnimParam::Type val) { controllerData->Params[param.first] = val; } + [&](SHAnimationController::AnimParam::Type val) + { + controllerData->Params[param.first] = val; + + // TODO: This needs to be handled in a custom command + // For changing to boolean, we need to change inequalities to not equal, etc. + if (val == SHAnimationController::AnimParam::Type::Bool) + { + for (auto& link : controllerData->Links) + { + switch (link.second.Condition) + { + case SHAnimationController::Transition::ConditionType::GreaterThan: + case SHAnimationController::Transition::ConditionType::LessThan: + link.second.Condition = SHAnimationController::Transition::ConditionType::NotEquals; + break; + case SHAnimationController::Transition::ConditionType::GreaterThanOrEqual: + case SHAnimationController::Transition::ConditionType::LessThanOrEqual: + link.second.Condition = SHAnimationController::Transition::ConditionType::Equals; + break; + } + } + } + } ) ), false @@ -227,6 +283,33 @@ namespace SHADE } } + void SHAnimationControllerEditor::drawNodeEditorMenuBar() + { + // Add Node Button + if (ImGui::Button(std::format("{} Add Node", ICON_MD_ADD).data())) + { + createNode(controllerData.value()); + } + ImGui::SameLine(); + + // Delete Node Button + ImGui::BeginDisabled(ImNodes::NumSelectedNodes() < 1); + if (ImGui::Button(std::format("{} Delete Nodes", ICON_MD_ADD).data())) + { + + } + ImGui::EndDisabled(); + ImGui::SameLine(); + + // Set Starting Node Button + ImGui::BeginDisabled(ImNodes::NumSelectedNodes() != 1); + if (ImGui::Button(std::format("{} Set Starting Node", ICON_MD_HOME).data())) + { + + } + ImGui::EndDisabled(); + } + void SHAnimationControllerEditor::drawNodeEditor() { static constexpr float NODE_WIDTH = 80.0f; @@ -330,6 +413,39 @@ namespace SHADE } } + void SHAnimationControllerEditor::drawPropertiesMenuBar() + { + // Set Starting Node Button + const int SELECTED_LINKS_COUNT = ImNodes::NumSelectedLinks(); + ImGui::BeginDisabled(SELECTED_LINKS_COUNT < 1); + if (ImGui::Button(std::format("{} Reset Conditions", ICON_MD_SETTINGS_BACKUP_RESTORE).data())) + { + std::vector selectedLinks(SELECTED_LINKS_COUNT); + ImNodes::GetSelectedLinks(selectedLinks.data()); + for (auto& link : selectedLinks) + { + // Get LinkData + NodeLinkIndex nodeLinkIndex; + nodeLinkIndex.Raw = link; + if (!controllerData->Links.contains(nodeLinkIndex.Raw)) + continue; + + LinkData& linkData = controllerData->Links[nodeLinkIndex.Raw]; + + // Ensure that the link is valid + if (!controllerData->IndexToNodeMap.contains(nodeLinkIndex.SourceAttribute.OwnerNodeIndex) || + !controllerData->IndexToNodeMap.contains(nodeLinkIndex.DestinationAttribute.OwnerNodeIndex)) + { + continue; + } + + linkData.ParamName = ""; + linkData.Condition = SHAnimationController::Transition::ConditionType::None; + } + } + ImGui::EndDisabled(); + } + void SHAnimationControllerEditor::drawPropertiesPanel() { const int SELECTED_LINKS_COUNT = ImNodes::NumSelectedLinks(); @@ -432,72 +548,78 @@ namespace SHADE { const SHAnimationController::AnimParam::Type PARAM_TYPE = controllerData->Params[linkData.ParamName]; - // Comparison Type - const auto& CURR_COMPARISON = conditionsList[static_cast(linkData.Condition)]; - ImGui::Text("Condition Type"); - ImGui::SameLine(); - if (ImGui::BeginCombo("##ConditionType", CURR_COMPARISON.c_str(), ImGuiComboFlags_None)) + if (PARAM_TYPE != SHAnimationController::AnimParam::Type::Trigger) { - // We only show equal and not equal for bool - const int LAST_ELEM = PARAM_TYPE == SHAnimationController::AnimParam::Type::Bool ? static_cast(SHAnimationController::Transition::ConditionType::NotEquals) - : static_cast(conditionsList.size() - 1); - // Comparisons - for (int i = 0; i <= LAST_ELEM; ++i) + // Comparison Type + const auto& CURR_COMPARISON = conditionsList[static_cast(linkData.Condition)]; + ImGui::Text("Condition Type"); + ImGui::SameLine(); + if (ImGui::BeginCombo("##ConditionType", CURR_COMPARISON.c_str(), ImGuiComboFlags_None)) { - const bool IS_SELECTED = i == static_cast(linkData.Condition); - if (ImGui::Selectable(conditionsList[i].c_str(), IS_SELECTED)) + // We only show equal and not equal for bool + const int LAST_ELEM = PARAM_TYPE == SHAnimationController::AnimParam::Type::Bool ? static_cast(SHAnimationController::Transition::ConditionType::NotEquals) + : static_cast(conditionsList.size() - 1); + // Comparisons + for (int i = 0; i <= LAST_ELEM; ++i) { - SHCommandManager::PerformCommand - ( - std::reinterpret_pointer_cast + const bool IS_SELECTED = i == static_cast(linkData.Condition); + if (ImGui::Selectable(conditionsList[i].c_str(), IS_SELECTED)) + { + SHCommandManager::PerformCommand ( - std::make_shared> + std::reinterpret_pointer_cast ( - linkData.Condition, - static_cast(i), - [&](SHAnimationController::Transition::ConditionType val) { linkData.Condition = val; } - ) - ), - false - ); - } + std::make_shared> + ( + linkData.Condition, + static_cast(i), + [&](SHAnimationController::Transition::ConditionType val) { linkData.Condition = val; } + ) + ), + false + ); + } - if (IS_SELECTED) + if (IS_SELECTED) + { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + + // Parameter Value + if (linkData.Condition != SHAnimationController::Transition::ConditionType::None) + { + switch (PARAM_TYPE) { - ImGui::SetItemDefaultFocus(); + case SHAnimationController::AnimParam::Type::Bool: + SHEditorWidgets::CheckBox + ( + "Required State", + [&]() { return linkData.ParamThresholdValue != 0.0f; }, + [&](bool val) { linkData.ParamThresholdValue = static_cast(val); } + ); + break; + case SHAnimationController::AnimParam::Type::Float: + SHEditorWidgets::DragFloat + ( + "Threshold", + [&]() { return linkData.ParamThresholdValue; }, + [&](float val) { linkData.ParamThresholdValue = val; } + ); + break; + case SHAnimationController::AnimParam::Type::Int: + SHEditorWidgets::DragInt + ( + "Threshold", + [&]() { return static_cast(linkData.ParamThresholdValue); }, + [&](int val) { linkData.ParamThresholdValue = static_cast(val); } + ); + break; } } - ImGui::EndCombo(); - } - - // Parameter Value - switch (PARAM_TYPE) - { - case SHAnimationController::AnimParam::Type::Bool: - SHEditorWidgets::CheckBox - ( - "Threshold", - [&](){ return std::get(linkData.ParamThresholdValue); }, - [&](bool val) { linkData.ParamThresholdValue = val; } - ); - break; - case SHAnimationController::AnimParam::Type::Float: - SHEditorWidgets::DragFloat - ( - "Threshold", - [&]() { return std::get(linkData.ParamThresholdValue); }, - [&](float val) { linkData.ParamThresholdValue = val; } - ); - break; - case SHAnimationController::AnimParam::Type::Int: - SHEditorWidgets::DragInt - ( - "Threshold", - [&]() { return std::get(linkData.ParamThresholdValue); }, - [&](int val) { linkData.ParamThresholdValue = val; } - ); - break; - } + } } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h index adc0887d..bafbe4a9 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h @@ -91,7 +91,7 @@ namespace SHADE NodeAttributeIndex SourceAttrib; NodeAttributeIndex DestAttrib; // Conditional Data - SHAnimationController::Transition::ConditionType Condition; + SHAnimationController::Transition::ConditionType Condition = SHAnimationController::Transition::ConditionType::None; std::string ParamName; SHAnimationController::AnimParam::ValueType ParamThresholdValue; }; @@ -120,8 +120,11 @@ namespace SHADE /* Helper Functions */ /*---------------------------------------------------------------------------------*/ void drawActiveMenuBar(); + void drawParamsMenuBar(); void drawParamsPanel(); + void drawNodeEditorMenuBar(); void drawNodeEditor(); + void drawPropertiesMenuBar(); void drawPropertiesPanel(); NodeAttributeIndex getExtraInputAttrib(uint32_t nodeIndex); NodeAttributeIndex getExtraOutputAttrib(uint32_t nodeIndex); From 6d01bd0b78f3d9f5513474f5b0ef8d53a22035bb Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 7 Mar 2023 19:00:10 +0800 Subject: [PATCH 26/69] Added ability to set starting node --- .../Animation/SHAnimationControllerEditor.cpp | 20 ++++++++++++++++++- .../Animation/SHAnimationControllerEditor.h | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 33372760..4be0c7b0 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -305,7 +305,10 @@ 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(); } @@ -325,6 +328,15 @@ 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)) @@ -749,6 +761,12 @@ namespace SHADE } } + // Mark starting node + if (nodeMap.contains(controller.GetStartingNode())) + { + data.StartingNode = nodeMap[controller.GetStartingNode()]->Index; + } + return data; } SHAnimationController SHAnimationControllerEditor::serialise(const AnimControllerData& data) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h index bafbe4a9..60e939c7 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h @@ -100,7 +100,7 @@ namespace SHADE struct AnimControllerData { - + NodeIndex StartingNode = 0; std::list Nodes; std::unordered_map Params; LinkMap Links; From ff27925f2d644ff442206fdc7f603f19a9766254 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 7 Mar 2023 20:05:37 +0800 Subject: [PATCH 27/69] Added ability to reset state, delete links and nodes --- .../Animation/SHAnimationControllerEditor.cpp | 109 ++++++++++++++++-- .../Animation/SHAnimationControllerEditor.h | 11 +- 2 files changed, 111 insertions(+), 9 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 4be0c7b0..9659f036 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -23,7 +23,8 @@ of DigiPen Institute of Technology is prohibited. #include "Animation/SHAnimationController.h" #include "Editor/SHEditorUI.h" #include "Editor/SHEditorWidgets.hpp" -#include "../../Command/SHCommand.hpp" +#include "Editor/Command/SHCommand.hpp" +#include "Input/SHInputManager.h" namespace SHADE { @@ -144,8 +145,9 @@ namespace SHADE SHEditorWindow::Exit(); } - void SHAnimationControllerEditor::Open(const SHAnimationController& controller) + void SHAnimationControllerEditor::Open(SHAnimationController& controllerHandle) { + controller = controllerHandle; controllerData = deserialise(controller); } /*-----------------------------------------------------------------------------------*/ @@ -158,12 +160,12 @@ namespace SHADE // Save Button if (ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) { - // TODO + // TODO: Actually save the resource } // Discard Button if (ImGui::Button(std::format("{} Discard Changes", ICON_MD_CANCEL).data())) { - // TODO + Open(controller); // TODO: Actually load the resource } ImGui::EndMenuBar(); @@ -211,7 +213,6 @@ 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) { @@ -293,10 +294,11 @@ namespace SHADE ImGui::SameLine(); // Delete Node Button - ImGui::BeginDisabled(ImNodes::NumSelectedNodes() < 1); - if (ImGui::Button(std::format("{} Delete Nodes", ICON_MD_ADD).data())) + ImGui::BeginDisabled((ImNodes::NumSelectedNodes() + ImNodes::NumSelectedLinks()) < 1); + if (ImGui::Button(std::format("{} Delete Objects", ICON_MD_DELETE).data())) { - + deleteSelectedLinks(); + deleteSelectedNodes(); } ImGui::EndDisabled(); ImGui::SameLine(); @@ -423,6 +425,13 @@ namespace SHADE ); } } + + // Delete + if (SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::DEL)) + { + deleteSelectedLinks(); + deleteSelectedNodes(); + } } void SHAnimationControllerEditor::drawPropertiesMenuBar() @@ -674,6 +683,34 @@ 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++; @@ -716,6 +753,62 @@ 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 */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.h index 60e939c7..1066fc7b 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(const SHAnimationController& controller); + void Open(SHAnimationController& controller); private: /*---------------------------------------------------------------------------------*/ @@ -61,6 +61,8 @@ 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 { @@ -70,6 +72,8 @@ namespace SHADE NodeAttributeIndex SourceAttribute; NodeAttributeIndex DestinationAttribute; }; + + bool operator==(NodeLinkIndex rhs) const noexcept { return Raw != rhs.Raw; } }; struct Node @@ -111,6 +115,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ + SHAnimationController controller; std::optional controllerData; // Persistent Cached Data std::vector conditionsList; @@ -130,12 +135,16 @@ 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); }; From dc32c5c9aafe437c846c6a0d670901c4ace8dc02 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 7 Mar 2023 20:29:57 +0800 Subject: [PATCH 28/69] Implemented saving of animation controller from editor --- .../src/Animation/SHAnimationController.cpp | 8 +-- .../src/Animation/SHAnimationController.h | 8 ++- .../src/Animation/SHAnimatorComponent.cpp | 2 +- .../Animation/SHAnimationControllerEditor.cpp | 67 +++++++++++++++++-- 4 files changed, 73 insertions(+), 12 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 9da907bf..ef15f223 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 (!startNode) - startNode = node; + if (!StartingNode) + StartingNode = 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 (startNode == node) - startNode = {}; + if (StartingNode == node) + StartingNode = {}; // Remove from nodes nodes.erase(iter); diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index 64210481..7708d0c9 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -145,6 +145,11 @@ namespace SHADE std::unordered_map Params; float ClipPlaybackTime; }; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + Handle StartingNode; /*---------------------------------------------------------------------------------*/ /* Lifecycle Functions */ @@ -186,11 +191,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; } @@ -199,7 +204,6 @@ 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 1ab5c894..0059d721 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->GetStartingNode(); + animInstanceData.CurrentNode = animController->StartingNode; // Playback Time animInstanceData.ClipPlaybackTime = 0.0f; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index 9659f036..a67c6a67 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. @@ -160,7 +160,7 @@ namespace SHADE // Save Button if (ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) { - // TODO: Actually save the resource + controller = serialise(controllerData.value()); // TODO: Actually save the resource } // Discard Button if (ImGui::Button(std::format("{} Discard Changes", ICON_MD_CANCEL).data())) @@ -855,15 +855,72 @@ namespace SHADE } // Mark starting node - if (nodeMap.contains(controller.GetStartingNode())) + if (nodeMap.contains(controller.StartingNode)) { - data.StartingNode = nodeMap[controller.GetStartingNode()]->Index; + data.StartingNode = nodeMap[controller.StartingNode]->Index; } return data; } SHAnimationController SHAnimationControllerEditor::serialise(const AnimControllerData& data) { - return {}; + 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; } } \ No newline at end of file From eae6f6399b1a392cdc7006ecf2d115b7709275b0 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Tue, 7 Mar 2023 22:05:33 +0800 Subject: [PATCH 29/69] Changed implementation of binary loader to load animation clip containers instead of individual animation clips --- .../Libraries/Loaders/SHBinaryLoader.cpp | 93 ++++++++++++++++--- .../Assets/Libraries/Loaders/SHBinaryLoader.h | 5 + 2 files changed, 83 insertions(+), 15 deletions(-) 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 From 07100de9508b2b53d1658998711d962629571777 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Tue, 7 Mar 2023 22:06:42 +0800 Subject: [PATCH 30/69] Added recognition for animation clip container as a file Added functions to create new sub asset for animation clips Added recognition for animation clip containers when creating new assets --- SHADE_Engine/src/Assets/SHAssetMacros.h | 13 +-- SHADE_Engine/src/Assets/SHAssetManager.cpp | 95 +++++++++++++++++++--- SHADE_Engine/src/Assets/SHAssetManager.h | 1 + 3 files changed, 91 insertions(+), 18 deletions(-) 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; From 3cc949bb7eafc67ab474ac6be1ee8b15df0cbbb4 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Tue, 7 Mar 2023 22:07:38 +0800 Subject: [PATCH 31/69] Animation container redefinition --- .../Assets/Asset Types/Models/SHAnimationAsset.h | 2 -- ...AnimClipAsset.h => SHAnimClipContainerAsset.h} | 15 +++++++++++---- SHADE_Engine/src/Resource/SHResourceManager.h | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) rename SHADE_Engine/src/Assets/Asset Types/{SHAnimClipAsset.h => SHAnimClipContainerAsset.h} (81%) 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/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" From e285d5e6b205197d62625bf4ee4e554d0c547266 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 7 Mar 2023 22:34:32 +0800 Subject: [PATCH 32/69] Added functions for setting animation parameters --- .../src/Animation/SHAnimationController.cpp | 14 +++++ .../src/Animation/SHAnimationController.h | 33 +++++++++++- .../src/Animation/SHAnimationController.hpp | 51 +++++++++++++++++++ .../src/Animation/SHAnimatorComponent.cpp | 8 +++ .../src/Animation/SHAnimatorComponent.h | 35 +++++++++++++ .../src/Animation/SHAnimatorComponent.hpp | 20 ++++++++ 6 files changed, 160 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index ef15f223..2347ca6e 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -192,6 +192,20 @@ namespace SHADE parameters.erase(name); } + void SHAnimationController::SetTrigger(InstanceData& instData, const std::string& paramName) + { + // Invalid param + if (!parameters.contains(paramName)) + return; + + // Not a trigger + if (parameters[paramName] != AnimParam::Type::Trigger) + return; + + // Set the flag + instData.Params[paramName].Value = true; + } + /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index 7708d0c9..e593bc63 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -14,6 +14,7 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include #include +#include // Project Includes #include "SH_API.h" #include "Resource/SHHandle.h" @@ -191,7 +192,37 @@ namespace SHADE ///
/// Name of the parameter. void RemoveParameter(const std::string& name); - void SetStartingNode(Handle node); + /// + /// Sets the parameter of the for the string. Does nothing if an invalid param name + /// is provided. Type of the parameter is not checked. + /// + /// + /// Type of parameter. Only bool, int, floats are supported. + /// + /// Data of the instance to update. + /// Name of the parameter. + /// Value to set the parameter to. + template + void SetParameter(InstanceData& instData, const std::string& paramName, T value); + /// + /// Gets the parameter of the for the string. Types are checked and will not return + /// a value if there is nothing. + /// + /// + /// Type of parameter. Only bool, int, floats are supported. + /// + /// Data of the instance to update. + /// Name of the parameter. + /// The value of the parameter or nothing if invalid. + template + std::optional GetParameter(InstanceData& instData, const std::string& paramName); + /// + /// Sets the flag for a trigger parameter. Does nothing if an invalid param name is + /// provided or if the param name refers to a parameter that is not a trigger. + /// + /// Data of the instance to update. + /// Name of the parameter. + void SetTrigger(InstanceData& instData, const std::string& paramName); /*---------------------------------------------------------------------------------*/ /* Getters */ diff --git a/SHADE_Engine/src/Animation/SHAnimationController.hpp b/SHADE_Engine/src/Animation/SHAnimationController.hpp index f040b8d4..98fa35e6 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.hpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.hpp @@ -66,4 +66,55 @@ namespace SHADE // Neither of the existing cases return false; } + + template + void SHAnimationController::SetParameter(InstanceData& instData, const std::string& paramName, T value) + { + static_assert(std::is_same_v || std::is_same_v || std::is_same_v, "Only works with bool, float or ints."); + + // Invalid param + if (!parameters.contains(paramName)) + return; + + // Set the value + instData.Params[paramName].Value = value; + } + + template + std::optional SHAnimationController::GetParameter(InstanceData& instData, const std::string& paramName) + { + static_assert(std::is_same_v || std::is_same_v || std::is_same_v, "Only works with bool, float or ints."); + + // Invalid param + if (!parameters.contains(paramName)) + return {}; + + // Check if the type matches + const auto TYPE = parameters[paramName]; + if constexpr (std::is_same_v) + { + if (TYPE != AnimParam::Type::Bool && TYPE != AnimParam::Type::Trigger) + return {}; + } + else if constexpr (std::is_same_v) + { + if (parameters[paramName] != AnimParam::Type::Float) + return {}; + } + else if constexpr (std::is_same_v) + { + if (parameters[paramName] != AnimParam::Type::Int) + return {}; + } + + // Return the correct value + if (instData.Params.contains(paramName)) + { + return instData.Params[paramName]; + } + else + { + return T(); // Default constructed value + } + } } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 0059d721..71ae4e03 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -199,6 +199,14 @@ namespace SHADE } } + void SHAnimatorComponent::SetTrigger(const std::string& paramName) + { + if (!animController) + return; + + return animController->SetTrigger(animInstanceData, paramName); + } + /*-----------------------------------------------------------------------------------*/ /* Helper Functions - Loading */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index d4af2c2b..8beef34c 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -95,7 +95,42 @@ namespace SHADE ///
/// Rig to use. void SetRig(Handle newRig); + /// + /// Sets the animation controller to use for this animator. + /// + /// Animation controller to use. void SetAnimationController(Handle ac); + /// + /// Sets the parameter of the for the string. Does nothing if an invalid param name + /// is provided. Type of the parameter is not checked. Also does nothing if no + /// animation controller is specified. + /// + /// + /// Type of parameter. Only bool, int, floats are supported. + /// + /// Name of the parameter. + /// Value to set the parameter to. + template + void SetParameter(const std::string& paramName, T value); + /// + /// Gets the parameter of the for the string. Types are checked and will not return + /// a value if there is nothing. Returns nothing if there is no animation controller + /// specified either. + /// + /// + /// Type of parameter. Only bool, int, floats are supported. + /// + /// Name of the parameter. + /// The value of the parameter or nothing if invalid. + template + std::optional GetParameter(const std::string& paramName); + /// + /// Sets the flag for a trigger parameter. Does nothing if an invalid param name is + /// provided or if the param name refers to a parameter that is not a trigger. + /// + /// Data of the instance to . + /// Name of the parameter. + void SetTrigger(const std::string& paramName); /*---------------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp index e8c52073..ec64bc6e 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp @@ -22,6 +22,26 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*-----------------------------------------------------------------------------------*/ + template + std::optional SHAnimatorComponent::GetParameter(const std::string& paramName) + { + if (!animController) + return; + + return animController->GetParameter(paramName); + } + template + void SHAnimatorComponent::SetParameter(const std::string& paramName, T value) + { + if (!animController) + return; + + return animController->SetParameter(paramName, value); + } + /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ From 615a5796f0af2f28fa8f7cd47bc56c0e24384107 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Tue, 7 Mar 2023 22:51:40 +0800 Subject: [PATCH 33/69] Added line to add subasset meta to parent asset Rewrote loading of all animation clips into resource manager --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 1 + .../SHRawAnimInspector.cpp | 21 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 5ad2bbd4..3763d491 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -308,6 +308,7 @@ namespace SHADE auto& newClip {animContainer->clips.emplace_back()}; newClip.name = name; assetCollection.emplace(id, asset); + assetCollection[parent].subAssets.push_back(&assetCollection[id]); assetData.emplace(id, &newClip); return id; } diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index e4b7f94d..b795b1fa 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -249,13 +249,26 @@ namespace SHADE { std::vector> animClips; - const auto ALL_ANIM_CLIPS = SHAssetManager::GetAllRecordOfType(AssetType::ANIM_CLIP); - for (auto asset : ALL_ANIM_CLIPS) + //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) { - const SHAnimClipAsset* ANIM_CLIP = SHAssetManager::GetData(asset.id); + auto const ANIM_CLIP {SHAssetManager::GetData(asset.id)}; if (ANIM_CLIP->animRawDataAssetId == rawAnimId) { - animClips.emplace_back(SHResourceManager::LoadOrGet(asset.id)); + for (auto const& subAsset : asset.subAssets) + { + animClips.emplace_back(SHResourceManager::LoadOrGet(subAsset->id)); + } } } From 1c12a05837f897cb4ba2160dbc3dce83137791f7 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 8 Mar 2023 15:29:29 +0800 Subject: [PATCH 34/69] Added C# interface for animator, animation clip and animation controller --- SHADE_Engine/src/Animation/SHAnimationClip.h | 1 - .../src/Animation/SHAnimationController.cpp | 1 + .../src/Animation/SHAnimationController.h | 10 +- .../src/Animation/SHAnimationController.hpp | 9 +- .../src/Animation/SHAnimatorComponent.cpp | 12 ++ .../src/Animation/SHAnimatorComponent.h | 17 +- .../src/Animation/SHAnimatorComponent.hpp | 10 +- .../Asset Types/Models/SHAnimationAsset.h | 4 +- .../SHRawAnimInspector.cpp | 1 - .../src/Resource/SHResourceManager.hpp | 2 +- .../Resource/SHResourceManagerInterface.cpp | 15 ++ .../src/Resource/SHResourceManagerInterface.h | 21 +++ .../src/Assets/AnimationClipAsset.cxx | 70 ++++++++ .../src/Assets/AnimationClipAsset.hxx | 90 ++++++++++ .../src/Assets/AnimationControllerAsset.cxx | 70 ++++++++ .../src/Assets/AnimationControllerAsset.hxx | 89 ++++++++++ .../src/Assets/AnimationRigAsset.cxx | 70 ++++++++ .../src/Assets/AnimationRigAsset.hxx | 89 ++++++++++ SHADE_Managed/src/Components/Animator.cxx | 159 +++++++++++++++++ SHADE_Managed/src/Components/Animator.hxx | 164 ++++++++++++++++++ 20 files changed, 883 insertions(+), 21 deletions(-) create mode 100644 SHADE_Managed/src/Assets/AnimationClipAsset.cxx create mode 100644 SHADE_Managed/src/Assets/AnimationClipAsset.hxx create mode 100644 SHADE_Managed/src/Assets/AnimationControllerAsset.cxx create mode 100644 SHADE_Managed/src/Assets/AnimationControllerAsset.hxx create mode 100644 SHADE_Managed/src/Assets/AnimationRigAsset.cxx create mode 100644 SHADE_Managed/src/Assets/AnimationRigAsset.hxx create mode 100644 SHADE_Managed/src/Components/Animator.cxx create mode 100644 SHADE_Managed/src/Components/Animator.hxx diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h index 9b93a7a3..9de621d0 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -14,7 +14,6 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SH_API.h" #include "Math/SHMatrix.h" -#include "Assets/Asset Types/Models/SHAnimationAsset.h" #include "Resource/SHHandle.h" namespace SHADE diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 2347ca6e..9b7b6de2 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -14,6 +14,7 @@ of DigiPen Institute of Technology is prohibited. #include "SHAnimationController.h" #include "SHAnimationSystem.h" #include "ECS_Base/Managers/SHSystemManager.h" +#include "SHAnimationClip.h" namespace SHADE { diff --git a/SHADE_Engine/src/Animation/SHAnimationController.h b/SHADE_Engine/src/Animation/SHAnimationController.h index e593bc63..56bf6f45 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.h +++ b/SHADE_Engine/src/Animation/SHAnimationController.h @@ -18,13 +18,17 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SH_API.h" #include "Resource/SHHandle.h" -#include "SHAnimationClip.h" namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Forward Declarations */ /*-----------------------------------------------------------------------------------*/ + class SHAnimationClip; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ /// /// Object that controls the animation that is played by an animator through the use /// of an internal state machine. @@ -36,7 +40,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Forward Declarations */ /*---------------------------------------------------------------------------------*/ - class Node; + struct Node; /*---------------------------------------------------------------------------------*/ /* Type Definition */ @@ -45,7 +49,7 @@ namespace SHADE /// Describes a parameter for the AnimationController that can be used to control /// the flow of animations. /// - struct AnimParam + struct SH_API AnimParam { /*-------------------------------------------------------------------------------*/ /* Type Definition */ diff --git a/SHADE_Engine/src/Animation/SHAnimationController.hpp b/SHADE_Engine/src/Animation/SHAnimationController.hpp index 98fa35e6..7b86f125 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.hpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.hpp @@ -73,7 +73,7 @@ namespace SHADE static_assert(std::is_same_v || std::is_same_v || std::is_same_v, "Only works with bool, float or ints."); // Invalid param - if (!parameters.contains(paramName)) + if (parameters.find(paramName) == parameters.end()) return; // Set the value @@ -86,7 +86,7 @@ namespace SHADE static_assert(std::is_same_v || std::is_same_v || std::is_same_v, "Only works with bool, float or ints."); // Invalid param - if (!parameters.contains(paramName)) + if (parameters.find(paramName) == parameters.end()) return {}; // Check if the type matches @@ -108,9 +108,10 @@ namespace SHADE } // Return the correct value - if (instData.Params.contains(paramName)) + auto paramIter = instData.Params.find(paramName); + if (paramIter != instData.Params.end()) { - return instData.Params[paramName]; + return paramIter->second.Value; } else { diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 71ae4e03..36f8e501 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -85,6 +85,12 @@ namespace SHADE void SHAnimatorComponent::PlayFromStart() { + if (!currClip) + { + SHLOG_WARNING("[SHAnimatorComponent] Attempted to restart a clip but there is no existing clip. Ignored."); + return; + } + isPlaying = true; currPlaybackTime = 0.0f; } @@ -96,6 +102,12 @@ namespace SHADE void SHAnimatorComponent::Stop() { + if (!currClip) + { + SHLOG_WARNING("[SHAnimatorComponent] Attempted to stop a clip but there is no existing clip. Ignored."); + return; + } + isPlaying = false; currPlaybackTime = 0.0f; } diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index 8beef34c..ef67d35e 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -33,7 +33,6 @@ namespace SHADE class SHRig; struct SHRigNode; class SHAnimationClip; - class SHVkBuffer; /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -65,7 +64,8 @@ namespace SHADE /// Animation clip to play. void PlayOneShot(Handle clip); /// - /// Plays the currently loaded animation clip from the start. + /// Plays the currently loaded animation clip from the start. Note that this only + /// works when using manual playback mode. /// void PlayFromStart(); /// @@ -73,7 +73,9 @@ namespace SHADE /// void Pause(); /// - /// Stops the animation and resets the play time back to 0. + /// Stops the animation and resets the play time back to 0. Note that this only + /// works when using manual playback mode. This is not supported when using an + /// Animation Controller. /// void Stop(); @@ -100,6 +102,10 @@ namespace SHADE ///
/// Animation controller to use. void SetAnimationController(Handle ac); + + /*---------------------------------------------------------------------------------*/ + /* Parameter Functions */ + /*---------------------------------------------------------------------------------*/ /// /// Sets the parameter of the for the string. Does nothing if an invalid param name /// is provided. Type of the parameter is not checked. Also does nothing if no @@ -128,7 +134,6 @@ namespace SHADE /// Sets the flag for a trigger parameter. Does nothing if an invalid param name is /// provided or if the param name refers to a parameter that is not a trigger. /// - /// Data of the instance to . /// Name of the parameter. void SetTrigger(const std::string& paramName); @@ -156,6 +161,10 @@ namespace SHADE /// /// Handle to the current Animation Controller node. Handle GetCurrentNode() const noexcept { return animInstanceData.CurrentNode; } + /// + /// Retrieves the currently set animation controller. + /// + /// Handle GetAnimationController() const noexcept { return animController; } private: diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp index ec64bc6e..0e51f2c3 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp @@ -16,9 +16,7 @@ of DigiPen Institute of Technology is prohibited. #include "SHRig.h" #include "Math/SHMatrix.h" #include "SHRawAnimation.h" -#include "Graphics/SHVkUtil.h" -#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" -#include "ECS_Base/Managers/SHSystemManager.h" +#include "SHAnimationController.h" namespace SHADE { @@ -29,9 +27,9 @@ namespace SHADE std::optional SHAnimatorComponent::GetParameter(const std::string& paramName) { if (!animController) - return; + return {}; - return animController->GetParameter(paramName); + return animController->GetParameter(animInstanceData, paramName); } template void SHAnimatorComponent::SetParameter(const std::string& paramName, T value) @@ -39,7 +37,7 @@ namespace SHADE if (!animController) return; - return animController->SetParameter(paramName, value); + return animController->SetParameter(animInstanceData, paramName, value); } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h b/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h index 6e98c661..b57664e8 100644 --- a/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h @@ -10,8 +10,10 @@ *****************************************************************************/ #pragma once -#include "Math/SHMath.h" #include "Assets/Asset Types/SHAssetData.h" +#include "Math/Vector/SHVec3.h" +#include "Math/Vector/SHVec4.h" +#include "Math/SHQuaternion.h" #include diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index b795b1fa..1c9dc61d 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -78,7 +78,6 @@ namespace SHADE // Generate new asset const AssetID NEW_ASSET_ID = SHAssetManager::CreateNewAsset(AssetType::ANIM_CLIP, newAssetName); auto animClip = SHAssetManager::GetData(NEW_ASSET_ID); - animClip->animRawDataAssetId = SHResourceManager::GetAssetID(rawAnimation).value_or(INVALID_ASSET_ID); animClip->firstIndex = firstIndex; animClip->lastIndex = lastIndex; SHAssetManager::SaveAsset(NEW_ASSET_ID); diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index cdda1ad7..a405b298 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -370,7 +370,7 @@ namespace SHADE loadedAssetData.emplace_back(assetId); return resourceHub.Create ( - LoadOrGet(assetData.animRawDataAssetId), + LoadOrGet(assetId), // TODO: Wrong, we need to grab the parent asset's ID assetData.firstIndex, assetData.lastIndex ); diff --git a/SHADE_Engine/src/Resource/SHResourceManagerInterface.cpp b/SHADE_Engine/src/Resource/SHResourceManagerInterface.cpp index d89a7b16..8feef560 100644 --- a/SHADE_Engine/src/Resource/SHResourceManagerInterface.cpp +++ b/SHADE_Engine/src/Resource/SHResourceManagerInterface.cpp @@ -44,6 +44,21 @@ namespace SHADE return SHResourceManager::LoadOrGet(assetId); } + Handle SHResourceManagerInterface::LoadOrGetAnimationClip(AssetID assetId) + { + return SHResourceManager::LoadOrGet(assetId); + } + + Handle SHResourceManagerInterface::LoadOrGetAnimationController(AssetID assetId) + { + return SHResourceManager::LoadOrGet(assetId); + } + + Handle SHResourceManagerInterface::LoadOrGetRig(AssetID assetId) + { + return SHResourceManager::LoadOrGet(assetId); + } + /*-----------------------------------------------------------------------------------*/ /* Query Functions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Resource/SHResourceManagerInterface.h b/SHADE_Engine/src/Resource/SHResourceManagerInterface.h index 359bd7c8..a09f3463 100644 --- a/SHADE_Engine/src/Resource/SHResourceManagerInterface.h +++ b/SHADE_Engine/src/Resource/SHResourceManagerInterface.h @@ -29,6 +29,9 @@ namespace SHADE struct SHMaterialSpec; class SHMaterial; class SHFont; + class SHAnimationClip; + class SHRig; + class SHAnimationController; /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -80,6 +83,24 @@ namespace SHADE /// Asset ID of the resource to load. /// Handle to the resource to retrieve. static Handle LoadOrGetFont(AssetID assetId); + /// + /// Wrapper for SHResourceManager::LoadOrGet(). + /// + /// Asset ID of the resource to load. + /// Handle to the resource to retrieve. + static Handle LoadOrGetAnimationClip(AssetID assetId); + /// + /// Wrapper for SHResourceManager::LoadOrGet(). + /// + /// Asset ID of the resource to load. + /// Handle to the resource to retrieve. + static Handle LoadOrGetAnimationController(AssetID assetId); + /// + /// Wrapper for SHResourceManager::LoadOrGet(). + /// + /// Asset ID of the resource to load. + /// Handle to the resource to retrieve. + static Handle LoadOrGetRig(AssetID assetId); /*---------------------------------------------------------------------------------*/ /* Query Functions */ diff --git a/SHADE_Managed/src/Assets/AnimationClipAsset.cxx b/SHADE_Managed/src/Assets/AnimationClipAsset.cxx new file mode 100644 index 00000000..603d3983 --- /dev/null +++ b/SHADE_Managed/src/Assets/AnimationClipAsset.cxx @@ -0,0 +1,70 @@ +/************************************************************************************//*! +\file AnimationClipAsset.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 8, 2023 +\brief Contains the implementation of the functions of the managed + AnimationClip class. + + Note: This file is written in C++17/CLI. + +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. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "AnimationClipAsset.hxx" +// External Dependencies +#include "Resource/SHResourceManagerInterface.h" +// Project Headers +#include "Utility/Convert.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + Handle AnimationClipAsset::NativeObject::get() + try + { + return SHResourceManagerInterface::LoadOrGetAnimationClip(asset.NativeAssetID); + } + catch (const BadHandleCastException&) + { + return Handle(); + } + AssetID AnimationClipAsset::NativeAssetID::get() + { + return asset.NativeAssetID; + } + + /*---------------------------------------------------------------------------------*/ + /* Constructors/Destructor */ + /*---------------------------------------------------------------------------------*/ + AnimationClipAsset::AnimationClipAsset(AssetID AnimationClipId) + : asset{ AnimationClipId } + {} + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + AnimationClipAsset::operator bool(AnimationClipAsset asset) + { + return asset.asset; + } + + /*---------------------------------------------------------------------------------*/ + /* Conversion Operators */ + /*---------------------------------------------------------------------------------*/ + AnimationClipAsset::operator Asset(AnimationClipAsset nativeAsset) + { + return nativeAsset.asset; + } + + AnimationClipAsset::operator AnimationClipAsset(Asset asset) + { + return AnimationClipAsset(asset.NativeAssetID); + } +} diff --git a/SHADE_Managed/src/Assets/AnimationClipAsset.hxx b/SHADE_Managed/src/Assets/AnimationClipAsset.hxx new file mode 100644 index 00000000..5a8c7845 --- /dev/null +++ b/SHADE_Managed/src/Assets/AnimationClipAsset.hxx @@ -0,0 +1,90 @@ +/************************************************************************************//*! +\file AnimationClipAsset.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 8, 2023 +\brief Contains the definition of the managed AnimationClipAsset class. + + Note: This file is written in C++17/CLI. + +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 + +// External Dependencies +#include "Resource/SHHandle.h" +#include "Animation/SHAnimationClip.h" +// Project Includes +#include "NativeAsset.hxx" +#include "Engine/GenericHandle.hxx" + +namespace SHADE +{ + /// + /// Managed counterpart of the native Animation Clip object that specifies a range of + /// animation frames that can be specified to an Animator component to play an + /// animation. + /// + public value struct AnimationClipAsset + { + internal: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Copy of the Handle to the native object. + /// + property Handle NativeObject + { + Handle get(); + } + /// + /// The raw asset ID of the asset. + /// + property AssetID NativeAssetID + { + AssetID get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Constructors/Destructor */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructor for the AnimationClip. + /// + /// AssetID to the AnimationClip asset. + AnimationClipAsset(AssetID AnimationClipId); + + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a AnimationClip is valid. + /// + /// Asset to check. + /// True if the Asset is valid. + static operator bool(AnimationClipAsset asset); + + /*-----------------------------------------------------------------------------*/ + /* Conversion Operators */ + /*-----------------------------------------------------------------------------*/ + /// + /// Conversion operator to enable casting from a AnimationClip to an Asset. + /// + /// Vector3 to convert from. + static explicit operator Asset(AnimationClipAsset nativeAsset); + /// + /// Conversion operator to enable casting from a Asset to a AnimationClip. + /// + /// + static explicit operator AnimationClipAsset(Asset asset); + + protected: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Asset asset; + }; +} diff --git a/SHADE_Managed/src/Assets/AnimationControllerAsset.cxx b/SHADE_Managed/src/Assets/AnimationControllerAsset.cxx new file mode 100644 index 00000000..044f94d2 --- /dev/null +++ b/SHADE_Managed/src/Assets/AnimationControllerAsset.cxx @@ -0,0 +1,70 @@ +/************************************************************************************//*! +\file AnimationController.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 8, 2023 +\brief Contains the implementation of the functions of the managed + AnimationController class. + + Note: This file is written in C++17/CLI. + +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. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "AnimationControllerAsset.hxx" +// External Dependencies +#include "Resource/SHResourceManagerInterface.h" +// Project Headers +#include "Utility/Convert.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + Handle AnimationControllerAsset::NativeObject::get() + try + { + return SHResourceManagerInterface::LoadOrGetAnimationController(asset.NativeAssetID); + } + catch (const BadHandleCastException&) + { + return Handle(); + } + AssetID AnimationControllerAsset::NativeAssetID::get() + { + return asset.NativeAssetID; + } + + /*---------------------------------------------------------------------------------*/ + /* Constructors/Destructor */ + /*---------------------------------------------------------------------------------*/ + AnimationControllerAsset::AnimationControllerAsset(AssetID AnimationControllerId) + : asset{ AnimationControllerId } + {} + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + AnimationControllerAsset::operator bool(AnimationControllerAsset asset) + { + return asset.asset; + } + + /*---------------------------------------------------------------------------------*/ + /* Conversion Operators */ + /*---------------------------------------------------------------------------------*/ + AnimationControllerAsset::operator Asset(AnimationControllerAsset nativeAsset) + { + return nativeAsset.asset; + } + + AnimationControllerAsset::operator AnimationControllerAsset(Asset asset) + { + return AnimationControllerAsset(asset.NativeAssetID); + } +} diff --git a/SHADE_Managed/src/Assets/AnimationControllerAsset.hxx b/SHADE_Managed/src/Assets/AnimationControllerAsset.hxx new file mode 100644 index 00000000..1be74fb9 --- /dev/null +++ b/SHADE_Managed/src/Assets/AnimationControllerAsset.hxx @@ -0,0 +1,89 @@ +/************************************************************************************//*! +\file AnimationControllerAsset.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 8, 2023 +\brief Contains the definition of the managed AnimationController class. + + Note: This file is written in C++17/CLI. + +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. +*//*************************************************************************************/ +#pragma once + +// External Dependencies +#include "Resource/SHHandle.h" +#include "Animation/SHAnimationController.h" +// Project Includes +#include "NativeAsset.hxx" +#include "Engine/GenericHandle.hxx" + +namespace SHADE +{ + /// + /// Managed counterpart of the native AnimationController object containing the + /// state machine for controlling what AnimationClips that an Animator should play. + /// + public value struct AnimationControllerAsset + { + internal: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Copy of the Handle to the native object. + /// + property Handle NativeObject + { + Handle get(); + } + /// + /// The raw asset ID of the asset. + /// + property AssetID NativeAssetID + { + AssetID get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Constructors/Destructor */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructor for the AnimationController. + /// + /// AssetID to the AnimationController asset. + AnimationControllerAsset(AssetID AnimationControllerId); + + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a AnimationController is valid. + /// + /// Asset to check. + /// True if the Asset is valid. + static operator bool(AnimationControllerAsset asset); + + /*-----------------------------------------------------------------------------*/ + /* Conversion Operators */ + /*-----------------------------------------------------------------------------*/ + /// + /// Conversion operator to enable casting from a AnimationController to an Asset. + /// + /// Vector3 to convert from. + static explicit operator Asset(AnimationControllerAsset nativeAsset); + /// + /// Conversion operator to enable casting from a Asset to a AnimationController. + /// + /// + static explicit operator AnimationControllerAsset(Asset asset); + + protected: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Asset asset; + }; +} diff --git a/SHADE_Managed/src/Assets/AnimationRigAsset.cxx b/SHADE_Managed/src/Assets/AnimationRigAsset.cxx new file mode 100644 index 00000000..154c6aee --- /dev/null +++ b/SHADE_Managed/src/Assets/AnimationRigAsset.cxx @@ -0,0 +1,70 @@ +/************************************************************************************//*! +\file AnimationRigAsset.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 8, 2023 +\brief Contains the implementation of the functions of the managed + AnimationRig class. + + Note: This file is written in C++17/CLI. + +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. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "AnimationRigAsset.hxx" +// External Dependencies +#include "Resource/SHResourceManagerInterface.h" +// Project Headers +#include "Utility/Convert.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + Handle AnimationRigAsset::NativeObject::get() + try + { + return SHResourceManagerInterface::LoadOrGetRig(asset.NativeAssetID); + } + catch (const BadHandleCastException&) + { + return Handle(); + } + AssetID AnimationRigAsset::NativeAssetID::get() + { + return asset.NativeAssetID; + } + + /*---------------------------------------------------------------------------------*/ + /* Constructors/Destructor */ + /*---------------------------------------------------------------------------------*/ + AnimationRigAsset::AnimationRigAsset(AssetID AnimationRigId) + : asset{ AnimationRigId } + {} + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + AnimationRigAsset::operator bool(AnimationRigAsset asset) + { + return asset.asset; + } + + /*---------------------------------------------------------------------------------*/ + /* Conversion Operators */ + /*---------------------------------------------------------------------------------*/ + AnimationRigAsset::operator Asset(AnimationRigAsset nativeAsset) + { + return nativeAsset.asset; + } + + AnimationRigAsset::operator AnimationRigAsset(Asset asset) + { + return AnimationRigAsset(asset.NativeAssetID); + } +} diff --git a/SHADE_Managed/src/Assets/AnimationRigAsset.hxx b/SHADE_Managed/src/Assets/AnimationRigAsset.hxx new file mode 100644 index 00000000..be43b7f0 --- /dev/null +++ b/SHADE_Managed/src/Assets/AnimationRigAsset.hxx @@ -0,0 +1,89 @@ +/************************************************************************************//*! +\file AnimationRigAsset.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 8, 2023 +\brief Contains the definition of the managed AnimationRigAsset class. + + Note: This file is written in C++17/CLI. + +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 + +// External Dependencies +#include "Resource/SHHandle.h" +#include "Animation/SHRig.h" +// Project Includes +#include "NativeAsset.hxx" +#include "Engine/GenericHandle.hxx" + +namespace SHADE +{ + /// + /// Managed counterpart of the native Animation Rig object that specifies how an + /// Animation Clip affects the model that this Rig is attached to. + /// + public value struct AnimationRigAsset + { + internal: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Copy of the Handle to the native object. + /// + property Handle NativeObject + { + Handle get(); + } + /// + /// The raw asset ID of the asset. + /// + property AssetID NativeAssetID + { + AssetID get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Constructors/Destructor */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructor for the AnimationRig. + /// + /// AssetID to the AnimationRig asset. + AnimationRigAsset(AssetID AnimationRigId); + + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a AnimationRig is valid. + /// + /// Asset to check. + /// True if the Asset is valid. + static operator bool(AnimationRigAsset asset); + + /*-----------------------------------------------------------------------------*/ + /* Conversion Operators */ + /*-----------------------------------------------------------------------------*/ + /// + /// Conversion operator to enable casting from a AnimationRig to an Asset. + /// + /// Vector3 to convert from. + static explicit operator Asset(AnimationRigAsset nativeAsset); + /// + /// Conversion operator to enable casting from a Asset to a AnimationRig. + /// + /// + static explicit operator AnimationRigAsset(Asset asset); + + protected: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Asset asset; + }; +} diff --git a/SHADE_Managed/src/Components/Animator.cxx b/SHADE_Managed/src/Components/Animator.cxx new file mode 100644 index 00000000..364ce046 --- /dev/null +++ b/SHADE_Managed/src/Components/Animator.cxx @@ -0,0 +1,159 @@ +/************************************************************************************//*! +\file Animator.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 8, 2023 +\brief Contains the definition of the functions of the managed Animator class. + + Note: This file is written in C++17/CLI. + +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. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "Animator.hxx" +#include "Assets/NativeAsset.hxx" +#include "Utility/Convert.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + Animator::Animator(Entity entity) + : Component(entity) + {} + + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + AnimationControllerAsset Animator::AnimationController::get() + { + auto controller = GetNativeComponent()->GetAnimationController(); + return controller ? AnimationControllerAsset(controller) : AnimationControllerAsset(); + } + void Animator::AnimationController::set(AnimationControllerAsset value) + { + if (value) + { + GetNativeComponent()->SetAnimationController(Handle()); + } + else + { + GetNativeComponent()->SetAnimationController(value.NativeObject); + } + } + AnimationRigAsset Animator::Rig::get() + { + auto rig = GetNativeComponent()->GetRig(); + return rig ? AnimationRigAsset(rig) : AnimationRigAsset(); + } + void Animator::Rig::set(AnimationRigAsset value) + { + if (value) + { + GetNativeComponent()->SetRig(Handle()); + } + else + { + GetNativeComponent()->SetRig(Handle(value.NativeObject)); + } + } + System::String^ Animator::CurrentNodeName::get() + { + const auto CURR_NODE = GetNativeComponent()->GetCurrentNode(); + if (CURR_NODE) + return Convert::ToCLI(CURR_NODE->Name); + return nullptr; + } + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void Animator::Play() + { + GetNativeComponent()->Play(); + } + + void Animator::Play(AnimationClipAsset clip) + { + GetNativeComponent()->Play(clip.NativeObject); + } + + void Animator::PlayOneShot(AnimationClipAsset clip) + { + GetNativeComponent()->PlayOneShot(clip.NativeObject); + } + + void Animator::PlayFromStart() + { + GetNativeComponent()->Play(); + } + + void Animator::Pause() + { + GetNativeComponent()->Pause(); + } + + void Animator::Stop() + { + GetNativeComponent()->Stop(); + } + + /*---------------------------------------------------------------------------------*/ + /* Parameter Functions */ + /*---------------------------------------------------------------------------------*/ + generic + void Animator::SetParameter(System::String^ paramName, T value) + { + if (T::typeid == int::typeid) + { + GetNativeComponent()->SetParameter(Convert::ToNative(paramName), static_cast(value)); + } + else if (T::typeid == float::typeid) + { + GetNativeComponent()->SetParameter(Convert::ToNative(paramName), static_cast(value)); + } + else if (T::typeid == bool::typeid) + { + GetNativeComponent()->SetParameter(Convert::ToNative(paramName), static_cast(value)); + } + } + + void Animator::SetTrigger(System::String^ paramName) + { + GetNativeComponent()->SetTrigger(Convert::ToNative(paramName)); + } + + System::Nullable Animator::GetIntParameter(System::String^ paramName) + { + auto val = GetNativeComponent()->GetParameter(Convert::ToNative(paramName)); + if (val.has_value()) + return System::Nullable(val.value()); + return {}; + } + + System::Nullable Animator::GetFloatParameter(System::String^ paramName) + { + auto val = GetNativeComponent()->GetParameter(Convert::ToNative(paramName)); + if (val.has_value()) + return System::Nullable(val.value()); + return {}; + } + + System::Nullable Animator::GetBoolParameter(System::String^ paramName) + { + auto val = GetNativeComponent()->GetParameter(Convert::ToNative(paramName)); + if (val.has_value()) + return System::Nullable(val.value()); + return {}; + } + + System::Nullable Animator::GetTriggerState(System::String^ paramName) + { + return GetBoolParameter(paramName); + } +} diff --git a/SHADE_Managed/src/Components/Animator.hxx b/SHADE_Managed/src/Components/Animator.hxx new file mode 100644 index 00000000..7100c54b --- /dev/null +++ b/SHADE_Managed/src/Components/Animator.hxx @@ -0,0 +1,164 @@ +/************************************************************************************//*! +\file Animator.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 8, 2023 +\brief Contains the definition of the managed Animator class with the + declaration of functions for working with it. + + Note: This file is written in C++17/CLI. + +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 "Components/Component.hxx" +// External Dependencies +#include "Animation/SHAnimatorComponent.h" +// Project Includes +#include "Assets/AnimationClipAsset.hxx" +#include "Assets/AnimationControllerAsset.hxx" +#include "Assets/AnimationRigAsset.hxx" + +namespace SHADE +{ + /// + /// CLR version of the SHADE Engine's SHAnimatorComponent. + /// + public ref class Animator : public Component + { + internal: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructs a Animator Component that represents a native Animator + /// component tied to the specified Entity. + /// + /// Entity that this Component will be tied to. + Animator(Entity entity); + + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Animation Controller used to controller the animation of this Animator. + /// + property AnimationControllerAsset AnimationController + { + AnimationControllerAsset get(); + void set(AnimationControllerAsset value); + } + /// + /// The shared Material used to render this Animator and other Animators + /// using the same base Material. + /// + property AnimationRigAsset Rig + { + AnimationRigAsset get(); + void set(AnimationRigAsset value); + } + /// + /// Name of the current node if there is an animation controller attached. If + /// there is none, null is returned. + /// + property System::String^ CurrentNodeName + { + System::String^ get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Plays the currently loaded animation from the last time. + /// + void Play(); + /// + /// Plays the specified animation clip from the start. This will unset any + /// SHAnimationControllers that have been set. + /// + /// Animation clip to play. + void Play(AnimationClipAsset clip); + /// + /// Plays the specified animation clip from the start one time only. This will unset + /// any SHAnimationControllers that have been set. + /// + /// Animation clip to play. + void PlayOneShot(AnimationClipAsset clip); + /// + /// Plays the currently loaded animation clip from the start. Note that this only + /// works when using manual playback mode. + /// + void PlayFromStart(); + /// + /// Pauses the animation at the current time. + /// + void Pause(); + /// + /// Stops the animation and resets the play time back to 0. Note that this only + /// works when using manual playback mode. This is not supported when using an + /// Animation Controller. + /// + void Stop(); + + /*-----------------------------------------------------------------------------*/ + /* Parameter Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Sets the parameter of the for the string. Does nothing if an invalid param name + /// is provided. Type of the parameter is not checked. Also does nothing if no + /// animation controller is specified. + /// + /// + /// Type of parameter. Only bool, int, floats are supported. + /// + /// Name of the parameter. + /// Value to set the parameter to. + generic + void SetParameter(System::String^ paramName, T value); + /// + /// Sets the flag for a trigger parameter. Does nothing if an invalid param name is + /// provided or if the param name refers to a parameter that is not a trigger. + /// + /// Name of the parameter. + void SetTrigger(System::String^ paramName); + /// + /// Gets the parameter of the for the named parameter of type int. Types are + /// checked and will not return a value if there is nothing. Returns nothing if + /// there is no animation controller specified either. + /// + /// Name of the parameter. + /// The value of the parameter or nothing if invalid. + System::Nullable GetIntParameter(System::String^ paramName); + /// + /// Gets the parameter of the for the named parameter of type float. Types are + /// checked and will not return a value if there is nothing. Returns nothing if + /// there is no animation controller specified either. + /// + /// Name of the parameter. + /// The value of the parameter or nothing if invalid. + System::Nullable GetFloatParameter(System::String^ paramName); + /// + /// Gets the parameter of the for the named parameter of type bool. Types are + /// checked and will not return a value if there is nothing. Returns nothing if + /// there is no animation controller specified either. + /// + /// Name of the parameter. + /// The value of the parameter or nothing if invalid. + System::Nullable GetBoolParameter(System::String^ paramName); + /// + /// Checks if the trigger flag for the named trigger parameter is set. Types are + /// checked and will not return a value if there is nothing. Returns nothing if + /// there is no animation controller specified either. + /// + /// Name of the parameter. + /// True if the trigger is set. + System::Nullable GetTriggerState(System::String^ paramName); + }; +} + From 43edfeb14f674f4e588593199ec5c5b6c5166bbf Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 8 Mar 2023 16:13:04 +0800 Subject: [PATCH 35/69] Added serialization of animation assets for scripts --- .../Serialisation/SerialisationUtilities.cxx | 159 ++++++++++-------- .../Serialisation/SerialisationUtilities.h++ | 27 ++- 2 files changed, 105 insertions(+), 81 deletions(-) diff --git a/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx b/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx index b31209c1..aafd510e 100644 --- a/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx @@ -23,6 +23,9 @@ of DigiPen Institute of Technology is prohibited. #include "Assets/MeshAsset.hxx" #include "Scripts/Script.hxx" #include "Scripts/ScriptStore.hxx" +#include "Assets/AnimationClipAsset.hxx" +#include "Assets/AnimationControllerAsset.hxx" +#include "Assets/AnimationRigAsset.hxx" /*-------------------------------------------------------------------------------------*/ /* File-Level Constants */ @@ -164,24 +167,27 @@ namespace SHADE YAML::Node fieldNode; // Retrieve string for the YAML - const bool PRIMITIVE_SERIALIZED = fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode) || - fieldInsertYaml(fieldInfo, object, fieldNode); + const bool PRIMITIVE_SERIALIZED = fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml (fieldInfo, object, fieldNode); // Serialization of more complex types if (!PRIMITIVE_SERIALIZED) @@ -228,24 +234,27 @@ namespace SHADE bool SerialisationUtilities::varInsertYaml(System::Object^ object, YAML::Node& fieldNode) { const bool INSERTED = - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode) || - varInsertYamlInternal(object, fieldNode); + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode) || + varInsertYamlInternal(object, fieldNode); return INSERTED; } @@ -255,24 +264,27 @@ namespace SHADE bool SerialisationUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) { const bool ASSIGNED = - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml(fieldInfo, object, node) || - fieldAssignYaml(fieldInfo, object, node) || - fieldAssignYaml(fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml(fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node) || - fieldAssignYaml (fieldInfo, object, node); + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node); if (!ASSIGNED) { if (ReflectionUtilities::FieldIsList(fieldInfo)) @@ -329,24 +341,27 @@ namespace SHADE bool SerialisationUtilities::varAssignYaml(System::Object^% object, YAML::Node& node) { const bool DESERIALISED = - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal(object, node) || - varAssignYamlInternal(object, node) || - varAssignYamlInternal(object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal(object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node) || - varAssignYamlInternal (object, node); + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node) || + varAssignYamlInternal(object, node); return DESERIALISED; } } diff --git a/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ index d2043f6b..80f1e4aa 100644 --- a/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ +++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ @@ -60,9 +60,12 @@ namespace SHADE { fieldNode = MAX_EID; } - else if constexpr (std::is_same_v || - std::is_same_v || - std::is_same_v) + else if constexpr (std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) { fieldNode = INVALID_ASSET_ID; } @@ -128,9 +131,12 @@ namespace SHADE return true; } } - else if constexpr (std::is_same_v || - std::is_same_v || - std::is_same_v) + else if constexpr (std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) { if (object->GetType() == FieldType::typeid) { @@ -254,9 +260,12 @@ namespace SHADE const uint32_t EID = node.as(); object = (EID == MAX_EID ? GameObject() : GameObject(EID)); } - else if constexpr (std::is_same_v || - std::is_same_v || - std::is_same_v) + else if constexpr (std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) { if (object->GetType() == FieldType::typeid) { From 35b60a24e4153a0fef209c2d79f20c2f95b0e0c7 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 8 Mar 2023 19:06:57 +0800 Subject: [PATCH 36/69] Added variable to control number of simulation steps for the SimulateBody method --- Assets/Scenes/Level3.shade | 53 +++++++++++++++++++ .../src/Physics/System/SHPhysicsSystem.cpp | 12 +++-- .../src/Physics/System/SHPhysicsSystem.h | 34 +++++++++--- 3 files changed, 88 insertions(+), 11 deletions(-) diff --git a/Assets/Scenes/Level3.shade b/Assets/Scenes/Level3.shade index e7ece081..19224e22 100644 --- a/Assets/Scenes/Level3.shade +++ b/Assets/Scenes/Level3.shade @@ -6017,6 +6017,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -6347,6 +6348,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: true Sleeping Enabled: true @@ -6409,6 +6411,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: true Sleeping Enabled: true @@ -6471,6 +6474,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: true Sleeping Enabled: true @@ -6623,6 +6627,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -6674,6 +6679,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -6725,6 +6731,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -6776,6 +6783,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -6827,6 +6835,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -6878,6 +6887,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -6929,6 +6939,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -6980,6 +6991,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7031,6 +7043,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7082,6 +7095,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7133,6 +7147,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7184,6 +7199,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7235,6 +7251,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7286,6 +7303,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7337,6 +7355,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7388,6 +7407,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7439,6 +7459,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7490,6 +7511,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7541,6 +7563,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7592,6 +7615,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7643,6 +7667,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7700,6 +7725,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7741,6 +7767,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7782,6 +7809,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7823,6 +7851,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7864,6 +7893,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7921,6 +7951,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7962,6 +7993,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8003,6 +8035,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8044,6 +8077,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8085,6 +8119,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8142,6 +8177,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8193,6 +8229,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8244,6 +8281,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8295,6 +8333,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8346,6 +8385,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8397,6 +8437,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8454,6 +8495,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8505,6 +8547,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8556,6 +8599,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8607,6 +8651,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8658,6 +8703,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8709,6 +8755,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8766,6 +8813,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8817,6 +8865,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8868,6 +8917,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8919,6 +8969,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -8970,6 +9021,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -9027,6 +9079,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: false Interpolate: false Sleeping Enabled: true diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 787a9f78..2e5f5c2c 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -274,6 +274,7 @@ namespace SHADE // Invert the inertia for (size_t i = 0; i < SHVec3::SIZE; ++i) localInvInertia[i] = 1.0f / localInvInertia[i]; + // Build raycast layer from colliders. If none exist....then this never stops simulating technically. @@ -297,16 +298,17 @@ namespace SHADE raycastInfo.continuous = false; raycastInfo.layers = raycastLayers; - bool terminate = true; + bool terminate = true; + int iterationCounter = simInfo.maxSteps; do { raycastInfo.distance = linearVelocity.Length(); raycastInfo.ray.position = bodyPosition; raycastInfo.ray.direction = SHVec3::Normalise(linearVelocity); - terminate = !Raycast(raycastInfo).empty(); + terminate = !Raycast(raycastInfo).empty() || iterationCounter == 0; if (terminate) - break; + return; // Compute world space data const SHMatrix R = SHMatrix::Rotate(bodyOrientation); @@ -348,7 +350,7 @@ namespace SHADE const SHQuaternion QV = SHQuaternion{ angularVelocity.x * simInfo.timeStep, angularVelocity.y * simInfo.timeStep, angularVelocity.z * simInfo.timeStep, 0.0f } * 0.5f; bodyPosition += linearVelocity * simInfo.timeStep; - bodyOrientation += bodyOrientation * QV; + bodyOrientation += bodyOrientation * QV * SHQuaternion::FromEuler(ANGULAR_LOCK); bodyOrientation = SHQuaternion::Normalise(bodyOrientation); // Clear forces after the first frame @@ -362,6 +364,8 @@ namespace SHADE positions.emplace_back(bodyPosition); + --iterationCounter; + } while (true); } diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index d95203b9..f466481d 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -50,19 +50,39 @@ namespace SHADE /** * @brief - * Used to simulate the motion of a rigid body until it hits something. + * Used to simulate the motion of a rigid body, ignoring collision detection and response. + * @param bodyEID + * The EntityID of the Rigid Body to simulate. + * @param force + * The force applied onto the Rigid Body. + * @param forceOffset + * The position to apply the force onto the body relative to it's local Center of Mass. + * @param torque + * The torque to apply onto the Rigid Body. + * @param continuousForce + * If the force should be applied every step throughout the simulation. Defaults to false.
+ * True : The force indicated is added to the body every step, therefore it has constant acceleration. + * False: The force is applied only in the first step, therefore it has constant speed. + * @param timeStep + * The timestep for each step of the simulation. Defaults to 0.016s (The default Fixed DT) + * @param maxSteps + * The number of steps to run the simulation for. Defaults to -1. + * < 0 : Runs until the object may hit something. Hit detection is done through raycasting. + * = 0 : Runs only the current step and checks if it may hit something. + * > 0 : Runs for the given number of steps or until it may hit something. */ struct SimulateBodyInfo { - EntityID bodyEID = MAX_EID; + EntityID bodyEID = MAX_EID; - SHVec3 force = SHVec3::Zero; - SHVec3 forceOffset = SHVec3::Zero; - SHVec3 torque = SHVec3::Zero; + SHVec3 force = SHVec3::Zero; + SHVec3 forceOffset = SHVec3::Zero; + SHVec3 torque = SHVec3::Zero; // Whether or not to clear the force after the first iteration - bool continuousForce = false; - float timeStep = static_cast(SHPhysicsConstants::DEFAULT_FIXED_DT); + bool continuousForce = false; + float timeStep = static_cast(SHPhysicsConstants::DEFAULT_FIXED_DT); + int maxSteps = -1; }; From 7ab1ee6fec3868dbf24204bde55ba313bad2923d Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 8 Mar 2023 20:34:11 +0800 Subject: [PATCH 37/69] Added serialization for animation assets for scripts --- SHADE_Managed/src/Editor/Editor.cxx | 83 ++++++++++++++++------------- SHADE_Managed/src/Editor/Editor.h++ | 39 ++++++++++++++ 2 files changed, 85 insertions(+), 37 deletions(-) diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index e10111c3..db8bd412 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -18,6 +18,7 @@ of DigiPen Institute of Technology is prohibited. #include "Editor/Editor.hxx" // STL Includes #include +#include // Project Headers #include "Components/Component.hxx" #include "Scripts/ScriptStore.hxx" @@ -30,7 +31,9 @@ of DigiPen Institute of Technology is prohibited. #include "RangeAttribute.hxx" #include "Math/Vector2.hxx" #include "Math/Vector3.hxx" -#include +#include "Assets/AnimationClipAsset.hxx" +#include "Assets/AnimationControllerAsset.hxx" +#include "Assets/AnimationRigAsset.hxx" // Using Directives using namespace System; @@ -163,24 +166,27 @@ namespace SHADE bool isHovered = false; const bool MODIFIED_PRIMITIVE = - renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputCheckbox, &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputFloat , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputDouble , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputVec2 , &isHovered) || - renderSpecificField(field, object, SHEditorUI::InputVec3 , &isHovered) || - renderSpecificField(field, object, nullptr , &isHovered) || - renderSpecificField(field, object, nullptr , &isHovered) || - renderSpecificField(field, object, nullptr , &isHovered) || - renderSpecificField(field, object, nullptr , &isHovered) || - renderSpecificField(field, object, nullptr , &isHovered) || - renderSpecificField(field, object, nullptr , &isHovered); + renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputInt , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputCheckbox, &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputFloat , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputDouble , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputVec2 , &isHovered) || + renderSpecificField(field, object, SHEditorUI::InputVec3 , &isHovered) || + renderSpecificField(field, object, nullptr , &isHovered) || + renderSpecificField(field, object, nullptr , &isHovered) || + renderSpecificField(field, object, nullptr , &isHovered) || + renderSpecificField(field, object, nullptr , &isHovered) || + renderSpecificField(field, object, nullptr , &isHovered) || + renderSpecificField(field, object, nullptr , &isHovered) || + renderSpecificField(field, object, nullptr , &isHovered) || + renderSpecificField(field, object, nullptr , &isHovered) || + renderSpecificField(field, object, nullptr , &isHovered); if (!MODIFIED_PRIMITIVE) { @@ -324,24 +330,27 @@ namespace SHADE bool modified; const bool RENDERED = - renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputCheckbox, nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputFloat , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputDouble , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputVec2 , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, SHEditorUI::InputVec3 , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || - renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified); + renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputCheckbox, nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputFloat , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputDouble , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputVec2 , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, SHEditorUI::InputVec3 , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified) || + renderFieldEditor(fieldName, object, nullptr , nullptr, rangeAttrib, modified); return modified; } diff --git a/SHADE_Managed/src/Editor/Editor.h++ b/SHADE_Managed/src/Editor/Editor.h++ index 37d5c27d..f6b0f06d 100644 --- a/SHADE_Managed/src/Editor/Editor.h++ +++ b/SHADE_Managed/src/Editor/Editor.h++ @@ -23,6 +23,9 @@ of DigiPen Institute of Technology is prohibited. #include "Assets/FontAsset.hxx" #include "Assets/MeshAsset.hxx" #include "Assets/MaterialAsset.hxx" +#include "Assets/AnimationClipAsset.hxx" +#include "Assets/AnimationControllerAsset.hxx" +#include "Assets/AnimationRigAsset.hxx" namespace SHADE { @@ -237,6 +240,42 @@ namespace SHADE return true; } + return false; + } + template<> + bool Editor::renderFieldEditorInternal(const std::string& fieldName, interior_ptr managedValPtr, EditorFieldFunc, bool* isHovered, RangeAttribute^) + { + uint32_t assetId = managedValPtr->NativeAssetID; + if (SHEditorUI::InputAssetField(fieldName, assetId, AssetType::FONT, isHovered)) + { + *managedValPtr = AnimationClipAsset(assetId); + return true; + } + + return false; + } + template<> + bool Editor::renderFieldEditorInternal(const std::string& fieldName, interior_ptr managedValPtr, EditorFieldFunc, bool* isHovered, RangeAttribute^) + { + uint32_t assetId = managedValPtr->NativeAssetID; + if (SHEditorUI::InputAssetField(fieldName, assetId, AssetType::MESH, isHovered)) + { + *managedValPtr = AnimationControllerAsset(assetId); + return true; + } + + return false; + } + template<> + bool Editor::renderFieldEditorInternal(const std::string& fieldName, interior_ptr managedValPtr, EditorFieldFunc, bool* isHovered, RangeAttribute^) + { + uint32_t assetId = managedValPtr->NativeAssetID; + if (SHEditorUI::InputAssetField(fieldName, assetId, AssetType::MATERIAL, isHovered)) + { + *managedValPtr = AnimationRigAsset(assetId); + return true; + } + return false; } } From 57a8e385e4a2f39d1021f6e6c86780dea3773566 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 8 Mar 2023 20:58:21 +0800 Subject: [PATCH 38/69] Added editor field for Animation Controller of the Animator component in the inspector --- SHADE_Engine/src/Assets/SHAssetMacros.h | 4 ++ .../Inspector/SHEditorComponentView.hpp | 65 +++++++++++++++---- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index b6ee240e..4784560b 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -60,6 +60,7 @@ enum class AssetType : AssetTypeMeta AUDIO_BANK, ANIM_CONTAINER, ANIM_CLIP, + ANIM_CONTROLLER, MAX_COUNT }; constexpr size_t TYPE_COUNT{ static_cast(AssetType::MAX_COUNT) }; @@ -82,6 +83,7 @@ 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_CONTROLLER_FOLDER{ "/Animation Controllers/" }; // ASSET EXTENSIONS @@ -99,6 +101,7 @@ 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_CONTAINER_EXTENSION{ ".shanimcontainer" }; +constexpr std::string_view ANIM_CONTROLLER_EXTENSION{ ".shanimcontroller" }; constexpr std::string_view FILLER_EXTENSION{"dummy"}; constexpr std::string_view EXTENSIONS[] = { @@ -115,6 +118,7 @@ constexpr std::string_view EXTENSIONS[] = { FONT_EXTENSION, AUDIO_BANK_EXTENSION, ANIM_CONTAINER_EXTENSION, + ANIM_CONTROLLER_EXTENSION, FILLER_EXTENSION }; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index b037d4d9..91c304e0 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -640,23 +640,29 @@ namespace SHADE if (ImGui::CollapsingHeader(componentType.get_name().data())) { DrawContextMenu(component); + + /* Animation Rig */ Handle const& rig = component->GetRig(); const auto RIG_NAME = rig ? SHResourceManager::GetAssetName(rig).value_or("") : ""; - SHEditorWidgets::DragDropReadOnlyField("Rig", RIG_NAME, [component]() - { - Handle const& rig = component->GetRig(); - return SHResourceManager::GetAssetID(rig).value_or(0); - }, - [component](AssetID const& id) - { - if (SHAssetManager::GetType(id) != AssetType::MODEL) + SHEditorWidgets::DragDropReadOnlyField + ( + "Rig", RIG_NAME, [component]() { - SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!") - return; - } - component->SetRig(SHResourceManager::LoadOrGet(id)); - SHResourceManager::FinaliseChanges(); - }, SHDragDrop::DRAG_RESOURCE); + Handle const& rig = component->GetRig(); + return SHResourceManager::GetAssetID(rig).value_or(0); + }, + [component](AssetID const& id) + { + if (SHAssetManager::GetType(id) != AssetType::MODEL) + { + SHLOG_WARNING("Attempted to assign non mesh rig asset to Animator Rig property!") + return; + } + component->SetRig(SHResourceManager::LoadOrGet(id)); + SHResourceManager::FinaliseChanges(); + }, + SHDragDrop::DRAG_RESOURCE + ); if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { if (Handle const& rig = component->GetRig()) @@ -665,6 +671,37 @@ namespace SHADE SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); } } + + /* Animation Controller */ + Handle animController = component->GetAnimationController(); + const auto AC_NAME = animController ? SHResourceManager::GetAssetName(animController).value_or("") : ""; + SHEditorWidgets::DragDropReadOnlyField + ( + "Animation Controller", AC_NAME, [component]() + { + Handle ac = component->GetAnimationController(); + return SHResourceManager::GetAssetID(ac).value_or(0); + }, + [component](AssetID const& id) + { + if (SHAssetManager::GetType(id) != AssetType::ANIM_CONTROLLER) + { + SHLOG_WARNING("Attempted to assign non animation controller asset to Animator Animation Controller property!") + return; + } + component->SetAnimationController(SHResourceManager::LoadOrGet(id)); + SHResourceManager::FinaliseChanges(); + }, + SHDragDrop::DRAG_RESOURCE + ); + if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) + { + if (Handle ac = component->GetAnimationController()) + { + AssetID assetID = SHResourceManager::GetAssetID(ac).value_or(0); + SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); + } + } } else { From 4012eb97ba7cd56796f53136272c03a7ddcaf839 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Wed, 8 Mar 2023 21:23:03 +0800 Subject: [PATCH 39/69] Auto stash before merge of "SP3-1-Rendering" and "origin/main" Solved shadow bugs and WIP trajectory --- Assets/Scenes/Level2.shade | 139 +++++++++++++++++- Assets/Scenes/Scene2.shade | 56 ++++++- Assets/Shaders/DeferredComposite_CS.glsl | 24 ++- Assets/Shaders/DeferredComposite_CS.shshaderb | Bin 11109 -> 11569 bytes .../GlobalData/SHGraphicsPredefinedData.cpp | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 3 +- .../MiddleEnd/Lights/SHLightComponent.cpp | 20 +-- .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 4 +- .../SHTrajectoryRenderableComponent.h | 4 + .../SHTrajectoryRenderingSubSystem.cpp | 20 ++- .../Graphics/Pipeline/SHVkPipelineLayout.cpp | 4 +- .../RenderGraph/SHRenderGraphNodeCompute.cpp | 2 +- 12 files changed, 240 insertions(+), 38 deletions(-) diff --git a/Assets/Scenes/Level2.shade b/Assets/Scenes/Level2.shade index d068f3ca..dadf7bf0 100644 --- a/Assets/Scenes/Level2.shade +++ b/Assets/Scenes/Level2.shade @@ -21,6 +21,7 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 Strength: 1 + Casting Shadows: false IsActive: true Scripts: ~ - EID: 5 @@ -35,6 +36,7 @@ Color: {x: 0.901608765, y: 0.867841423, z: 1, w: 1} Layer: 4294967295 Strength: 0.699999988 + Casting Shadows: false IsActive: true Scripts: ~ - EID: 65674 @@ -54,6 +56,7 @@ Color: {x: 0, y: 0, z: 0, w: 1} Layer: 4294967295 Strength: 1 + Casting Shadows: true IsActive: true Scripts: ~ - EID: 240 @@ -80,6 +83,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -131,6 +135,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -182,6 +187,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -233,6 +239,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -284,6 +291,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -335,6 +343,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -386,6 +395,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -437,6 +447,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -494,6 +505,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -535,6 +547,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -576,6 +589,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -617,6 +631,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -658,6 +673,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -709,6 +725,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -760,6 +777,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -811,6 +829,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -862,6 +881,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -913,6 +933,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -964,6 +985,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1015,6 +1037,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1066,6 +1089,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1117,6 +1141,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1168,6 +1193,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1219,6 +1245,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1270,6 +1297,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1321,6 +1349,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1372,6 +1401,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1423,6 +1453,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1474,6 +1505,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1525,6 +1557,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1576,6 +1609,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1627,6 +1661,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1684,6 +1719,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1735,6 +1771,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1786,6 +1823,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1837,6 +1875,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1888,6 +1927,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1939,6 +1979,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -1996,6 +2037,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2047,6 +2089,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2098,6 +2141,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2149,6 +2193,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2200,6 +2245,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2251,6 +2297,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2308,6 +2355,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2349,6 +2397,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2390,6 +2439,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2431,6 +2481,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2472,6 +2523,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2529,6 +2581,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2570,6 +2623,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2611,6 +2665,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2652,6 +2707,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -2695,6 +2751,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: true Sleeping Enabled: true @@ -2757,6 +2814,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: true Sleeping Enabled: true @@ -2999,6 +3057,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: false Interpolate: false Sleeping Enabled: true @@ -3180,6 +3239,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3227,6 +3287,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3268,6 +3329,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3309,6 +3371,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3350,6 +3413,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3391,6 +3455,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3438,6 +3503,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3479,6 +3545,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3520,6 +3587,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3561,6 +3629,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3602,6 +3671,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3649,6 +3719,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3690,6 +3761,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3731,6 +3803,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3772,6 +3845,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3813,6 +3887,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3860,6 +3935,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3901,6 +3977,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3942,6 +4019,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -3983,6 +4061,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4024,6 +4103,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4071,6 +4151,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4112,6 +4193,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4153,6 +4235,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4194,6 +4277,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4235,6 +4319,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4282,6 +4367,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4323,6 +4409,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4364,6 +4451,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4405,6 +4493,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4446,6 +4535,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4493,6 +4583,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4534,6 +4625,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4575,6 +4667,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4616,6 +4709,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4657,6 +4751,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4704,6 +4799,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4745,6 +4841,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4786,6 +4883,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4827,6 +4925,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4868,6 +4967,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4915,6 +5015,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4956,6 +5057,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -4997,6 +5099,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -5038,6 +5141,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -5079,6 +5183,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -5126,6 +5231,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -5167,6 +5273,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -5208,6 +5315,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -5249,6 +5357,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -5373,6 +5482,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -7421,7 +7531,7 @@ Components: Transform Component: Translate: {x: 2, y: 0, z: 0} - Rotate: {x: -0, y: 0, z: 0} + Rotate: {x: -0, y: 0, z: -0} Scale: {x: 1, y: 1, z: 1} IsActive: true Renderable Component: @@ -14149,4 +14259,31 @@ Perspective: true FOV: 90 IsActive: true + Scripts: ~ +- EID: 537 + Name: ShadowFixRoof + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.0146873593, y: 2.83242893, z: 0} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 5.15999985, y: 5.15999985, z: 5.15999985} + IsActive: true + Renderable Component: + Mesh: 142812576 + Material: 127069936 + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Collision Tag: 0 + Type: Box + Half Extents: {x: 2, y: 0.0500000007, z: 2} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: -0.00999999978, z: 0} + Rotation Offset: {x: 0, y: 0, z: 0} + IsActive: true Scripts: ~ \ No newline at end of file diff --git a/Assets/Scenes/Scene2.shade b/Assets/Scenes/Scene2.shade index 891c9664..c45d8b51 100644 --- a/Assets/Scenes/Scene2.shade +++ b/Assets/Scenes/Scene2.shade @@ -26,7 +26,7 @@ NumberOfChildren: 1 Components: Transform Component: - Translate: {x: 0, y: 0.189419448, z: 0} + Translate: {x: 0, y: 0.201105013, z: 0} Rotate: {x: 0.00523597933, y: -2.96353412, z: -6.40293041e-10} Scale: {x: 1.00000191, y: 1, z: 1.00000191} IsActive: true @@ -41,9 +41,9 @@ NumberOfChildren: 0 Components: Transform Component: - Translate: {x: 0.006237939, y: -0.000393368304, z: 0} - Rotate: {x: -0, y: 2.79945588, z: 0} - Scale: {x: 1.0000881, y: 1, z: 1.0000881} + Translate: {x: 0.00623797067, y: -0.000395311916, z: -2.03726813e-08} + Rotate: {x: 1.35041773e-08, y: 2.79945588, z: -9.6043955e-09} + Scale: {x: 1.00008798, y: 1, z: 1.0000881} IsActive: true Renderable Component: Mesh: 144838771 @@ -67,6 +67,7 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 Strength: 0 + Casting Shadows: false IsActive: true Scripts: ~ - EID: 4 @@ -81,6 +82,7 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 Strength: 0.600000024 + Casting Shadows: false IsActive: true Scripts: ~ - EID: 5 @@ -97,4 +99,50 @@ Mesh: 141771688 Material: 124370424 IsActive: true + Scripts: ~ +- EID: 6 + Name: TrajectoryTest + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.39616156, y: 3.66783714, z: -0.722039163} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + RigidBody Component: + Type: Dynamic + Drag: 0.00999999978 + Angular Drag: 0.100000001 + Gravity Scale: 1 + Use Gravity: true + Interpolate: true + Sleeping Enabled: false + Freeze Position X: false + Freeze Position Y: false + Freeze Position Z: false + Freeze Rotation X: false + Freeze Rotation Y: false + Freeze Rotation Z: false + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Collision Tag: 0 + Type: Sphere + Radius: 1 + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0, z: 0} + Rotation Offset: {x: 0, y: 0, z: 0} + IsActive: true + Trajectory Renderer Component: + Mesh: 134305891 + Start Color: {x: 1, y: 0.951541781, z: 0} + Start Alpha: 1 + End Color: {x: 0, y: 1, z: 0.748898745} + End Alpha: 1 + "Color Eval Rate ": 0.192000002 + IsActive: true Scripts: ~ \ No newline at end of file diff --git a/Assets/Shaders/DeferredComposite_CS.glsl b/Assets/Shaders/DeferredComposite_CS.glsl index 18f53de4..e9f9eb0c 100644 --- a/Assets/Shaders/DeferredComposite_CS.glsl +++ b/Assets/Shaders/DeferredComposite_CS.glsl @@ -1,4 +1,5 @@ #version 450 +#extension GL_EXT_nonuniform_qualifier : require struct DirectionalLightStruct { @@ -63,8 +64,6 @@ float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV // Perform perspective division and convert to 0 to 1 range vec3 converted = (fragPosLightPOV.xyz / fragPosLightPOV.w) * vec3(0.5f) + vec3(0.5f); - // float sampledDepth = texture(shadowMap, converted.xy).r; - // float sampledDepth = texture(shadowMap, converted.xy).z; vec2 moments = texture(shadowMap, converted.xy).xy; if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f) @@ -121,18 +120,21 @@ void main() // light layer index uint lightLayer = lightLayerAndNormal.x; + // Normals are stored in 2 32-bit uints (only first 48 bits are used) where they can be unpacked in 3 floats so we unpack them here. vec3 worldNormal = vec3 (unpackHalf2x16 (lightLayerAndNormal.y).xy, unpackHalf2x16 (lightLayerAndNormal.z).x); vec3 fragColor = vec3 (0.0f); vec4 shadowMapColor = vec4 (1.0f); + // Shadow multiplier + float shadowValue = 1.0f; + for (int i = 0; i < lightCounts.ambientLights; ++i) { if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0) { // Just do some add - //fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f); fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength); } } @@ -153,12 +155,16 @@ void main() // If the shadow map is enabled (test the bit) if ((DirLightData.dLightData[i].shadowData & uint(1)) == 1) { - // calculate shadow map here - fragColor.rgb *= CalcShadowValue (shadowMaps[0], positionWorld, DirLightData.dLightData[i].pvMatrix, worldNormal, DirLightData.dLightData[i].directionWorld.xyz).xxx; + uint shadowMapIndex = (DirLightData.dLightData[i].shadowData >> 8); + shadowValue = min (shadowValue, CalcShadowValue (shadowMaps[nonuniformEXT(shadowMapIndex)], positionWorld, DirLightData.dLightData[i].pvMatrix, worldNormal, DirLightData.dLightData[i].directionWorld.xyz)); } } } + // calculate shadow map here + if (shadowValue != 0.0f) + fragColor.rgb *= shadowValue; + float ssaoVal = imageLoad (ssaoBlurredImage, globalThread).r; fragColor *= ssaoVal; @@ -167,12 +173,4 @@ void main() // store result into result image imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f)); - - // vec2 normTexCoords = vec2 (gl_GlobalInvocationID.xy) / vec2 (1024.0f); - // vec4 shadowMapVal = texture(shadowMaps[0], normTexCoords); - // if (normTexCoords.x > 1.0f || normTexCoords.y > 1.0f) - // shadowMapVal = vec4(0.0f); - - // imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), shadowMapVal.xxxx); - } \ No newline at end of file diff --git a/Assets/Shaders/DeferredComposite_CS.shshaderb b/Assets/Shaders/DeferredComposite_CS.shshaderb index 57401b13063ae5536870be4281bf45663baf213c..1ec2bcf0d56aa6c9634e82958dec3fd7f3f954af 100644 GIT binary patch literal 11569 zcmZ{o37lM2m4{!FUP1^<2umOk(?OCr1V~6&Vjv+TAw&}rYz%R2s=KQ@1=Uqeb#*61 zki>|hU<8fe!X~03pfez-qce^$Bg{TJ%;M~Em>HaX7105m?|XGm|6c0nT>5bS=YP&U z_uTEhSDC-~tSoQSrk>uNWmB>l*-_aqPHAzovZ*jxre2oxQ^&XLuO$5q^o(qJ*1K(c z--aDm^$nKC1{#&oX1&o@sSTEQS8BuAky%%sXXEDH&1a7_2hUz{-cm<6I-91-ea8^f z3GP5fN|l=YSCM1k(-5%H}nmRj`oc;Z>X00s+C%~Z?MuR4>T(i<;grLu2LJQjt>?CI>}V5uQTh; zW>UlEO0Bn99$h@NY*p(Iu9NzXKu?saIi3No)^~wBSdT2*SsC7m!k(F(hF({y4)pFU z4c2#UFIC6Oi^tAgwrXN%#j25^6)OPCbIId7vpMLoJa$WIH0QdrlhM2Cjp|_UXlbB) zS)(+(tv;6fI+s=5M+1!Y|f_2L4>&#A#nDvzgkf^TgO!QDI)8@SU)>i*> z;0NlpiE^V^9?WAqveoF3`bfFf9LvY($8MCHT}!lb6o?D+!U+Rx7HdvLXU z>spb{`OhXf*S|YEgq`pC=F$!2#@gE8mC-*%FF1U|wsbY?wNfPnyz5e}w}&naldR@#X83#&_+GhFe>R z?QJ&32b!&1`fMpzEI~fLKHX!@M!7cJ%n||Bmx~IeI z9Q5g)^nru_d2=(qeQxfBd`F%qze0ztpFZCKqZ3<7%|<1^-!VoPeCvG0oTq26C%%0? z#kJCJ8!W7fXZ501zXI#H-PwBhR&49CRQBYLH+)^$8}zlVJxkWwUim@z$#cKSH=emV zvymdtIrNS;;fl|xi8gyrn|))OeH-@JSgGz4)p`#k`_k%oqfs8*G*TK)&!n#GE`0U= zYuW4Vm+hFmk6qc_MLzYg-Us2ErN(f%*&;VmukT;qRlXavpGGf0+}E&s!0x}c&$psq zTfcj%|M@n*wtky_pJB!R+WMy?{|jw?ZT;4BIitjL<8*9WaQ2t;+y!UNa?=Z(dE|Vj zZzQYvVs1Vstj%23s@(&&nbW&$v%f7kX*s`Jf{U^FbeiO1>^X4eKZcH;`S~d(?tSF9 zJ~{gt@BJ^}u=Iq_FMSp9Nla`D6ne4xcLRn+;U5Et|QOqUMta0Y|JHX zTsL-cOy_FcUc~vVqz<_|5Oc*{Hpb@s<)-DhBfrzd`FqEE@S*a2-bek`Y<_M1Hgnan zpJYSyd9RF(+}g%QU++-SudUxX+26ZV^lR&PKKj3e?Y;7wZ8obt72U&Vjwe156nj6P zc=IZ9J^bG@D-K?LGGCiVC!X|&wXo-s_ZU3Jnb-BV$(@AlH@115r~c#6=9Zs>Jv-s> zdw%uH+y4Z#{hf#XPekjN@1g3G(E1(M-1av{Ig@yO3lUq`i*jr4niKG!3!b0bEx-11 z#PK5j!j^x{60$k&N<=QiIxoU@EZ5pPFGgFZ{PD2s(dIM%2E-P2FL+9_&EYra^5x6d zgr85qJa5!`D--A6gG?dThaqxV^eAe{@S}yAPGT6H0^*@ESrdZ#vfbA>4 z3ct3`?8x`aVDlO8`S>-oHR~@n$BRAvR&p3?PVJ`?7xr_>Hs^Q2|6fkWaeeJLdP%`psW#&SM_pn17ob#yW=f3yIVJBG{bfiL>$} z@WO&DAz~KxkC8=fVvhfXGly&J{;FR^Z1Y$Z-yh~Liv7CatyRCZY5P8ri#*e@W1o*m zKJ%E@ca3$q?veX6qJ3xRn+NvYpzV0G(B_tNJZ;|(a{5nA*qkx`0yzG1|LMu^c=K3) z-x0=ozhZpt*~zvRpWnt=i_d9o$6AGUTsdpe_E{aZT$Zr8qn0b-JPTpJ1KV1{-ihrq z(Q&T>`#f{3D%d9HSlT}KZPE97Y~NAF?*dzg^YEPAj_o+8!=CojV|56Ad2`bosI zsqORC->zXF2Y$9->;F!h{k?+i{X0~!Uj+Z4VB6o{iIHFXrGo8vFBfd%{9PFF-lJFA z>?O=K{O0r9JZ!b!<6*yu?RR+Cj_0>_*uH1{)(+czd)jQjwZpIWTRUv?`8}(=N_OFK@HY~N%7Xiq#E~l7M%)wVUqy`7x0;=F-{c&}XYez~)5$je z*AZj->F=HU4a6Avt=t0d&9@PG#pZaP7xQ}#^hf^R1V5K-^Zyo7%>Uci#>hwh-vP@j zw#e^1y)VCu7-I|W_rP+-2KW1kv$k!luJic=#Qw(XUxZk<=T)C|e;55n$n(jz?mtF~ zb^i&rG4fIOpMvETThwiS&%gf2|L0)eN!sTB3#6F;FR_i0kNkfHmRD@W{N5-1=KDVS z?~oUgZT`PUBERpse?W|px4uJYxwWkEi|Btu4j~&5bDoR-Cq&+O@27Ue{|opK;`1Zo z{}n7hlU=(A{cnghuSWDm-+u=mLh4BL{SUBw^!-n8^wk%8{9j;ww&4C7>{zzo{s$c6 zZ=)X1@edJW^_jr&u&i z|5UJkwex%&ej3;u-gDQu16$6u@x43)@!jqFI@adM#Qzd8>*+HS+kWytA&>UY;2q!b z#L@RCIQK5bpN;MKYq=kecRb>|+d1hgj(bA#KgYP%dLp*@VG6?~&IcF`m8!h_OC@&Pe_^M+>p#LSmdnaE_(lzK*>Z?77;PYIz;DoUw7{ zlIy09x_<#|-FwOBc{&qY&U($KPp)`Av*hy~7-#n^u({Qq-E+`O5u1IN zCBHhxJ{N3`IJ?Wia&dN7fIYjhSDu;ku;t_Io)5O4yk|uFY{c=cN9=g^y#QQ1yBA|S zew^LaV88Y9@zBMyy9Qf-oZU;n=97=JyA~`TXLlXgW?lL&MdYkY9P6+F9Ci48xeF)o|w0A9LIR_W2MoZ^1TBK4RVqF5a!TVapjCcT3KA@5mJu-s0>IS!)b%1y9Q-WW@ta_6@8mA@ZY1VnZhsHiZ#MBaB)|P8z}ot}7w-c5F4ngPtZmLy(KjKH z)B581VlD4Z{y392W6LQvReY=7h@pQazr|duz2MW(&e3^TlVckf_h=uOzw8XewY85m zy2ko^R>mHywb!BDbG7!;WUFJH-vf5t<2k+`EVlqLzdkwp`;0cTh6$sQO_s^Gw7x9l3x# za2<~*;28ycB-nF&6gt-THDKezo)5Oq{*=E5Y|MNlVithS753@iVxQMy8zX;f%Hwmu zT>55Gt+o4(WlH>eOY1q|9dyn=rAB?ldHTGuorE|~pRsciJ`R0y!pEaeN%%zc+yXuo z?EL4U{r4FAIksyS|2}h0!M+&0x?mgE-)0ZA**CS>``hdTZT7)7``$MDzBc>*WV`mh z8SKB*x7UEjm$+~NwjTj^EU2wi~5x*2H7k6|SSWdCIKc3OJqbtD17w_nK*z)nc zaz0ot#4~UL_63Of^~d+g>l42cy)VVB0?W%;vwI?E&BvhEAnv`kc`reX@%~+N!?)ZL*JnA1ZZ^zz>Sd(Yp zc*lskwt@9q*PGBb>yp0`k+Uvw)O8iux_XgVgExcaV-2>0uRuLTdVPo z5q0eV>$k4AqHWeC{}x2fy2Me}+raI0y&X4=XDS~7m43CWw2+>^Q150hQL0vB5oKQar)wS%ucX5 z^gG@FS}yjb0+x$?xfU#EP0p!`wmBz#*CBGwLF}AHk}V%=JqkV(sUtDg^y z#k(?wEg$>Q1lv#EdM3~|>(Muk$XSm#a_<5=e(_nf8(Thd-vE|#uAafjqmI4a19lwe zX1rrq$Bk&4br|z5;<>4!#+6q_-1|&*!^9K*k8Z<={rSV zDz_obNPy1ySzK4NbDIWZrAllS@Dh5jI7Kl%73xDD)h`l9v^fvtTp zqW^Zp+V`XN#h4!kx3AS5aPkpzC%ApBJ_08nHGC9oKY7PFfR>AM_%X0!hkaL@eK)p! z!vFDP$Gks*ZH)ZBv=*NPn@3-K*L(`>So*BP_qUw*KJ+~a-;Z8|tmJv@x;}u+M2t61 zzkLp(A3&n6PlMh6upa~)6YKsNaICwr`lH^5!1}$r5&v1R@n<0Vt;uow(fVSX&w=H< z`(n?$XFvAn3*h#Bd<0HD?%tzdImhrmeGzT*KIwZ5ku$g0u@)v<-uvnu)US?btKWtH E2O`qd?f?J) literal 11109 zcmZ{o37DN_b;rLXvjhlB2umOkXF!rz0wg3XF^~`v7@`vr3G zEHmOtAnlDRMoiIrMTMIV106^9MDNbdHl|-JDbB8{k5^Jt?Kxa z;pMA~Ke$fDKL9;dspt4WaJ{h;+`)XaY)5Tm2MT*mc0780r9QZIM`ft7b6cf8SzR)5 z`tsFN!z)*h4zFAZSdmK}-wvJZ@s~0vaBU>61xvwKT z7F}n&)|PFI*O@Jd*ozy@(Y(IS?6`>8P-_B->dM^0;UZIi-hFe?|1|i)#@JM~*{TlZ zu^rhO^k`$WI@X%V#~8qFR$G(JG3JxUbZ3L;yvAbO4UJZwmiSrO&G?GBbY{E3QAvE0r2ZrP!^l=Hy_j$feJga>aD>@%8DR zXf>;2Bdz={TbI0b)h5=Zr%EvodFvXStn=6z*;JXhF5jm^;mhL}yHWJfXRGA1h<)nH z<`#WQta~skI~l%M>)F{^V6L){w&^u3&rQE=dfn4Obq@M;Py4{Z|E{?i-#$0@LcSx< zlV6wp)=!_$^YN)ol~%Ks-{lyi3%)o@G3VLYD&pJcQ(i0mwxQChcrI5L{YtFkc4zD1 zi`e2~)NaflW%#-nj|PoHtloA>Toxbm~7-e!-t+08clChUocO2en5 zb={Ke^Xrq%W_4)eXk{clXS%Z6@ihjnWly(Vc*XP`>&osZ^QnjR-UHvNG)Jnfg6yMS z-z|SQ&$jus^;^$H zuCRf$6ALxXNy~Y@BF>uSW|uhg$oZb`BdhshZaxpJ&0N;1-3zvvGw#3rZNV8Y=eI_1 zG4>H9F2${mzxB!4&v@^7xjyY)d@*P5kS+RKi=4Dv)F&79x$hC@ zIL7sqICIM_%ejs`pL?xDKd~|AwQ=3p$hopm-I(IZT%7Ny(#;(^*ayydw-;OI*tXLaru2^)b$wH zy5#kL1Z_>RzJCF>ul#EK+CHZv-(P{vXT0a*@6gt)zuX)z_VnY)VXQf|pG;iXPbb@) zUjqNWoQ~uAemTV(YYy#a5*N15cboJ42HJT>P5%LQ9poMJn`r&!FE{705OK`^Ob%lm zL;Kmp>3ZB`6+l&NtO~Z7yD<(;x;kI&*9AB8oR&hUm~`Jtcvdp^Owbbo$&dZ zqpeNbcZgi%>Bf$Io}GN=F|Y3z>vG*A_whvgp3t`t?E665@eV_qTh8&ceJ9B2Uy!gl zWBgt?{&N2b$?tdzS%2RP#(KYEeC>J3wich+##xKcW^KoMDcW)6tVP@BbJTJ{!sd=z zw!nE7!oCXIT8@Jq1pEB*UYdUh+a_;*ZJ+P9=s$w(yU6%auwz@hXX|EcbEEca#yF0B zUYDH4I)=9I2%GlD(Y_OGVfzlSdA{!jyKd&RCh-GsJ{LWU-e=zta*A_1lZuUZ9c-SB z7hs%+V?2g_9PvDA`%LwBXV`~>pDNk)W_Lc1C!2ZsQeD?P@UfF)WWINsq zCEL5=Z@P%r_IF3v=JVS+Y_;FhVVloy=CFNt_{|)){rzSx+kP{Lt@fKaZ1eeDtbH!) z<(fZ%`24&H+h^xT6L$%#{0R836Nk!z`opN8~9LMMCCy*zT zZT#OO#thKkd-O@f82Qb-H@yp=LgW>j<9Qy;?>_5~{GSFtoow^}15(cakJ!e@NB+-% zBjtouvouOQDP+q%Ds zleX2IlSAh>nv&TlYpq9On@|2jsg|R_@}8BSvOe>{HtW)N zG$LnRV(W1Ij{$!S9d#Xx9d-E~a2yhK>9am#=c12K{w-%6oqsH9FRdARN!Q z7_SE$Tz00k)sKXGHrH#PO|1?0EJ)6I?#K=U_X2 zoZWN5ezQ5AzVg{!gRMW#?pm<<~*2FF~ycb6bB7kz&78tc7#Me@hJ+lnox*i_y-heNF|P!d@79&ra>hDWeR9ToS6&5J$NAZgE$2J#gRHyH;cKwv<$U%HfNh>1eHBE`^CONrhQZbm_KswGj}D`M z4cp%eagSX4>#(0fJFjcO+TH_yH;f@M4|9(o=AK7T#isHcn74_ce-*!JJQGvk-1^spVF1e0RBruTL@Z@olmjEN^p+o4|7BbiLjHmWwsG4eUJka8}&IH)6{f z7i%DAyx;h50^gBrYkD)dT+>^yjghzi?PxjsTl1Y@x!CKsg5?yO%DwjNcBA(|7{3A> zb9fuJeAIjw*gWzvue-s{E8dfD$CfiT<|P;N+6%rX*&m_bJHY;C+DsMqg5QbADK?ew zE!W^(82V%EcY_@}_T)X-a<<^!n>gv{fqGpGOqPHuKr(9&Dn^* zrQPE>h;24<7JJ}29#FyumheGf&)vc3Sl<_cjSssAY@gjJe=pdW9wcH;0Gli96T#&^ zFUB@T{*ILAB(S;k&7oRr_x-|@`1b?8dyqwlbN)3o>MPIFdv7}$ah^Ww<|lkO`j~`| zKp&g%QRoFFd>q*MFGTzA3-)tt*DU_M;k1%{E_hAJHg2HJ9&EF3ZnJl{*?ZdTy>0gW zZT16g_JhfG?R`csMVzm;ckUF#wYZyg*FF_7M&7&NeB~m38CWjv=yI@}Vsn2yqj5)9 zf{icV(KE2+;~9J=ST4jfa3uCwi23!$bNHo+UxkkQyBaJnXU*=3oHZYcUW>T*+U7kE zF~<9Q4tgDOUJ_J3hb!>89_J(WH^zB+=Az$vuztnn+#TODpfA?oLa^ic?Pm?1xw+; zsOxgDV_U27juCZT0oHF_SE6m!CI3o9&bq`=*Q>zobzKD~AM15BST5Ep@~ES(SA!kf zT8(!M>$nDOvkqgnBiA6-A@a=zIf$LpXtL#Ft;fM9BMl_R zdJR}UVwzy@Px-D)V9UpTw7~Y0x1K4q&3g1rB68Lvj@&!Jj$eKjU5_mvxo-f=IakkM z*m*MZyD;TAagh}i{hUx!=a%s2t zGQ|G+-A~^s`XbjGa(@52cN?61#Jn-Zl-K=sIQfXV<9Eco2~OVUa~Jx}i2dZ_o8T>A z$I}Is6XAfE~&f&da z#}4})ZT35{?GyfYB|GN*Zfs-ZZ%u3Q9iR>l`ycinfsKiE|6_2hyRrJC-ai5B_wGjgpMs4)3DIv& zjyr(X7vuaHSkAjI_RM?sV~;)nZr{fb!pXpF}zP7M%%nk`W{B)%q@1TMah=; PzIq4stK-?~cj0dVKJ1B) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp index a15687cb..91ec0cea 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp @@ -186,7 +186,7 @@ namespace SHADE .flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount, }; - // For global data (generic data and textures) + // For global data (generic data and textures). NOT USED. Handle shadowMapDescLayout = logicalDevice->CreateDescriptorSetLayout({ shadowMapBinding }); SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, shadowMapDescLayout->GetVkHandle(), "[Descriptor Set Layout] Shadow Maps"); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index bf2f1ec2..397edf74 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -942,7 +942,8 @@ namespace SHADE else { // get the shadow map node - renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName)->SetDynamicActive(false); + if (auto node = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName)) + node->SetDynamicActive(false); } return eventPtr->handle; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp index f8578647..de930596 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp @@ -120,21 +120,17 @@ namespace SHADE { lightData.castShadows = flag; - // If the flag is true - if (flag) - { - // Create new event and broadcast it - SHLightShadowEvent newEvent; - newEvent.lightEntity = GetEID(); + // Create new event and broadcast it + SHLightShadowEvent newEvent; + newEvent.lightEntity = GetEID(); - // If shadow map index is invalid, that means light is enabling shadow for the first time. - newEvent.firstEnable = (lightData.shadowMapIndex == SHLightData::INVALID_SHADOW_MAP_INDEX); + // If shadow map index is invalid, that means light is enabling shadow for the first time. + newEvent.firstEnable = (lightData.shadowMapIndex == SHLightData::INVALID_SHADOW_MAP_INDEX); - // pass the flag to the event - newEvent.enableShadow = flag; + // pass the flag to the event + newEvent.enableShadow = flag; - SHEventManager::BroadcastEvent(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT); - } + SHEventManager::BroadcastEvent(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index 27685d69..a2b9cc0a 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -526,7 +526,7 @@ namespace SHADE if (auto renderer = light.GetRenderer()) { //SHMatrix orthoMatrix = SHMatrix::OrthographicRH() - renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(15.0f, 15.0f, 1.0f, 80.0f)); + renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(20.0f, 20.0f, 1.0f, 80.0f)); } auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type); @@ -636,7 +636,7 @@ namespace SHADE shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal); // Add to container of shadow maps - shadowMapIndexing.emplace(lightEntity, static_cast (shadowMaps.size())); + shadowMapIndexing.emplace(lightEntity, static_cast (shadowMaps.size() - 1u)); usedIndex = static_cast(shadowMapImageSamplers.size()) - 1u; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h index f3744d83..fd3d8b02 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h @@ -35,6 +35,9 @@ namespace SHADE //! evolving rate of the color float colorEvolveRate; + //! Entity to simulate trajectory of + //EntityID + public: /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ @@ -61,6 +64,7 @@ namespace SHADE void ClearPositions(void) noexcept; bool HasPositions(void) const noexcept; + void SimulateTrajectory (EntityID eid) noexcept; RTTR_ENABLE() diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp index cbf593d4..3ff7c1ec 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp @@ -11,6 +11,8 @@ #include "Graphics/RenderGraph/SHSubpass.h" #include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h" #include "Graphics/MiddleEnd/Interface/SHRenderer.h" +#include "Physics/System/SHPhysicsSystem.h" +#include "ECS_Base/Managers/SHSystemManager.h" namespace SHADE { @@ -74,6 +76,8 @@ namespace SHADE void SHTrajectoryRenderingSubSystem::Run(uint32_t frameIndex) noexcept { + auto* physicsSystem = SHSystemManager::GetSystem(); + auto& comps = SHComponentManager::GetDense(); for (auto& comp : comps) { @@ -86,7 +90,21 @@ namespace SHADE // x += 0.5f; //} - //comp.SetPositions (test); + std::vector positions{}; + std::vector quats{}; + physicsSystem->SimulateBody + (positions, quats, + SHPhysicsSystem::SimulateBodyInfo + { + .bodyEID = comp.GetEID(), + .force = SHVec3 {30.0f, 100.0f, 30.0f}, + .continuousForce = false, + .timeStep = 0.1f, + .maxSteps = 100, + } + ); + + comp.SetPositions(positions); // If has positions, feed data to buffer. if (comp.HasPositions()) { diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index d1c37e3a..166b3c6e 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -194,9 +194,9 @@ namespace SHADE // In reality, the check for variable descriptor sets do not exists in spirv-reflect. Fortunately, when a shader // defines a boundless descriptor binding in the shader, the information reflected makes the array dimensions - // contain a 1 element of value 1. Knowing that having an array [1] doesn't make sense, we can use this to + // contain a 1 element of value 0. Knowing that having an array [1] doesn't make sense, we can use this to // signify a variable sized binding. - if (reflectedBinding->array.dims[0] == 1) + if (reflectedBinding->array.dims_count == 1 && reflectedBinding->array.dims[0] == 0) { // variable binding has to be the last in the set if (i == set->binding_count - 1) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp index ef1b6b03..72176f4e 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -118,7 +118,7 @@ namespace SHADE if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1) { Handle computeResourceLayout = {}; - computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)]; + computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)]; // create compute resources computeResource = graphStorage->resourceHub->Create(); From 8670fe5fa97a3d27d035491a3a0a3bf299cceedf Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 8 Mar 2023 22:03:08 +0800 Subject: [PATCH 40/69] Added text RawAnimInspector for when no animations are selected --- .../EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index 1c9dc61d..f587a554 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -198,6 +198,10 @@ namespace SHADE ImGui::Unindent(); } } + else + { + SHEditorUI::CenteredText("Double click on a model file to inspect its animations here."); + } } ImGui::End(); } From 2692db1ed3109ceb0448c96b3a65e15a1e02405a Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 9 Mar 2023 01:49:43 +0800 Subject: [PATCH 41/69] Changed function to return pointer type instead of std::optional --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 16 +++++++++++++--- SHADE_Engine/src/Assets/SHAssetManager.h | 3 ++- SHADE_Engine/src/Editor/SHEditorUI.cpp | 8 ++++---- SHADE_Engine/src/Resource/SHResourceManager.cpp | 4 ++-- SHADE_Engine/src/Resource/SHResourceManager.hpp | 4 ++-- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 3dfe91a7..660fe6d9 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -164,14 +164,24 @@ namespace SHADE return AssetType::INVALID; } - std::optional SHAssetManager::GetAsset(AssetID id) noexcept + SHAsset* SHAssetManager::GetAsset(AssetID id) noexcept { if (assetCollection.contains(id)) { - return assetCollection[id]; + return &assetCollection[id]; } - return {}; + return nullptr; + } + + SHAsset const* SHAssetManager::GetAssetConst(AssetID id) noexcept + { + if (assetCollection.contains(id)) + { + return &assetCollection[id]; + } + + return nullptr; } AssetID SHAssetManager::GetAssetIDFromPath(AssetPath const& path) noexcept diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 6a8f91ef..d8a48afd 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -50,7 +50,8 @@ namespace SHADE * \return const& to unordered_map ****************************************************************************/ static std::vector GetAllAssets() noexcept; - static std::optional GetAsset(AssetID id) noexcept; + static SHAsset* GetAsset(AssetID id) noexcept; + static SHAsset const* GetAssetConst(AssetID id) noexcept; static AssetType GetType(AssetID id) noexcept; diff --git a/SHADE_Engine/src/Editor/SHEditorUI.cpp b/SHADE_Engine/src/Editor/SHEditorUI.cpp index 3f5fdaaa..212a87ae 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.cpp +++ b/SHADE_Engine/src/Editor/SHEditorUI.cpp @@ -378,9 +378,9 @@ namespace SHADE // Attempt to get the asset's data for rendering editor auto asset = SHAssetManager::GetAsset(value); std::string assetName; - if (asset.has_value()) + if (asset) { - assetName = asset.value().name; + assetName = asset->name; } // Editor @@ -391,9 +391,9 @@ namespace SHADE { // Check if type matches auto draggedAsset = SHAssetManager::GetAsset(*payload); - if (draggedAsset.has_value() && draggedAsset.value().type == type) + if (draggedAsset && draggedAsset->type == type) { - value = draggedAsset.value().id; + value = draggedAsset->id; changed = true; } SHDragDrop::EndTarget(); diff --git a/SHADE_Engine/src/Resource/SHResourceManager.cpp b/SHADE_Engine/src/Resource/SHResourceManager.cpp index 9ddb8814..1875ee46 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.cpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.cpp @@ -127,8 +127,8 @@ namespace SHADE if (assetId.has_value()) { const auto ASSET_INFO = SHAssetManager::GetAsset(assetId.value()); - if (ASSET_INFO.has_value()) - return ASSET_INFO.value().name; + if (ASSET_INFO) + return ASSET_INFO->name; } return {}; } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index a405b298..85f5fd33 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -162,8 +162,8 @@ namespace SHADE if (assetId.has_value()) { const auto ASSET_INFO = SHAssetManager::GetAsset(assetId.value()); - if (ASSET_INFO.has_value()) - return ASSET_INFO.value().name; + if (ASSET_INFO) + return ASSET_INFO->name; } return {}; } From 7df989759821f3911beb19b3e5ac9cbd5571081b Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 9 Mar 2023 01:50:26 +0800 Subject: [PATCH 42/69] Fixed bug in binary loader where result from load was always nullptr, changed pointer to pointer reference --- SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp | 4 +++- SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp index ad2a7f2c..c1e73540 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp @@ -84,7 +84,7 @@ namespace SHADE } } - void SHBinaryLoader::LoadAnimClipContainer(std::ifstream& file, SHAssetData* result, AssetPath path) + void SHBinaryLoader::LoadAnimClipContainer(std::ifstream& file, SHAssetData*& result, AssetPath path) { auto const data = new SHAnimClipContainerAsset(); @@ -120,5 +120,7 @@ namespace SHADE sizeof(uint32_t) * 2 ); } + + result = data; } } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h index 7cf50d51..5689901d 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.h @@ -12,6 +12,6 @@ namespace SHADE 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); + void LoadAnimClipContainer(std::ifstream& file,SHAssetData*& result, AssetPath path); }; } \ No newline at end of file From 2c8eca4125ce2332fbe406dd75c39fd262b5148b Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 9 Mar 2023 01:51:54 +0800 Subject: [PATCH 43/69] 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); }; } From e3a552f983340890ab5f6e73c10f18be5a464ea1 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 9 Mar 2023 10:45:57 +0800 Subject: [PATCH 44/69] Wrote scripting interface for trajectory rendering --- .../SHTrajectoryRenderableComponent.cpp | 35 ++-- .../SHTrajectoryRenderableComponent.h | 41 +++-- .../SHTrajectoryRenderingSubSystem.cpp | 151 ++++++++---------- .../src/Components/TrajectoryRenderable.cxx | 5 + .../src/Components/TrajectoryRenderable.hxx | 3 + 5 files changed, 128 insertions(+), 107 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.cpp index 91c11e60..41678935 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.cpp @@ -22,19 +22,32 @@ namespace SHADE } - void SHTrajectoryRenderableComponent::ClearPositions(void) noexcept + void SHTrajectoryRenderableComponent::SimulateTrajectory(EntityID eid, SHVec3 force, float timestep, uint32_t maxSteps) noexcept { - positions.clear(); + entityToSimulate = eid; + simulationForce = force; + simulationTimestep = timestep; + simulationMaxSteps = maxSteps; } - bool SHTrajectoryRenderableComponent::HasPositions(void) const noexcept + float SHTrajectoryRenderableComponent::GetSimulationTimestep(void) const noexcept { - return !positions.empty(); + return simulationTimestep; } - std::vector SHTrajectoryRenderableComponent::GetPositions(void) const noexcept + void SHTrajectoryRenderableComponent::ResetSimulationInfo(void) noexcept { - return positions; + entityToSimulate = MAX_EID; + } + + uint32_t SHTrajectoryRenderableComponent::GetSimulationMaxSteps(void) const noexcept + { + return simulationMaxSteps; + } + + SHVec3 SHTrajectoryRenderableComponent::GetSimulationForce(void) const noexcept + { + return simulationForce; } Handle SHTrajectoryRenderableComponent::GetMesh(void) const noexcept @@ -67,16 +80,16 @@ namespace SHADE return colorEvolveRate; } + EntityID SHTrajectoryRenderableComponent::GetEntityToSimulate(void) const noexcept + { + return entityToSimulate; + } + void SHTrajectoryRenderableComponent::SetMesh(Handle newMesh) noexcept { mesh = newMesh; } - void SHTrajectoryRenderableComponent::SetPositions(std::vector const& inPositions) noexcept - { - positions = inPositions; - } - void SHTrajectoryRenderableComponent::SetStartColor(SHVec3 color) noexcept { startColor = color; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h index fd3d8b02..95d40af1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h @@ -17,9 +17,6 @@ namespace SHADE //! Mesh used to render the trajectory Handle mesh; - //! positions to plot for rendering. Will be cleared every frame. - std::vector positions; - //! Starting color of the trajectory SHVec3 startColor; @@ -35,36 +32,48 @@ namespace SHADE //! evolving rate of the color float colorEvolveRate; + //! Used for the trajectory simulation. Indicates the time to pass before + //! plotting a point in the simulation + float simulationTimestep; + //! Entity to simulate trajectory of - //EntityID + EntityID entityToSimulate; + + //! Force to use during simulation of + SHVec3 simulationForce; + + //! max points to be plotted in the simulation before stopping. + //! Note that the plotting might still be halted if the simulation + //! detects a raycast hit with a collider. + uint32_t simulationMaxSteps; public: /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void SetMesh(Handle newMesh) noexcept; - void SetPositions (std::vector const& inPositions) noexcept; void SetStartColor(SHVec3 startColor) noexcept; void SetEndColor (SHVec3 endColor) noexcept; void SetStartAlpha(float a) noexcept; void SetEndAlpha (float a) noexcept; void SetColorEvolveRate(float rate) noexcept; - std::vector GetPositions (void) const noexcept; - Handle GetMesh (void) const noexcept; - SHVec3 const& GetStartColor (void) const noexcept; - SHVec3 const& GetEndColor (void) const noexcept; - float GetStartAlpha (void) const noexcept; - float GetEndAlpha (void) const noexcept; - float GetColorEvolveRate (void) const noexcept; + Handle GetMesh (void) const noexcept; + SHVec3 const& GetStartColor (void) const noexcept; + SHVec3 const& GetEndColor (void) const noexcept; + float GetStartAlpha (void) const noexcept; + float GetEndAlpha (void) const noexcept; + float GetColorEvolveRate (void) const noexcept; + EntityID GetEntityToSimulate (void) const noexcept; + SHVec3 GetSimulationForce (void) const noexcept; + uint32_t GetSimulationMaxSteps (void) const noexcept; + float GetSimulationTimestep (void) const noexcept; + void ResetSimulationInfo (void) noexcept; void OnCreate(void) override final; void OnDestroy(void) override final; - void ClearPositions(void) noexcept; - bool HasPositions(void) const noexcept; - - void SimulateTrajectory (EntityID eid) noexcept; + void SimulateTrajectory (EntityID eid, SHVec3 force, float timestep, uint32_t maxSteps) noexcept; RTTR_ENABLE() diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp index 3ff7c1ec..f923add4 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp @@ -81,94 +81,85 @@ namespace SHADE auto& comps = SHComponentManager::GetDense(); for (auto& comp : comps) { - //std::vector test{}; - //test.resize(10); - //float x = 0.0f; - //for (auto& vec : test) - //{ - // vec = SHVec3(x, 5.0f, 0.0f); - // x += 0.5f; - //} - - std::vector positions{}; - std::vector quats{}; - physicsSystem->SimulateBody - (positions, quats, - SHPhysicsSystem::SimulateBodyInfo - { - .bodyEID = comp.GetEID(), - .force = SHVec3 {30.0f, 100.0f, 30.0f}, - .continuousForce = false, - .timeStep = 0.1f, - .maxSteps = 100, - } - ); - - comp.SetPositions(positions); - // If has positions, feed data to buffer. - if (comp.HasPositions()) + if (EntityID entityToSimulate = comp.GetEntityToSimulate(); entityToSimulate != MAX_EID) { - auto meshHandle = comp.GetMesh(); - - // dont do anything if no mesh - if (!meshHandle) - continue; - - SHTransformComponent* transform = SHComponentManager::GetComponent_s(comp.GetEID()); - if (transform) - { - // convenient variable - SHVec3 const& startColor = comp.GetStartColor(); - SHVec3 const& endColor = comp.GetEndColor(); - float colorEvolveRate = comp.GetColorEvolveRate(); - - // trs to be reused - SHMatrix trs = transform->GetTRS(); - - // starting color of trajectory - SHVec4 currentColor = comp.GetStartColor(); - - // Start from 0 and slowly evolve to 1 - float lerpValue = 0.0f; - - // Will be used for baseInstance later - uint32_t oldTransformDataSize = transformData.size(); - - - auto const& positions = comp.GetPositions(); - for (auto& pos : positions) + std::vector positions{}; + std::vector quats{}; + physicsSystem->SimulateBody + (positions, quats, + SHPhysicsSystem::SimulateBodyInfo { - // modify position and reuse matrix - trs.m[3][0] = pos.x; - trs.m[3][1] = pos.y; - trs.m[3][2] = pos.z; - - transformData.push_back(trs); - colorData.push_back(currentColor); - - // evolve lerp value and clamp to 1 - lerpValue = std::min (1.0f, lerpValue + colorEvolveRate); - - // evolve color - currentColor = SHVec3::Lerp(startColor, endColor, lerpValue); - currentColor.w = SHMath::Lerp (comp.GetStartAlpha(), comp.GetEndAlpha(), lerpValue); - + .bodyEID = entityToSimulate, + .force = comp.GetSimulationForce(), + .continuousForce = false, + .timeStep = comp.GetSimulationTimestep(), + .maxSteps = static_cast(comp.GetSimulationMaxSteps()), } + ); - // add draw data for this trajectory - drawData.push_back(vk::DrawIndexedIndirectCommand + comp.ResetSimulationInfo(); + + // If has positions, feed data to buffer. + if (!positions.empty()) + { + auto meshHandle = comp.GetMesh(); + + // dont do anything if no mesh + if (!meshHandle) + continue; + + SHTransformComponent* transform = SHComponentManager::GetComponent_s(comp.GetEID()); + if (transform) + { + // convenient variable + SHVec3 const& startColor = comp.GetStartColor(); + SHVec3 const& endColor = comp.GetEndColor(); + float colorEvolveRate = comp.GetColorEvolveRate(); + + // trs to be reused + SHMatrix trs = transform->GetTRS(); + + // starting color of trajectory + SHVec4 currentColor = comp.GetStartColor(); + + // Start from 0 and slowly evolve to 1 + float lerpValue = 0.0f; + + // Will be used for baseInstance later + uint32_t oldTransformDataSize = transformData.size(); + + for (auto& pos : positions) { - .indexCount = meshHandle->IndexCount, - .instanceCount = static_cast(transformData.size()) - oldTransformDataSize, - .firstIndex = meshHandle->FirstIndex, - .vertexOffset = meshHandle->FirstVertex, - .firstInstance = oldTransformDataSize - }); + // modify position and reuse matrix + trs.m[3][0] = pos.x; + trs.m[3][1] = pos.y; + trs.m[3][2] = pos.z; + + transformData.push_back(trs); + colorData.push_back(currentColor); + + // evolve lerp value and clamp to 1 + lerpValue = std::min(1.0f, lerpValue + colorEvolveRate); + + // evolve color + currentColor = SHVec3::Lerp(startColor, endColor, lerpValue); + currentColor.w = SHMath::Lerp(comp.GetStartAlpha(), comp.GetEndAlpha(), lerpValue); + + } + + // add draw data for this trajectory + drawData.push_back(vk::DrawIndexedIndirectCommand + { + .indexCount = meshHandle->IndexCount, + .instanceCount = static_cast(transformData.size()) - oldTransformDataSize, + .firstIndex = meshHandle->FirstIndex, + .vertexOffset = meshHandle->FirstVertex, + .firstInstance = oldTransformDataSize + }); + } } } - // clear at the end of every frame since data is already in buffers - comp.ClearPositions(); } if (!transformData.empty()) diff --git a/SHADE_Managed/src/Components/TrajectoryRenderable.cxx b/SHADE_Managed/src/Components/TrajectoryRenderable.cxx index 4b762338..9eace4ab 100644 --- a/SHADE_Managed/src/Components/TrajectoryRenderable.cxx +++ b/SHADE_Managed/src/Components/TrajectoryRenderable.cxx @@ -13,6 +13,11 @@ namespace SHADE } + void TrajectoryRenderable::SimulateTrajectory(EntityID eid, Vector3 force, float timestep, uint32_t maxSteps) + { + GetNativeComponent()->SimulateTrajectory(eid, Convert::ToNative(force), timestep, maxSteps); + } + MeshAsset TrajectoryRenderable::Mesh::get() { auto mesh = GetNativeComponent()->GetMesh(); diff --git a/SHADE_Managed/src/Components/TrajectoryRenderable.hxx b/SHADE_Managed/src/Components/TrajectoryRenderable.hxx index 37a350ad..78e3c0f1 100644 --- a/SHADE_Managed/src/Components/TrajectoryRenderable.hxx +++ b/SHADE_Managed/src/Components/TrajectoryRenderable.hxx @@ -82,6 +82,9 @@ namespace SHADE float get(); void set(float val); } + + void SimulateTrajectory(EntityID eid, Vector3 force, float timestep, uint32_t maxSteps); + }; } From e816df28a8ee9b18b2b44425dca19b4e75da65e2 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 9 Mar 2023 12:07:07 +0800 Subject: [PATCH 45/69] Clips can now be dragged and dropped into the animation controller editor --- .../Animation/SHAnimationControllerEditor.cpp | 39 +++++++++++++++---- .../SHRawAnimInspector.cpp | 1 - SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 6 ++- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp index a67c6a67..17b252f9 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Animation/SHAnimationControllerEditor.cpp @@ -25,11 +25,14 @@ of DigiPen Institute of Technology is prohibited. #include "Editor/SHEditorWidgets.hpp" #include "Editor/Command/SHCommand.hpp" #include "Input/SHInputManager.h" +#include "Resource/SHResourceManager.h" +#include "Editor/EditorWindow/SHEditorWindowManager.h" +#include "Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h" namespace SHADE { /*-----------------------------------------------------------------------------------*/ - /* Cosntructors/Destructors */ + /* Constructors/Destructors */ /*-----------------------------------------------------------------------------------*/ SHAnimationControllerEditor::SHAnimationControllerEditor() : SHEditorWindow("Animation Controller Editor", ImGuiWindowFlags_MenuBar) @@ -318,6 +321,7 @@ namespace SHADE void SHAnimationControllerEditor::drawNodeEditor() { static constexpr float NODE_WIDTH = 80.0f; + static constexpr float TEXT_FIELD_PADDING = 15.0f; ImNodes::BeginNodeEditor(); { @@ -346,8 +350,8 @@ namespace SHADE node.EditingName = false; } ImGui::SameLine(); - static constexpr float TEXT_FIELD_PADDING = 15.0f; ImGui::SetNextItemWidth(std::max(ImGui::CalcTextSize(node.Name.c_str()).x + TEXT_FIELD_PADDING, NODE_WIDTH)); + SHEditorUI::InputTextField("", node.Name); } else @@ -363,11 +367,32 @@ namespace SHADE ImNodes::EndNodeTitleBar(); // Body - ImGui::Text("Clip"); - ImGui::SameLine(); - std::array buffer = { '\0' }; - ImGui::SetNextItemWidth(std::max(NODE_WIDTH, ImGui::CalcTextSize(buffer.data()).x)); - ImGui::InputText("", buffer.data(), buffer.size()); + const auto CLIP_NAME = SHResourceManager::GetAssetName(node.Clip).value_or(""); + ImGui::SetNextItemWidth(NODE_WIDTH); + SHEditorWidgets::DragDropReadOnlyField + ( + "Clip", CLIP_NAME, + [&]() + { + return SHResourceManager::GetAssetID(node.Clip).value_or(0); + }, + [&](AssetID id) + { + if (SHAssetManager::GetType(id) != AssetType::ANIM_CLIP) + return; + node.Clip = SHResourceManager::LoadOrGet(id); + SHResourceManager::FinaliseChanges(); + }, + SHDragDrop::DRAG_RESOURCE, {}, NODE_WIDTH + ); + if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) + { + if (node.Clip) + { + AssetID assetID = SHResourceManager::GetAssetID(node.Clip).value_or(0); + SHEditorWindowManager::GetEditorWindow()->SetScrollTo(assetID); + } + } // Input Nodes for (auto inputAttrib : node.InputAttribs) diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index 75ab7945..0391f75d 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -5,7 +5,6 @@ \date Mar 1, 2023 \brief Contains the definition of SHRawAnimInspector's functions. - 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. diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 2698e3f2..124bbfb3 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -418,12 +418,16 @@ namespace SHADE } template - static bool DragDropReadOnlyField(std::string const& label, std::string_view const& fieldVTextValue, std::function const& get, std::function const& set, SHDragDrop::DragDropTag const& dragDropTag, std::string_view const& tooltip = {}) + static bool DragDropReadOnlyField(std::string const& label, std::string_view const& fieldVTextValue, std::function const& get, std::function const& set, SHDragDrop::DragDropTag const& dragDropTag, std::string_view const& tooltip = {}, float customWidth = -1.0f) { std::string text = fieldVTextValue.data(); ImGui::BeginGroup(); ImGui::PushID(label.data()); TextLabel(label); + if (customWidth > 0.0f) + { + ImGui::SetNextItemWidth(customWidth); + } bool changed = ImGui::InputText("##inputText", &text, ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_AutoSelectAll, nullptr, nullptr); if(SHDragDrop::BeginTarget()) { From fc789334bdcfa5e53300349f708c11028d901957 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 9 Mar 2023 13:10:06 +0800 Subject: [PATCH 46/69] Fixed animation assets fields for scripts not supporting the correct types --- SHADE_Managed/src/Editor/Editor.h++ | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SHADE_Managed/src/Editor/Editor.h++ b/SHADE_Managed/src/Editor/Editor.h++ index f6b0f06d..59d1f7d9 100644 --- a/SHADE_Managed/src/Editor/Editor.h++ +++ b/SHADE_Managed/src/Editor/Editor.h++ @@ -246,7 +246,7 @@ namespace SHADE bool Editor::renderFieldEditorInternal(const std::string& fieldName, interior_ptr managedValPtr, EditorFieldFunc, bool* isHovered, RangeAttribute^) { uint32_t assetId = managedValPtr->NativeAssetID; - if (SHEditorUI::InputAssetField(fieldName, assetId, AssetType::FONT, isHovered)) + if (SHEditorUI::InputAssetField(fieldName, assetId, AssetType::ANIM_CLIP, isHovered)) { *managedValPtr = AnimationClipAsset(assetId); return true; @@ -258,7 +258,7 @@ namespace SHADE bool Editor::renderFieldEditorInternal(const std::string& fieldName, interior_ptr managedValPtr, EditorFieldFunc, bool* isHovered, RangeAttribute^) { uint32_t assetId = managedValPtr->NativeAssetID; - if (SHEditorUI::InputAssetField(fieldName, assetId, AssetType::MESH, isHovered)) + if (SHEditorUI::InputAssetField(fieldName, assetId, AssetType::ANIM_CONTROLLER, isHovered)) { *managedValPtr = AnimationControllerAsset(assetId); return true; @@ -270,7 +270,7 @@ namespace SHADE bool Editor::renderFieldEditorInternal(const std::string& fieldName, interior_ptr managedValPtr, EditorFieldFunc, bool* isHovered, RangeAttribute^) { uint32_t assetId = managedValPtr->NativeAssetID; - if (SHEditorUI::InputAssetField(fieldName, assetId, AssetType::MATERIAL, isHovered)) + if (SHEditorUI::InputAssetField(fieldName, assetId, AssetType::MODEL, isHovered)) { *managedValPtr = AnimationRigAsset(assetId); return true; From 07a2eb2f64ced6ee21a59eba79d6071e4157cfed Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 9 Mar 2023 13:18:09 +0800 Subject: [PATCH 47/69] Fixed not opening the correct Visual Studio version for scripts --- SHADE_Engine/src/Scripting/SHVSUtilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Scripting/SHVSUtilities.cpp b/SHADE_Engine/src/Scripting/SHVSUtilities.cpp index 17435d6f..d34e0211 100644 --- a/SHADE_Engine/src/Scripting/SHVSUtilities.cpp +++ b/SHADE_Engine/src/Scripting/SHVSUtilities.cpp @@ -115,7 +115,7 @@ namespace SHADE #else static constexpr int EXCESS_CHARS_COUNT = 2; - const auto RESULT = SHExecUtilties::ExecBlockingPowerShellCommand(L"./vswhere -version \"[15.0,19.0]\" -requires Microsoft.NetCore.Component.DevelopmentTools -find Common7\\\\IDE\\\\devenv.exe | Select-Object -first 1", true, true); + const auto RESULT = SHExecUtilties::ExecBlockingPowerShellCommand(L"./vswhere -version \"[15.0,21.0]\" -requires Microsoft.NetCore.Component.DevelopmentTools -find Common7\\\\IDE\\\\devenv.exe | Select-Object -last 1", true, true); if (RESULT.StdOutput.size() < EXCESS_CHARS_COUNT) { SHLOG_ERROR("[SHVSUtilities] Unable to get path to Visual Studio installation. SHVSUtilities will not work."); From 5669babc0fba32fa781608c3bc3a64d4f6a3ccc8 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 9 Mar 2023 13:35:49 +0800 Subject: [PATCH 48/69] Fixed animator components in scripts not being retrievable. Also added script for testing animations --- Assets/Scenes/anim.shade | 29 +++++++++++++++++++--- Assets/Scripts/AnimTest.cs | 41 +++++++++++++++++++++++++++++++ Assets/Scripts/AnimTest.cs.shmeta | 3 +++ SHADE_Managed/src/Engine/ECS.cxx | 5 +++- 4 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 Assets/Scripts/AnimTest.cs create mode 100644 Assets/Scripts/AnimTest.cs.shmeta diff --git a/Assets/Scenes/anim.shade b/Assets/Scenes/anim.shade index aa42fc11..c553b17d 100644 --- a/Assets/Scenes/anim.shade +++ b/Assets/Scenes/anim.shade @@ -10,6 +10,7 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 Strength: 1 + Casting Shadows: false IsActive: true Scripts: ~ - EID: 2 @@ -23,11 +24,33 @@ Scale: {x: 1, y: 1, z: 1} IsActive: true Renderable Component: - Mesh: 148542784 - Material: 121518381 + Mesh: 149697411 + Material: 128805346 IsActive: true Animator Component: Rig: 76586906 - Clip: 76586906 + AnimationController: 0 + IsActive: true + Scripts: + - Type: SHADE.Test.AnimTest + Enabled: true + idleClip: 227450439 + runClip: 229125027 + pickUpClip: 219605278 +- EID: 1 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Camera Component: + Position: {x: 0, y: 0.5, z: 0.699999988} + Pitch: 0 + Yaw: 0 + Roll: 0 + Width: 1920 + Near: 0.00999999978 + Far: 10000 + Perspective: true + FOV: 90 IsActive: true Scripts: ~ \ No newline at end of file diff --git a/Assets/Scripts/AnimTest.cs b/Assets/Scripts/AnimTest.cs new file mode 100644 index 00000000..376fb372 --- /dev/null +++ b/Assets/Scripts/AnimTest.cs @@ -0,0 +1,41 @@ +namespace SHADE.Test +{ + public class AnimTest : Script + { + #region Serialized Fields + [SerializeField] + private AnimationClipAsset idleClip; + [SerializeField] + private AnimationClipAsset runClip; + [SerializeField] + private AnimationClipAsset pickUpClip; + #endregion + + #region Components + public Animator Animator { get; private set; } + #endregion + + #region Lifecycle Functions + protected override void awake() + { + Animator = GetComponent(); + } + + protected override void update() + { + if (Input.GetKeyUp(Input.KeyCode.Alpha1)) + { + Animator.Play(idleClip); + } + else if (Input.GetKeyUp(Input.KeyCode.Alpha2)) + { + Animator.Play(runClip); + } + else if (Input.GetKeyUp(Input.KeyCode.Alpha3)) + { + Animator.Play(pickUpClip); + } + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/Scripts/AnimTest.cs.shmeta b/Assets/Scripts/AnimTest.cs.shmeta new file mode 100644 index 00000000..45df5a57 --- /dev/null +++ b/Assets/Scripts/AnimTest.cs.shmeta @@ -0,0 +1,3 @@ +Name: AnimTest +ID: 165676130 +Type: 9 diff --git a/SHADE_Managed/src/Engine/ECS.cxx b/SHADE_Managed/src/Engine/ECS.cxx index 5b73b64e..c79175bf 100644 --- a/SHADE_Managed/src/Engine/ECS.cxx +++ b/SHADE_Managed/src/Engine/ECS.cxx @@ -32,6 +32,8 @@ of DigiPen Institute of Technology is prohibited. #include "UI\SHUIComponent.h" #include "UI\SHSliderComponent.h" #include "UI\SHCanvasComponent.h" +#include "Animation\SHAnimatorComponent.h" +#include "Graphics\MiddleEnd\TrajectoryRendering\SHTrajectoryRenderableComponent.h" // Project Headers #include "Utility/Convert.hxx" #include "Utility/Debug.hxx" @@ -47,7 +49,7 @@ of DigiPen Institute of Technology is prohibited. #include "Components\Canvas.hxx" #include "Components\Slider.hxx" #include "Components\TrajectoryRenderable.hxx" -#include "Graphics\MiddleEnd\TrajectoryRendering\SHTrajectoryRenderableComponent.h" +#include "Components\Animator.hxx" @@ -338,6 +340,7 @@ namespace SHADE componentMap.Add(createComponentSet()); componentMap.Add(createComponentSet()); componentMap.Add(createComponentSet()); + componentMap.Add(createComponentSet()); } /*---------------------------------------------------------------------------------*/ From 3d6bfaa1196e8b324edee246549cc5f4f60a9218 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 9 Mar 2023 13:46:39 +0800 Subject: [PATCH 49/69] Write raw anim asset id into anim clips --- SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h | 1 + SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h index 3905ddd8..733119c0 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h @@ -25,6 +25,7 @@ namespace SHADE std::string name; uint32_t firstIndex; uint32_t lastIndex; + AssetID animRawDataAssetId; // Not serialised, only populated during runtime from parent asset }; struct SH_API SHAnimClipContainerAsset final : SHAssetData diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp index c1e73540..b59f6807 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp @@ -119,6 +119,8 @@ namespace SHADE reinterpret_cast(&clip.firstIndex), sizeof(uint32_t) * 2 ); + + clip.animRawDataAssetId = data->animRawDataAssetId; } result = data; From bfc8b3600f0ae2a18d58632adfebbf5a304869e6 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 9 Mar 2023 13:56:36 +0800 Subject: [PATCH 50/69] Removed stupid 10 second time limit on dependencies pull --- Dependencies.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dependencies.bat b/Dependencies.bat index ec07e440..30c5e24f 100644 --- a/Dependencies.bat +++ b/Dependencies.bat @@ -24,7 +24,7 @@ echo "Q - vswhere" echo --------------------------------------------------- echo. -choice /C ABCDEFGHIJKLMNOPQ /T 10 /D A +choice /C ABCDEFGHIJKLMNOPQ set _e=%ERRORLEVEL% if %_e%==1 goto VMA From ac971f0945d21f6507f0cbddb83e1bd12c3e50d2 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 9 Mar 2023 14:46:06 +0800 Subject: [PATCH 51/69] Fixed infinite loop and incorrect playback setting for Animator --- SHADE_Engine/src/Animation/SHAnimatorComponent.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 56a326ec..0effbd92 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -33,7 +33,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ void SHAnimatorComponent::Play() { - isPlaying = false; + isPlaying = true; playOnce = false; } @@ -293,9 +293,9 @@ namespace SHADE } // Apply pose to children - for (auto& child : node->Children) + for (auto child : node->Children) { - updatePoseWithClip(poseTime, rawAnimData, node, transformMatrix); + updatePoseWithClip(poseTime, rawAnimData, child, transformMatrix); } } } From ab2f3e395bf391841f928b6353c5a2472555aeac Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 9 Mar 2023 14:47:48 +0800 Subject: [PATCH 52/69] Animation clips now load the correct raw animation --- .../EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp | 1 + SHADE_Engine/src/Resource/SHResourceManager.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index 0391f75d..563c0f60 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -87,6 +87,7 @@ namespace SHADE animClip->name = newAssetName; animClip->firstIndex = firstIndex; animClip->lastIndex = lastIndex; + animClip->animRawDataAssetId = SHResourceManager::GetAssetID(rawAnimation).value_or(0); SHAssetManager::SaveAsset(containerAsset->id); // Close diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index 85f5fd33..6474b478 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -370,7 +370,7 @@ namespace SHADE loadedAssetData.emplace_back(assetId); return resourceHub.Create ( - LoadOrGet(assetId), // TODO: Wrong, we need to grab the parent asset's ID + LoadOrGet(assetData.animRawDataAssetId), assetData.firstIndex, assetData.lastIndex ); From bf08be045ac023437f61fa2b267495255567e9c7 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 9 Mar 2023 14:56:03 +0800 Subject: [PATCH 53/69] Solved bugs with shadows Switching a scene causes a crash from shadows. --- Assets/Scenes/Level2.shade | 4 +-- Assets/Shaders/DeferredComposite_CS.glsl | 6 +++- Assets/Shaders/DeferredComposite_CS.shshaderb | Bin 11569 -> 11569 bytes Assets/Shaders/ShinyHighlight_FS.glsl | 2 +- Assets/Shaders/ShinyHighlight_FS.shshaderb | Bin 5733 -> 5921 bytes .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 28 ++++++++++-------- .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 10 +++---- .../Graphics/RenderGraph/SHRenderGraph.cpp | 6 ++-- 8 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Assets/Scenes/Level2.shade b/Assets/Scenes/Level2.shade index dadf7bf0..ef197542 100644 --- a/Assets/Scenes/Level2.shade +++ b/Assets/Scenes/Level2.shade @@ -45,14 +45,14 @@ NumberOfChildren: 0 Components: Transform Component: - Translate: {x: 0.242245644, y: 1.56757355, z: -6.07086945} + Translate: {x: 0.236000001, y: 1.56757355, z: -6.07086945} Rotate: {x: -0, y: 0, z: -0} Scale: {x: 1, y: 1, z: 1} IsActive: true Light Component: Position: {x: 2, y: 1.5, z: -5.5999999} Type: Directional - Direction: {x: 0, y: 0, z: -1} + Direction: {x: -0.0780000016, y: 0.159999996, z: -1} Color: {x: 0, y: 0, z: 0, w: 1} Layer: 4294967295 Strength: 1 diff --git a/Assets/Shaders/DeferredComposite_CS.glsl b/Assets/Shaders/DeferredComposite_CS.glsl index e9f9eb0c..2839e106 100644 --- a/Assets/Shaders/DeferredComposite_CS.glsl +++ b/Assets/Shaders/DeferredComposite_CS.glsl @@ -73,9 +73,12 @@ float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV float worldNormalDotLight = dot (normalize (worldNormal), normalize(lightDir)); - if (worldNormalDotLight < 0.0f) + if (worldNormalDotLight <= 0.0f) return 0.7f; + // if (worldNormalDotLight <= 0.01f) + // return 0.7f; + if (fragPosLightPOV.z > moments.x && fragPosLightPOV.w > 0.0f) { float p = step (fragPosLightPOV.z, moments.x); @@ -94,6 +97,7 @@ float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV return 0.0f; } + // return min (worldNormalDotLight + 0.7f, 1.0f); return 1.0f; } diff --git a/Assets/Shaders/DeferredComposite_CS.shshaderb b/Assets/Shaders/DeferredComposite_CS.shshaderb index 1ec2bcf0d56aa6c9634e82958dec3fd7f3f954af..a48a176f5d45e271183945cd393248c18c43ea5f 100644 GIT binary patch delta 14 VcmdlOwJ~Z#ss`hp&1o8^SpYG;1|a|d delta 14 VcmdlOwJ~Z#ss`hZ&1o8^SpYGm1|0wZ diff --git a/Assets/Shaders/ShinyHighlight_FS.glsl b/Assets/Shaders/ShinyHighlight_FS.glsl index 18f979fe..b2a2e940 100644 --- a/Assets/Shaders/ShinyHighlight_FS.glsl +++ b/Assets/Shaders/ShinyHighlight_FS.glsl @@ -77,7 +77,7 @@ void main() worldSpacePosition = In.worldPos; outEntityID = In2.eid; - lightLayerIndices = uvec4 (In2.lightLayerIndex, 0, 0, 1); + lightLayerIndices = uvec4 (In2.lightLayerIndex, packHalf2x16 (In.worldNormal.xy), packHalf2x16 (vec2 (In.worldNormal.z, 1.0f)), 1); // float vpHeight = float (In2.screenSpacePos.y) - MatProp.data[In2.materialIndex].highlightPosition; // bring the frame of reference to the object's screen space pos diff --git a/Assets/Shaders/ShinyHighlight_FS.shshaderb b/Assets/Shaders/ShinyHighlight_FS.shshaderb index a3a6230df5e550a976d687e26fd3bab001c76575..7bbcb950f9afcf7c089937860865cd4c234a5f2a 100644 GIT binary patch literal 5921 zcmZ9Oi+@~I5yx-IZqlYtq)-rzNeeAntWe9#N+G4`CK5;>wXM(PcK0T^bhCH4dpBu) z(Sk@7Ux-?HsP(Pj+r9*=P!#bW@IUe6PpBmrR&g$EC+;S74*91Lo1!Aw&Ur8LA3*#n+A<<^hjUp!O673Ux zNK_TQAi5x0r#Q@0;*xrlZ4g{k&{D7>sEk*KAKYDSN3Adov#8ph4eL=_O%6RA)w1@b zJ~AoYY9nmUbi$dax?}rIt*~}jah4N@@|sDr(~PH+bgueHCv3#iag@s5kG(Q6Q5hep z)>^GHXsEv^JhBClF=arF z?0p`q?R3sT*f3DF8r1SWai5p; zp5Xl$G|127IUmmwq{rCEFN*7nzU1R_9S@I2Y3^-t=(TQP6g8)Gek0d$*5m$+HMhIm zxks+==Hd&cf84L6lZ`a9I6FGF$N6*LE?F<$(Uow?-pcDN*yw zfsRLzMvai0Ktg3zazdEqHMu8Kh5642ZzKy*Iv&r(iopDn!a6OrcoFM$_kX5Q-J6Cp z_asSLmy0}0!HeRFDp&SSKP{c>Kj-ady7aSM`nfLs{3UwXy*c>_A-4W~H;A*w|0ASywrK zZwN1}xw|txt=A|&f7lpH=dUk#Q~JzOj*I>k^=wGC0VZgma|eq$_Yj?2uyYU5xxeV# z!;K<_>BOYoQT2yA#MqRxMGQL_amo)OT5$_j1cDF26MOlIMi16p0kqdE5 zCl?03yTo}{u_04O+37vOi1_LCxnHFqk1on3_YGQ_Q*!qOomz;=T|u|?`A+c`uN7hE zn}wa4sE0jfSUrYy_XfXWZ_JOnnQQ&Ay|;MO3}*Ro4mOGyk*|_O zu7i$BI(hlG7Hmkn#6BS#UgR4T{~g}W9uG<%6el+LPOq~*82;o&Jl0014s`4TTID)% z=Hds3@FDi~;>$$%5F357$F7vVMe?B6w|e~s=?vz-Q=Iw5+&KHJZT|0;Om3DtcLDn~ z`Xb*fPOii#4%4rd=XM$Jd%NWKilejk4siw;vC+9#i~)a#$e;KS^SK+`tpUm00d!*B zAx@59#6ss@fYFDY;)5c_fTHn@AvQQ<{k&5$xnm~|`Yw;L&Rt&4`&tTiOJ@z!_ey3^ zqxEl0GBKI|0WWX#cIuiC1;MeqtiSuD75o1|uQUIkm-D=Ho$nX^*gq`JTG%;DAM>)E z#g9wJH^)l>devi=?;+{tUz1F{O(N{XofT0t>&4>Osl)92m;%Gz67LhyAB)eM{dYNF zKPs76HXr`9CO--!SUzKLC2pvcDIOoXYsd49v0p0c%Qp>_ekcBi_lj3UyfxtD!+jkUf#btHy;nre++Tb)ijRxH56Fj_?-MZ(d_rG_ zP2%^9z#+ym5$E9n&FK}N6yd`#>;cJO_!{=0$Cx{*-C?~cC*uo!}A{FZ+Ubi=e8bquhHoV=XycZeXfsq zd|0{g9)3bZew=4)cK)dGlOpVo`kFuGv8MDbl0Pj1BNz0~h{*dXt&jew2p{mo$2cY# z+~ypY%$z6voW~@CvDY@|amnD1%ZI!^D>~-%yjQ$mVAhi-B!ij$Imx_v$Nl^#C4=Ed zud#ty-#+i~OYis>gn?V%o|0^R!)9lb{Jto{ZhQA7$?OC7qj-kCEFGKG^%cpSAMhu9 zu3wc*JZy%2O)~h?BJw{W4rcX!T{1P9{te0a*gD^oj1M^TpAiQ$|8Gey&VN=q^R0i+ zNyZ19`6tD}=pT3H+oBgl#dG={kJ}pGmCm{^YtHlHr$qRG|5Gu)FV6Un&dn+D?}@

;jk_fxa{f%Vm zGyS)ci?Mzu9UpM=J1tHu-bqbFpKv`$;7ko)So1S6^VHlgkfWk**Es+ zRdKVu)@8$oJ$qgJ&m!hu6yc9fj{jBWw~P4QMJ@D!v0QYU{QAUK6y*Mbys{v#D#)uP zliONxt8txVd`!PwGI33Ri)3P3&#sV+54icPmrQKauarzon{$<9e8BB(*&vx%*lga_ nlF8llYa|!feyenRz)$$TTq~Ja*p7SbZIY=A+y7KAI=%cq$?j-b literal 5733 zcmZ9O`*&2;6~`}RCV>zhR>WG{Gy#jYSgI6XMT0@YByE&vD4?|+FEcmEmC4-k&YcAM z0Fhd$wzieNpJLw?r4O`-wRZWFe?k9~u0GakSHGWg&rU9LV6Xk%-@VU1`|NYhoosk? zQ{YC=$}N3Cup;OW)&_seso<($rI^6!*EZ(*b+6x)?hjT4(^ChlV}}n^>ruOw#;q(# zt8ud)9gCZ@!J44g&96*OPi}8#_3b-vyM@&2f*!X5x!3DoNgA0C<0g(_$yUkD5+;mD z4oDuBR3&F67bP2%hj}Vos7KWX!8=M?3RVY|$?E7sd#dfI6{cYpRoio6JxZ&|k;kK2 z*1j@EE|pttgw5GbI2%=W?zp8D){ZLAD)O+sX4335v5`;;)RH{Tpk}6H*1Yfy%=hZm-Gh@pyL5`3Gdz+u4$TZEkyi+4Z}XwBsyJT>s1J z#<2b+0!g37#Z>mLM1FqM_aMFuO+Nd*8!+7@V_y_U{tjU>A zr~>xL+2^_1&gLG3jU!P#!Cww;lbuD!vQ8Sgyl}URyFbjP(xkOF%tEcz=Qz<8JHg$= z?$wzP&mQK~sD^~iSre!eKYPmN;@Z(>)Mg>h=1ys?6Qyz3U@^5NrV4t6k5Q)p4fgU0 zX{xM z%^j|G-jVCOh4>BAKi*f;$;O&loE@Lo>*9HDSF9J;T*KMdjC}1{*vRi;Ihd2Z&>D|u zrJ&}Q16_q6jT#{@fr84~$q8|q*W{f{7v?`JzL6|O>0~?~D+BYN7uRX2#Yb^9by)Q}9x0~cdq0((Lr5%;2sg<&an};+EM*LJRiC9gy%dL;%Kpzq}idkp3y_j6CdYk zKI5$aRNwuVg?%jJ++(RZ&%NJrd%1 zXVgL-v#Eta?1=O_hf5B#kFxiTNnhNU$5je=dm~RvO5y5>+Z#e6ZoxSB_&u~@`_kjK|s0Z8nbG4#~8`d21 zf;S0K>yVR@ZeIRd3pcD&;+(+77xlHu|3UBPjE7_oNs}9Xm$z9Tj(BP#A8TW?4{ZE{ zTIB|5<`RcSh#~ifq*q9YAvg9`&s`(?M&TiEZ}av|vKh?(ur%|FwQ=`Z+u}beOl?*> zZvp>x`bEA~np(+G9A;my$Q^PJ_W|LLOJlS4PH6@lxv_ayj6wf~sGs}@^LZP*twCYl z05-YqlBPyDa$)l>;ON6H=^+VYP}%O5CO14{{k%t*+VPVId&G0Bv)kjmuccs*Y}PP) zpD=?xTK^`5$;tdrdc4{D+1Gwa5Init`g=fDvHzd;HuDdAoY$S({C*LS{}E}{!p~j$ ztjBg2KPQ{moG%5~RnJi`^NvUuX4izR{z$k_!hUUkv%-H@0PDxX#Ii4J{n_IBgKhav zdk!1^j3fx&-Lp}VF9^{G?j_$5a#`FeA#n%}RtWaDGbU!_+{;8-8~ZO`4VyNZt|FI z0*^3ONVpFVYEG~8l!O?DaSsZ^5o_E-o@4HmPJ{KP9VR9S@N=i>AKzen*6)MD)XulU z`h7?ko_M|~*u?XV_>AM1_sYG0bcyeAzwy`>|Cli6W9LbHD0xgmt$a`F61XE?YSOG- zmBt62k)D-|sxy2m9(R0RH}TX?&yFtndfZ#VrWWqXyrlcCG(A76S`y)w#O?|{J5zE$ z;r%E5TB+xnvbj5L2^_UxXA<~-x)92174e>Ug1F#Ku7 zP}k=r@Nz>Nly9sUlN8Rj`{fDtZyeBf91P*QXIVX?Ub5$X*kRKoG^Pb z`)k6)*g9VqCI+7Q&q~8t{5OP)^S>#Z`PRR02@?a){O6_N=pT3W+mf@A;ywM2=WUJe z%4Xfmn)8D6_awx?|5G`CAkFxX?hU^0OW^pu0NYwW6z*Q@N8;dZtse_h<0Ze=PlSnq z|F`m4Ui3foE~w|H64otCh-XdedQqA|UBvuM@@ENkf$7IN>6au{cc&qW3 z!t~tE=vTtTzz^uwbFY3aSs^J&@Y~$q2(v%4e=A(f^*hF-$T_`PJEggne=9`VF6m;DoC_548?Za}{S%>Sc=eQcB9V}0`5-v8un z;w&GW<$Fz-eD>{sT^Oz?%)2NKA7}icG-t$FneS4Uj~LGEvh78bwp=SrE_^ocy~5OP_I1L=wcjV382B^3FV_o`3*RZvy84-+|3h5!Hn diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 397edf74..bc50d0a7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -865,32 +865,30 @@ namespace SHADE std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity); std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); std::string shadowMapBlurredResourceName = "ShadowMap Blurred" + std::to_string(EVENT_DATA->lightEntity); - Handle gBufferWriteSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS); - Handle gBufferWriteVfxSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_VFX_SUBPASS); + + // we need to wait for the device to finish using the graph first + device->WaitIdle(); + if (EVENT_DATA->enableShadow) { // When the light first enables shadow rendering, we need to prepare the relevant objects to render shadows; namely renderpasses and subpasses, pipelines and descriptor sets if (EVENT_DATA->firstEnable) { - // we need to wait for the device to finish using the graph first - device->WaitIdle(); + Handle gBufferWriteSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS); + Handle gBufferWriteVfxSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_VFX_SUBPASS); + // Create new renderer for the light component and give it to the light component Handle newRenderer = resourceManager.Create(device, swapchain->GetNumImages(), descPool, SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC); lightComp->SetRenderer(newRenderer); - // assign shadow map index to light component - lightComp->SetShadowMapIndex(lightingSubSystem->GetNumShadowMaps()); - - // Add the shadow map resource to the graph renderGraph->AddResource(depthResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat); renderGraph->AddResource(shadowMapResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat); renderGraph->AddResource(shadowMapBlurredResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat); - // link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer. auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, { depthResourceName.c_str(), shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() }, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data()); @@ -929,6 +927,10 @@ namespace SHADE // add the shadow map and the blurred version to the lighting system uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapBlurredResourceName), EVENT_DATA->lightEntity); + // assign shadow map index to light component + lightComp->SetShadowMapIndex(NEW_SHADOW_MAP_INDEX); + + // Get deferred composite node compute and modify descriptor set auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()); nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX); @@ -964,12 +966,12 @@ namespace SHADE std::string shadowMapBlurredResourceName = "ShadowMap Blurred" + std::to_string(EVENT_DATA->lightEntity); // Remove render graph node - //renderGraph->RemoveNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName); + renderGraph->RemoveNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName); // Remove render graph resource - //renderGraph->RemoveResource(depthResourceName); - //renderGraph->RemoveResource(shadowMapResourceName); - //renderGraph->RemoveResource(shadowMapBlurredResourceName); + renderGraph->RemoveResource(depthResourceName); + renderGraph->RemoveResource(shadowMapResourceName); + renderGraph->RemoveResource(shadowMapBlurredResourceName); // Register light component shadow map index into light system as recyclable lightingSubSystem->RemoveShadowMap (EVENT_DATA->lightEntity); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index a2b9cc0a..b17964e4 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -62,15 +62,13 @@ namespace SHADE // write view projection matrix if renderer is available auto lightRenderer = lightComp->GetRenderer(); if (lightRenderer) - { lightPtr->pvMatrix = lightRenderer->GetCPUCameraData().viewProjectionMatrix; - // Boolean to cast shadows in first 8 bits (1 byte) - lightPtr->shadowData = lightData.castShadows; + // Boolean to cast shadows in first 8 bits (1 byte) + lightPtr->shadowData = lightData.castShadows; - // Next 24 bits for shadow map index - lightPtr->shadowData |= (lightData.shadowMapIndex << 8); - } + // Next 24 bits for shadow map index + lightPtr->shadowData |= (lightData.shadowMapIndex << 8); break; } case SH_LIGHT_TYPE::POINT: diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 34206e5b..c44c9464 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -111,7 +111,6 @@ namespace SHADE renderGraphStorage->graphResources->at(resourceName).Free(); renderGraphStorage->graphResources->erase (resourceName); - resourceHdl.Free (); /* * IMPORTANT NOTES * @@ -134,8 +133,11 @@ namespace SHADE // Get handle to node since it exists auto nodeHdl = nodes[nodeIndexing[nodeName]]; + nodes.erase(nodes.begin() + nodeIndexing[nodeName]); + nodeHdl.Free(); - nodeIndexing.erase(nodeName); + + ReindexNodes(); } } From baed0bec0b9b29c4079b6f02e82974eb317b5001 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 9 Mar 2023 15:08:38 +0800 Subject: [PATCH 54/69] Fixed animator component always using manual mode playback time --- SHADE_Engine/src/Animation/SHAnimatorComponent.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 0effbd92..7d4a2765 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -257,7 +257,7 @@ namespace SHADE return; // Play the clip - updatePoseWithClip(clip, currPlaybackTime); + updatePoseWithClip(clip, playbackTime); } void SHAnimatorComponent::updatePoseWithClip(Handle clip, float poseTime) { @@ -286,7 +286,6 @@ namespace SHADE // Apply transformations to this node const int BONE_MTX_IDX = rig->GetNodeIndex(node); - std::optional position; if (BONE_MTX_IDX >= 0) { boneMatrices[BONE_MTX_IDX] = node->OffsetMatrix * transformMatrix; From bfbca68d50bd91cea177eca4ee669db8aae1578e Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 9 Mar 2023 15:14:30 +0800 Subject: [PATCH 55/69] Added more animation tests --- ...igTest01_SkinningTestAnims.shanimcontainer | Bin 0 -> 24 bytes ...1_SkinningTestAnims.shanimcontainer.shmeta | 7 ++++ .../racoonAnims.shanimcontainer | Bin 215 -> 231 bytes .../racoonAnims.shanimcontainer.shmeta | 3 ++ Assets/Scenes/anim.shade | 32 ++++++++++++++++-- Assets/Scripts/AnimTest.cs | 14 +++++--- 6 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 Assets/Animation Clips/MD_RigTest01_SkinningTestAnims.shanimcontainer create mode 100644 Assets/Animation Clips/MD_RigTest01_SkinningTestAnims.shanimcontainer.shmeta diff --git a/Assets/Animation Clips/MD_RigTest01_SkinningTestAnims.shanimcontainer b/Assets/Animation Clips/MD_RigTest01_SkinningTestAnims.shanimcontainer new file mode 100644 index 0000000000000000000000000000000000000000..5d6924e2be094865660e35de817f0e71ebd1574b GIT binary patch literal 24 acmewz Date: Thu, 9 Mar 2023 15:20:40 +0800 Subject: [PATCH 56/69] Changed to correct RIG --- Assets/Scenes/anim.shade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Scenes/anim.shade b/Assets/Scenes/anim.shade index fb4049fa..986195f6 100644 --- a/Assets/Scenes/anim.shade +++ b/Assets/Scenes/anim.shade @@ -28,7 +28,7 @@ Material: 128805346 IsActive: true Animator Component: - Rig: 76586906 + Rig: 77816045 AnimationController: 0 IsActive: true Scripts: From fe41245008cb775777e888989ebcdb2bff883a67 Mon Sep 17 00:00:00 2001 From: SHAM-DP Date: Thu, 9 Mar 2023 15:28:32 +0800 Subject: [PATCH 57/69] Bug Fixes & Tweaks for editor fixed window width for physics settings drop down fixed double click to look at fix crash when some fields in collider and rigidbody are set to 0.0f --- .../HierarchyPanel/SHHierarchyPanel.cpp | 3 +- .../Inspector/SHEditorComponentView.hpp | 13 ++++--- .../Inspector/SHEditorInspector.cpp | 36 +++++++++++++++++++ .../Inspector/SHEditorInspector.h | 2 +- .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 1 + SHADE_Engine/src/Editor/SHEditor.cpp | 6 ++++ 6 files changed, 54 insertions(+), 7 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 8f0a8193..311b1cd0 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -454,7 +454,8 @@ namespace SHADE { if(auto entityTransform = SHComponentManager::GetComponent_s(eid)) { - editorCam->SetPosition(entityTransform->GetWorldPosition() + SHVec3(0.5f)); + SHVec3 scale = entityTransform->GetLocalScale(); + editorCam->SetPosition(entityTransform->GetWorldPosition() + scale * 0.5f); camSystem->CameraLookAt(*editorCam, entityTransform->GetWorldPosition()); camSystem->UpdateEditorCamera(SHFrameRateController::GetRawDeltaTime()); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index c655ff60..3f468d64 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -273,8 +273,8 @@ namespace SHADE } if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields { - SHEditorWidgets::DragFloat("Drag", [component] {return component->GetDrag(); }, [component](float const& value) {component->SetDrag(value); }, "Drag"); - SHEditorWidgets::DragFloat("Angular Drag", [component] {return component->GetAngularDrag(); }, [component](float const& value) {component->SetAngularDrag(value); }, "Angular Drag"); + SHEditorWidgets::DragFloat("Drag", [component] {return component->GetDrag(); }, [component](float const& value) {component->SetDrag(value); }, "Drag", 0.1f, 0.0001f, std::numeric_limits::infinity()); + SHEditorWidgets::DragFloat("Angular Drag", [component] {return component->GetAngularDrag(); }, [component](float const& value) {component->SetAngularDrag(value); }, "Angular Drag", 0.1f, 0.0001f, std::numeric_limits::infinity()); SHEditorWidgets::CheckBox("Interpolate", [component] {return component->IsInterpolating(); }, [component](bool const& value) {component->SetInterpolate(value); }, "Interpolate"); @@ -377,7 +377,8 @@ namespace SHADE ( "Radius", [sphereShape] { return sphereShape->GetRelativeRadius(); }, - [sphereShape](float const& value) { sphereShape->SetRelativeRadius(value); } + [sphereShape](float const& value) { sphereShape->SetRelativeRadius(value); }, "Collider Radius", 0.1f, + 0.0001f, std::numeric_limits::infinity() ); } else if (collisionShape->GetType() == SHCollisionShape::Type::CAPSULE) @@ -388,13 +389,15 @@ namespace SHADE ( "Radius", [capsuleShape] { return capsuleShape->GetRelativeRadius(); }, - [capsuleShape](float const& value) { capsuleShape->SetRelativeRadius(value); } + [capsuleShape](float const& value) { capsuleShape->SetRelativeRadius(value); }, "Collider Radius", 0.1f, + 0.0001f, std::numeric_limits::infinity() ); SHEditorWidgets::DragFloat ( "Height", [capsuleShape] { return capsuleShape->GetRelativeHeight(); }, - [capsuleShape](float const& value) { capsuleShape->SetRelativeHeight(value); } + [capsuleShape](float const& value) { capsuleShape->SetRelativeHeight(value); }, "Collider Height", 0.1f, + 0.0001f, std::numeric_limits::infinity() ); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index faede2bd..f331f499 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -26,6 +26,8 @@ #include "SHEditorComponentView.h" #include "AudioSystem/SHAudioListenerComponent.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" +#include "Camera/SHCameraSystem.h" +#include "FRC/SHFramerateController.h" namespace SHADE { @@ -106,6 +108,7 @@ namespace SHADE { if (editor && !editor->selectedEntities.empty()) { + DrawMenuBar(); EntityID const& eid = editor->selectedEntities[0]; SHEntity* entity = SHEntityManager::GetEntityByID(eid); SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(eid); @@ -114,6 +117,7 @@ namespace SHADE ImGui::End(); return; } + ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid); SHEditorWidgets::CheckBox("##IsActive", [entityNode]()->bool {return entityNode->IsActive(); }, [entityNode](bool const& active) {entityNode->SetActive(active); }); ImGui::SameLine(); @@ -222,4 +226,36 @@ namespace SHADE { SHEditorWindow::Exit(); } + void SHEditorInspector::DrawMenuBar() + { + if(ImGui::BeginMenuBar()) + { + EntityID const& eid = editor->selectedEntities[0]; + SHEntity* entity = SHEntityManager::GetEntityByID(eid); + SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(eid); + if (!entity || !entityNode) + { + ImGui::EndMenuBar(); + return; + } + if (ImGui::SmallButton("Look At")) + { + editor->selectedEntities.clear(); + editor->selectedEntities.push_back(eid); + if (auto camSystem = SHSystemManager::GetSystem()) + { + if (auto editorCam = camSystem->GetEditorCamera()) + { + if (auto entityTransform = SHComponentManager::GetComponent_s(eid)) + { + editorCam->SetPosition(entityTransform->GetWorldPosition() + SHVec3(0.5f)); + camSystem->CameraLookAt(*editorCam, entityTransform->GetWorldPosition()); + camSystem->UpdateEditorCamera(SHFrameRateController::GetRawDeltaTime()); + } + } + } + } + ImGui::EndMenuBar(); + } + } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.h b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.h index 06676beb..431f3239 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.h +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.h @@ -25,6 +25,6 @@ namespace SHADE void Exit() override; private: - + void DrawMenuBar(); }; } diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index 21cc85f4..65e497aa 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -358,6 +358,7 @@ namespace SHADE void SHEditorMenuBar::DrawPhysicsSettings() noexcept { + ImGui::SetNextWindowSize({400.0f, 0.0f}); if (ImGui::BeginMenu("Physics Settings")) { if (auto* physicsSystem = SHSystemManager::GetSystem()) diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 4c7db57c..4129cc15 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -669,6 +669,12 @@ namespace SHADE SaveScene(); } } + if(editorState == State::PLAY && ImGui::IsKeyReleased(ImGuiKey_LeftAlt)) + { + SHInputManager::SetMouseCentering(!SHInputManager::GetMouseCentering()); + SHWindow::SetMouseVisible(!SHWindow::GetMouseVisible()); + + } if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z)) { SHCommandManager::RedoCommand(); From 621f8a5f381122d07f08387f5884e17839fa838c Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 9 Mar 2023 15:41:27 +0800 Subject: [PATCH 58/69] Added Capsule Collider to Managed --- SHADE_Managed/src/Components/Collider.cxx | 100 +++++++++++----------- SHADE_Managed/src/Components/Collider.h++ | 3 +- SHADE_Managed/src/Components/Collider.hxx | 86 ++++++++++--------- 3 files changed, 101 insertions(+), 88 deletions(-) diff --git a/SHADE_Managed/src/Components/Collider.cxx b/SHADE_Managed/src/Components/Collider.cxx index ac191cdd..fcabfb0a 100644 --- a/SHADE_Managed/src/Components/Collider.cxx +++ b/SHADE_Managed/src/Components/Collider.cxx @@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited. #include "Collider.hxx" #include "Physics/Collision/Shapes/SHBox.h" +#include "Physics/Collision/Shapes/SHCapsule.h" #include "Physics/Collision/Shapes/SHSphere.h" #include "Utility/Debug.hxx" @@ -118,6 +119,29 @@ namespace SHADE } } + /*---------------------------------------------------------------------------------*/ + /* SphereCollider - Properties */ + /*---------------------------------------------------------------------------------*/ + Vector3 SphereCollider::Center::get() + { + return Convert::ToCLI(getNativeCollisionShape().GetWorldCentroid()); + } + float SphereCollider::Radius::get() + { + return getNativeCollisionShape().GetWorldRadius(); + } + void SphereCollider::Radius::set(float value) + { + getNativeCollisionShape().SetWorldRadius(value); + } + + /*---------------------------------------------------------------------------------*/ + /* SphereCollider - Constructors */ + /*---------------------------------------------------------------------------------*/ + SphereCollider::SphereCollider(int arrayIndex, Entity attachedEntity) + : CollisionShape{ arrayIndex, attachedEntity } + {} + /*---------------------------------------------------------------------------------*/ /* BoxCollider - Constructors */ /*---------------------------------------------------------------------------------*/ @@ -147,53 +171,33 @@ namespace SHADE } /*---------------------------------------------------------------------------------*/ - /* BoxCollider - Usage Functions */ + /* CapsuleCollider - Properties */ /*---------------------------------------------------------------------------------*/ - bool BoxCollider::TestPoint(Vector3 point) + Vector3 CapsuleCollider::Center::get() { - //return getNativeCollisionShape().TestPoint(Convert::ToNative(point)); - return false; + return Convert::ToCLI(getNativeCollisionShape().GetWorldCentroid()); } - bool BoxCollider::Raycast(Ray ray, float maxDistance) + float CapsuleCollider::Radius::get() { - //return getNativeCollisionShape().Raycast(Convert::ToNative(ray)); - return false; + return getNativeCollisionShape().GetWorldRadius(); + } + void CapsuleCollider::Radius::set(float value) + { + getNativeCollisionShape().SetWorldRadius(value); + } + float CapsuleCollider::Height::get() + { + return getNativeCollisionShape().GetWorldHeight(); + } + void CapsuleCollider::Height::set(float value) + { + getNativeCollisionShape().SetWorldHeight(value); } /*---------------------------------------------------------------------------------*/ - /* SphereCollider - Properties */ + /* CapsuleCollider - Constructors */ /*---------------------------------------------------------------------------------*/ - Vector3 SphereCollider::Center::get() - { - return Convert::ToCLI(getNativeCollisionShape().GetWorldCentroid()); - } - float SphereCollider::Radius::get() - { - return getNativeCollisionShape().GetWorldRadius(); - } - void SphereCollider::Radius::set(float value) - { - getNativeCollisionShape().SetWorldRadius(value); - } - - /*---------------------------------------------------------------------------------*/ - /* SphereCollider - Usage Functions */ - /*---------------------------------------------------------------------------------*/ - bool SphereCollider::TestPoint(Vector3 point) - { - //return getNativeCollisionShape().TestPoint(Convert::ToNative(point)); - return false; - } - bool SphereCollider::Raycast(Ray ray, float maxDistance) - { - //return getNativeCollisionShape().Raycast(Convert::ToNative(ray)); - return false; - } - - /*---------------------------------------------------------------------------------*/ - /* SphereCollider - Constructors */ - /*---------------------------------------------------------------------------------*/ - SphereCollider::SphereCollider(int arrayIndex, Entity attachedEntity) + CapsuleCollider::CapsuleCollider(int arrayIndex, Entity attachedEntity) : CollisionShape{ arrayIndex, attachedEntity } {} @@ -303,18 +307,18 @@ namespace SHADE int i = 0; for (const auto& collider : GetNativeComponent()->GetCollisionShapes()) { - CollisionShape^ bound = nullptr; + CollisionShape^ shape = nullptr; switch (collider->GetType()) { - case SHCollisionShape::Type::BOX: - bound = gcnew BoxCollider(i, Owner.GetEntity()); - break; case SHCollisionShape::Type::SPHERE: - bound = gcnew SphereCollider(i, Owner.GetEntity()); + shape = gcnew SphereCollider(i, Owner.GetEntity()); + break; + case SHCollisionShape::Type::BOX: + shape = gcnew BoxCollider(i, Owner.GetEntity()); + break; + case SHCollisionShape::Type::CAPSULE: + shape = gcnew CapsuleCollider(i, Owner.GetEntity()); break; - //case SHCollisionShape::Type::CAPSULE: - // // TODO - // break; default: Debug::LogWarning("[Collider] An invalid Collider Type was detected. Skipping."); break; @@ -322,7 +326,7 @@ namespace SHADE ++i; // Add into list - subColliderList->Add(bound); + subColliderList->Add(shape); } } } \ No newline at end of file diff --git a/SHADE_Managed/src/Components/Collider.h++ b/SHADE_Managed/src/Components/Collider.h++ index b16e8063..8dc13e01 100644 --- a/SHADE_Managed/src/Components/Collider.h++ +++ b/SHADE_Managed/src/Components/Collider.h++ @@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited. // Primary Include #include "Component.hxx" + namespace SHADE { template @@ -28,7 +29,7 @@ namespace SHADE try { auto& shape = collider->GetCollisionShape(arrayIndex); - if (shape.GetType() != SHCollisionShape::Type::BOX) + if (shape.GetType() == SHCollisionShape::Type::INVALID) throw gcnew System::InvalidOperationException("Attempted to retrieve invalid CollisionShape."); return dynamic_cast(shape); diff --git a/SHADE_Managed/src/Components/Collider.hxx b/SHADE_Managed/src/Components/Collider.hxx index 3c7b060e..d934affd 100644 --- a/SHADE_Managed/src/Components/Collider.hxx +++ b/SHADE_Managed/src/Components/Collider.hxx @@ -87,23 +87,6 @@ namespace SHADE void set(float value); } - /*-----------------------------------------------------------------------------*/ - /* Usage Functions */ - /*-----------------------------------------------------------------------------*/ - ///

- /// Checks if the specified point is within this shape's bounds. - /// - /// Point to test with. - /// True if the point is in the shape's bounds. - virtual bool TestPoint(Vector3 point) = 0; - /// - /// Computes a Raycast and checks if there is a collision with any object. - /// - /// The ray to cast. - /// Maximum distance for the raycast check. - /// True if the ray intersects with an object in the scene. - virtual bool Raycast(Ray ray, float maxDistance) = 0; - protected: /*-----------------------------------------------------------------------------*/ /* Constructors */ @@ -135,7 +118,39 @@ namespace SHADE }; /// - /// Box-shaped Collider Bound. + /// A Sphere Collider + /// + public ref class SphereCollider : public CollisionShape + { + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Center of the sphere. + /// + property Vector3 Center + { + Vector3 get(); + } + /// + /// Radius of the sphere/ + /// + property float Radius + { + float get(); + void set(float value); + } + + internal: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + SphereCollider(int arrayIndex, Entity attachedEntity); + }; + + /// + /// A Box Collider /// public ref class BoxCollider : public CollisionShape { @@ -166,14 +181,6 @@ namespace SHADE Quaternion get(); } - /*-----------------------------------------------------------------------------*/ - /* ColliderBound Functions */ - /*-----------------------------------------------------------------------------*/ - /// - bool TestPoint(Vector3 point) override; - /// - bool Raycast(Ray ray, float maxDistance) override; - internal: /*-----------------------------------------------------------------------------*/ /* Constructors */ @@ -182,44 +189,45 @@ namespace SHADE }; /// - /// Sphere-shaped Collider Bound. + /// A Capsule Collider /// - public ref class SphereCollider : public CollisionShape + public ref class CapsuleCollider : public CollisionShape { public: /*-----------------------------------------------------------------------------*/ /* Properties */ /*-----------------------------------------------------------------------------*/ /// - /// Center of the sphere. + /// Center of the capsule. /// property Vector3 Center { Vector3 get(); } /// - /// Radius of the Bounding Sphere formed by this bound. + /// Radius of the capsule. /// property float Radius { float get(); void set(float value); } - - /*-----------------------------------------------------------------------------*/ - /* ColliderBound Functions */ - /*-----------------------------------------------------------------------------*/ - /// - bool TestPoint(Vector3 point) override; - /// - bool Raycast(Ray ray, float maxDistance) override; + /// + /// Height of the capsule. + /// + property float Height + { + float get(); + void set(float value); + } internal: /*-----------------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------------*/ - SphereCollider(int arrayIndex, Entity attachedEntity); + CapsuleCollider(int arrayIndex, Entity attachedEntity); }; + /// /// CLR version of the the SHADE Engine's SHColliderComponent. From 7f170deb27a5c78f7034e0b3cab9a34ae4af652f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 9 Mar 2023 15:46:15 +0800 Subject: [PATCH 59/69] Fixed animations not playing from the correct start point --- Assets/Scripts/AnimTest.cs | 17 ++++++++++++----- SHADE_Engine/src/Animation/SHAnimationClip.cpp | 5 ++++- SHADE_Engine/src/Animation/SHAnimationClip.h | 4 +++- .../src/Animation/SHAnimationController.cpp | 14 ++++++++++++-- .../src/Animation/SHAnimatorComponent.cpp | 8 +++++--- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/Assets/Scripts/AnimTest.cs b/Assets/Scripts/AnimTest.cs index 324058b2..4ceccbe6 100644 --- a/Assets/Scripts/AnimTest.cs +++ b/Assets/Scripts/AnimTest.cs @@ -1,4 +1,6 @@ -namespace SHADE.Test +using System; + +namespace SHADE.Test { public class AnimTest : Script { @@ -25,21 +27,26 @@ protected override void update() { + // Play loop if shift is held + Action playFunc = Input.GetKey(Input.KeyCode.LeftShift) ? (x) => Animator.Play(x) + : (x) => Animator.PlayOneShot(x); + + // Play animations if (Input.GetKeyUp(Input.KeyCode.Equals)) { - Animator.Play(fullClip); + playFunc(fullClip); } else if (Input.GetKeyUp(Input.KeyCode.Alpha1)) { - Animator.Play(idleClip); + playFunc(idleClip); } else if (Input.GetKeyUp(Input.KeyCode.Alpha2)) { - Animator.Play(runClip); + playFunc(runClip); } else if (Input.GetKeyUp(Input.KeyCode.Alpha3)) { - Animator.Play(pickUpClip); + playFunc(pickUpClip); } } #endregion diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.cpp b/SHADE_Engine/src/Animation/SHAnimationClip.cpp index 130503af..b4a62651 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationClip.cpp @@ -25,11 +25,14 @@ namespace SHADE , startFrameIndex { firstFrame } , endFrameIndex { lastFrame } , duration { 0.0f } + , startTimeStamp { 0.0f } { if (!rawAnim) return; + const float SECS_PER_TICK = 1.0f / static_cast(rawAnim->GetTicksPerSecond()); const int ONE_PAST_LAST_FRAME = lastFrame + 1; - duration = (ONE_PAST_LAST_FRAME - firstFrame) / rawAnim->GetTicksPerSecond(); + duration = static_cast(ONE_PAST_LAST_FRAME - firstFrame) * SECS_PER_TICK; + startTimeStamp = static_cast(firstFrame) * SECS_PER_TICK; } } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h index 9de621d0..6b97c955 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -50,6 +50,7 @@ namespace SHADE inline int GetStartFrameIndex() const noexcept { return startFrameIndex; } inline int GetEndFrameIndex() const noexcept { return endFrameIndex; } inline float GetTotalDuration() const noexcept { return duration; } + inline float GetStartTimeStamp() const noexcept { return startTimeStamp; } private: /*---------------------------------------------------------------------------------*/ @@ -58,6 +59,7 @@ namespace SHADE Handle rawAnim; int startFrameIndex; // First Frame int endFrameIndex; // Last Frame (inclusive) - float duration; // Total playback time + float duration; // Total playback time + float startTimeStamp; // Starting time stamp of the raw anim }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 9b7b6de2..8152426f 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -65,18 +65,21 @@ namespace SHADE instData.ClipPlaybackTime += dt; // Check if we finished playing - if (instData.ClipPlaybackTime > instData.CurrentNode->Clip->GetTotalDuration()) + const float CLIP_CURR_PLAYED_TIME = instData.ClipPlaybackTime - instData.CurrentNode->Clip->GetStartTimeStamp(); + if (CLIP_CURR_PLAYED_TIME > instData.CurrentNode->Clip->GetTotalDuration()) { // Clamp - instData.ClipPlaybackTime = instData.CurrentNode->Clip->GetTotalDuration(); + instData.ClipPlaybackTime = instData.CurrentNode->Clip->GetStartTimeStamp() + instData.CurrentNode->Clip->GetTotalDuration(); // Go to next state + bool stateChanged = false; for (const auto& transition : instData.CurrentNode->Transitions) { // Check for no condition special case if (transition.Condition == Transition::ConditionType::None) { changeNode(instData, transition.Target); + stateChanged = true; break; } else @@ -90,6 +93,7 @@ namespace SHADE if (transition.EvaluateCondition(param)) { changeNode(instData, transition.Target); + stateChanged = true; // If trigger, we need to unset it if (param.ParamType == AnimParam::Type::Trigger) @@ -101,6 +105,12 @@ namespace SHADE } } } + + // Handle if there is no next state, we repeat + if (!stateChanged) + { + instData.ClipPlaybackTime = instData.CurrentNode->Clip->GetStartTimeStamp(); + } } } diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 7d4a2765..d21ee5e1 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -62,6 +62,7 @@ namespace SHADE { // Calculate secs for the clip secsPerTick = 1.0f / RAW_ANIM->GetTicksPerSecond(); + currPlaybackTime = currClip->GetStartTimeStamp(); // Start playback Play(); @@ -232,17 +233,18 @@ namespace SHADE void SHAnimatorComponent::updateManualClipState(float dt) { currPlaybackTime += dt; - if (currPlaybackTime > currClip->GetTotalDuration()) + const float CLIP_CURR_PLAYED_TIME = currPlaybackTime - currClip->GetStartTimeStamp(); + if (CLIP_CURR_PLAYED_TIME > currClip->GetTotalDuration()) { if (playOnce) { playOnce = false; isPlaying = false; - currPlaybackTime = currClip->GetTotalDuration(); + currPlaybackTime = currClip->GetStartTimeStamp() + currClip->GetTotalDuration(); } else { - currPlaybackTime = currPlaybackTime - currClip->GetTotalDuration(); + currPlaybackTime = currClip->GetStartTimeStamp(); } } } From 2eee1d4ab75842f5a07abb04c3da7e6317bb75dc Mon Sep 17 00:00:00 2001 From: Glence Date: Thu, 9 Mar 2023 18:47:06 +0800 Subject: [PATCH 60/69] camera offset rotation fix along with ai not hard hard for box collider --- Assets/Scenes/Level1.shade | 22 +++++++++++++------ .../Implemented/LeafNodes/LeafSearch.cs | 4 ++-- Assets/Scripts/Gameplay/Item/SC_Item.cs | 11 +++++++--- SHADE_Engine/src/Camera/SHCameraSystem.cpp | 2 +- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Assets/Scenes/Level1.shade b/Assets/Scenes/Level1.shade index 6e3aa1c5..9fcbf7ce 100644 --- a/Assets/Scenes/Level1.shade +++ b/Assets/Scenes/Level1.shade @@ -2419,7 +2419,7 @@ Components: Transform Component: Translate: {x: 0, y: 0, z: 0} - Rotate: {x: 0, y: 0, z: 0} + Rotate: {x: -1.48352981, y: 0, z: 0} Scale: {x: 1, y: 1, z: 1} IsActive: true Renderable Component: @@ -4107,7 +4107,7 @@ Collider Component: Colliders: - Is Trigger: false - Collision Tag: 0 + Collision Tag: 1 Type: Box Half Extents: {x: 20, y: 0.100000001, z: 20} Friction: 0.400000006 @@ -4299,6 +4299,8 @@ Enabled: true Score: 50 currCategory: 1 + returnBack: false + firstPostion: [0, 0, 0] density: 1 dontReturn: false soundDistance: 10 @@ -4311,7 +4313,7 @@ NumberOfChildren: 0 Components: Transform Component: - Translate: {x: 3.22328258, y: 1.02709854, z: -0.57395637} + Translate: {x: 3.22328258, y: 1.11577427, z: -0.57395637} Rotate: {x: 5.62993963e-09, y: -7.03049191e-17, z: -1.92319405e-08} Scale: {x: 1, y: 1, z: 1} IsActive: true @@ -4351,6 +4353,8 @@ Enabled: true Score: 500 currCategory: 2 + returnBack: false + firstPostion: [0, 0, 0] density: 1 dontReturn: false soundDistance: 10 @@ -4403,6 +4407,8 @@ Enabled: true Score: 10 currCategory: 0 + returnBack: false + firstPostion: [0, 0, 0] density: 1 dontReturn: false soundDistance: 10 @@ -4455,6 +4461,8 @@ Enabled: true Score: 10 currCategory: 0 + returnBack: false + firstPostion: [0, 0, 0] density: 1 dontReturn: false soundDistance: 10 @@ -4804,7 +4812,7 @@ IsActive: true Animator Component: Rig: 72178939 - Clip: 72178939 + AnimationController: 0 IsActive: true Scripts: ~ - EID: 219 @@ -4823,7 +4831,7 @@ IsActive: true Animator Component: Rig: 80728853 - Clip: 80728853 + AnimationController: 0 IsActive: true Scripts: ~ - EID: 218 @@ -4842,7 +4850,7 @@ IsActive: true Animator Component: Rig: 80500944 - Clip: 80500944 + AnimationController: 0 IsActive: true Scripts: ~ - EID: 220 @@ -4861,7 +4869,7 @@ IsActive: true Animator Component: Rig: 76715962 - Clip: 76715962 + AnimationController: 0 IsActive: true Scripts: ~ - EID: 198 diff --git a/Assets/Scripts/Gameplay/AIBehaviour/Implemented/LeafNodes/LeafSearch.cs b/Assets/Scripts/Gameplay/AIBehaviour/Implemented/LeafNodes/LeafSearch.cs index 2aebc3b7..4640b5eb 100644 --- a/Assets/Scripts/Gameplay/AIBehaviour/Implemented/LeafNodes/LeafSearch.cs +++ b/Assets/Scripts/Gameplay/AIBehaviour/Implemented/LeafNodes/LeafSearch.cs @@ -156,7 +156,7 @@ public partial class LeafSearch : BehaviourTreeNode //Draw a ray, succeed if ray is unobstructed Vector3 eyePosition = transform.GlobalPosition + eyeOffset; - BoxCollider playerCollider = player.GetValueOrDefault().GetComponent().GetCollisionShape(0); + Collider playerCollider = player.GetValueOrDefault().GetComponent(); if (playerCollider == null) { //Debug.Log("Failure: Player has no collider"); @@ -167,7 +167,7 @@ public partial class LeafSearch : BehaviourTreeNode } //Ray destination to target the centre of the player's collider instead of transform position //Since transform position is often the raccoon's base and the ray needs to hit somewhere higher to be more reliable - Vector3 rayDestination = plrT.GlobalPosition + plrT.GlobalScale * playerCollider.PositionOffset; + Vector3 rayDestination = plrT.GlobalPosition + plrT.GlobalScale * playerCollider.GetCollisionShape(0).PositionOffset; Ray sightRay = new Ray(eyePosition, rayDestination - eyePosition); RaycastHit sightRayHit = Physics.Raycast(sightRay, false, (ushort)65535)[0]; //As of November 2022, RaycastHit contains only the FIRST object hit by diff --git a/Assets/Scripts/Gameplay/Item/SC_Item.cs b/Assets/Scripts/Gameplay/Item/SC_Item.cs index b315ab08..be28bb5a 100644 --- a/Assets/Scripts/Gameplay/Item/SC_Item.cs +++ b/Assets/Scripts/Gameplay/Item/SC_Item.cs @@ -86,12 +86,17 @@ public class Item : Script if (returnBack && !dontReturn) { + if (rb) + { + rb.LinearVelocity = Vector3.Zero; + rb.AngularVelocity = Vector3.Zero; + rb.ClearForces(); + rb.ClearTorque(); + } + if(transform) transform.LocalPosition = firstPostion; - if (rb) - rb.LinearVelocity = Vector3.Zero; - returnBack = false; } diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index bd35af76..921f6f80 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -280,7 +280,7 @@ namespace SHADE if (arm->lookAtCameraOrigin) - CameraLookAt(camera, camera.position + arm->GetTargetOffset()); + CameraLookAt(camera, camera.position + tOffset); } From f706bd818895512ee3f9dae285e0f6bdbd2d2359 Mon Sep 17 00:00:00 2001 From: Glence Date: Thu, 9 Mar 2023 21:19:00 +0800 Subject: [PATCH 61/69] updated level 1 &3 to have tree --- Assets/Scenes/Level1.shade | 2719 +++++++++++++++++++++++++++++++++++- Assets/Scenes/Level3.shade | 2531 ++++++++++++++++++++++++++++++++- 2 files changed, 5240 insertions(+), 10 deletions(-) diff --git a/Assets/Scenes/Level1.shade b/Assets/Scenes/Level1.shade index 9fcbf7ce..5a6d52fb 100644 --- a/Assets/Scenes/Level1.shade +++ b/Assets/Scenes/Level1.shade @@ -16,7 +16,7 @@ - EID: 85 Name: EnvironmentMaster IsActive: true - NumberOfChildren: 8 + NumberOfChildren: 9 Components: ~ Scripts: ~ - EID: 84 @@ -4117,6 +4117,2715 @@ Rotation Offset: {x: 0, y: 0, z: 0} IsActive: true Scripts: ~ +- EID: 517 + Name: Exterior + IsActive: true + NumberOfChildren: 4 + Components: + Transform Component: + Translate: {x: -1.01231074, y: 0, z: -2.86974525} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 1.30016053, y: 1, z: 1.03591442} + IsActive: true + Scripts: ~ +- EID: 295 + Name: Fences + IsActive: true + NumberOfChildren: 21 + Components: + Transform Component: + Translate: {x: 0, y: 0, z: 0} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Scripts: ~ +- EID: 276 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1, y: 0, z: -10} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 0.75, y: 0.75, z: 0.75} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65811 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 6.5, y: 0, z: -0.75} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749885261, y: 0.75, z: 0.749885261} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 277 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 4.75, y: 0, z: -10} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 0.75, y: 0.75, z: 0.75} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 278 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 6.5, y: 0, z: -4.5} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749958098, y: 0.75, z: 0.749958098} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 279 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 6.5, y: 0, z: -8.25} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749971926, y: 0.75, z: 0.749971926} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 280 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -2.75, y: 0, z: -10} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 0.75, y: 0.75, z: 0.75} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 281 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -6.5, y: 0, z: -10} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 0.75, y: 0.75, z: 0.75} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 282 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -8.25, y: 0, z: -8.25} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.74998349, y: 0.75, z: 0.74998349} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 283 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -8.25, y: 0, z: -4.5} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749970615, y: 0.75, z: 0.749970615} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 284 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -8.25, y: 0, z: -0.75} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749959767, y: 0.75, z: 0.749959767} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 285 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -8.25, y: 0, z: 3} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749949992, y: 0.75, z: 0.749949992} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 286 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -8.25, y: 0, z: 6.75} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749939382, y: 0.75, z: 0.749939382} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 287 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -8.25, y: 0, z: 10.5} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749930501, y: 0.75, z: 0.749930501} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 288 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -6.5, y: 0, z: 12.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 0.749930501, y: 0.75, z: 0.749930501} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 289 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.63078785, y: 0, z: 12.25} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 0.749930501, y: 0.75, z: 0.749930501} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 290 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.76748997, y: 0, z: 12.25} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 0.749930501, y: 0.75, z: 0.749930501} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 291 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 4.75, y: 0, z: 12.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 0.749930501, y: 0.75, z: 0.749930501} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 292 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 6.5, y: 0, z: 10.5} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749919176, y: 0.75, z: 0.749919176} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 293 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 6.5, y: 0, z: 6.75} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749905586, y: 0.75, z: 0.749905586} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 294 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 6.5, y: 0, z: 3} + Rotate: {x: 0, y: 1.57079601, z: 0} + Scale: {x: 0.749896526, y: 0.75, z: 0.749896526} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 504 + Name: Exterior_FenceFivepiece + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.9147172, y: 0, z: 12.25} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 0.749930501, y: 0.75, z: 0.749930501} + IsActive: true + Renderable Component: + Mesh: 145842965 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 437 + Name: Trees + IsActive: true + NumberOfChildren: 14 + Components: ~ + Scripts: ~ +- EID: 65842 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 10.1952591, y: 0, z: 10.7309589} + Rotate: {x: 0, y: 1.9471432, z: 0} + Scale: {x: 0.749998093, y: 0.75, z: 0.749998093} + IsActive: true + Scripts: ~ +- EID: 297 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999917, y: 0, z: 1.25000107} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 298 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999964, y: 0, z: -0.999999106} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 299 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.50000006, y: 0, z: 1.00000012} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 300 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000167, y: 0, z: -0.75000006} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 301 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.49999928, y: 0, z: -0.499999076} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 302 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.7500006, y: 0, z: -0.999998152} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 303 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.25000146, y: 0, z: -0.75000006} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 304 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000072, y: 0, z: -1.24999821} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 305 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999917, y: 0, z: 1.25000107} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 307 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -14.3396883, y: 1.02942158e-06, z: 3.45037246} + Rotate: {x: -0, y: -1.55548823, z: 0} + Scale: {x: 0.946743906, y: 0.947038352, z: 0.946743906} + IsActive: true + Scripts: ~ +- EID: 308 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 309 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999964, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 310 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999911, y: 0, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 311 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000024, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 312 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000024, y: 0, z: -0.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 313 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000012, y: 0, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 314 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250002086, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 315 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.74999928, y: 0, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 316 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 317 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 7.0228982, y: 0, z: 14.5601959} + Rotate: {x: 0, y: 0.723479152, z: 0} + Scale: {x: 0.75, y: 0.75, z: 0.75} + IsActive: true + Scripts: ~ +- EID: 318 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999905, y: 0, z: 1.24999952} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 319 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999952, y: 0, z: -1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 320 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.5, y: 0, z: 0.999998093} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 321 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000095, y: 0, z: -0.750000477} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 322 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.49999905, y: 0, z: -0.500001431} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 323 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000048, y: 0, z: -1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 324 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250000954, y: 0, z: -0.750000954} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 325 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.74999905, y: 0, z: -1.25000143} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 326 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999905, y: 0, z: 1.24999952} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 327 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 1.25, y: 0, z: 14.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 0.75, y: 0.75, z: 0.75} + IsActive: true + Scripts: ~ +- EID: 328 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 329 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000012, y: 0, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 330 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000119, y: 0, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 331 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 332 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000048, y: 0, z: -0.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 333 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75, y: 0, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 334 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999881, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 335 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000048, y: 0, z: -1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 336 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 337 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -3.74656153, y: 5.05771936e-07, z: 15.2930593} + Rotate: {x: 0, y: -0.566242754, z: 0} + Scale: {x: 0.749999821, y: 0.75, z: 0.749999821} + IsActive: true + Scripts: ~ +- EID: 338 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999976, y: 0, z: 1.25000167} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 339 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999952, y: 0, z: -0.999999881} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 340 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000954, y: 0, z: 1.00000238} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 341 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000048, y: 0, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 342 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 0, z: -0.499999404} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 343 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75, y: 0, z: -0.999998808} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 344 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999523, y: 0, z: -0.749997854} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 345 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000095, y: 0, z: -1.24999714} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 346 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999976, y: 0, z: 1.25000167} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 347 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -9.52095222, y: 1.8582007e-07, z: -12.4267845} + Rotate: {x: -0, y: -2.5559175, z: 0} + Scale: {x: 0.749932706, y: 0.75, z: 0.749932706} + IsActive: true + Scripts: ~ +- EID: 348 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000095, y: 0, z: 1.25000143} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 349 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000095, y: 0, z: -0.999999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 350 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500001907, y: 0, z: 1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 351 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999952, y: 0, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 352 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000095, y: 0, z: -0.499999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 353 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000095, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 354 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.25, y: 0, z: -0.749998569} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 355 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75, y: 0, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 356 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000095, y: 0, z: 1.25000143} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 357 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -3.85509062, y: 1.903868e-07, z: -13.8841438} + Rotate: {x: 0, y: 2.91411972, z: 0} + Scale: {x: 0.749867201, y: 0.75, z: 0.749867201} + IsActive: true + Scripts: ~ +- EID: 358 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: 0, z: 1.25000083} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 359 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000048, y: 0, z: -0.999998808} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 360 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000954, y: 0, z: 1.00000167} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 361 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999976, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 362 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000048, y: 0, z: -0.499998808} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 363 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.74999952, y: 0, z: -0.999998927} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 364 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999046, y: 0, z: -0.749997973} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 365 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000143, y: 0, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 366 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: 0, z: 1.25000083} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 367 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 1.08703649, y: 1.755852e-07, z: -13.769515} + Rotate: {x: -0, y: -2.83319044, z: 0} + Scale: {x: 0.749745905, y: 0.75, z: 0.749745905} + IsActive: true + Scripts: ~ +- EID: 368 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108564e-14, z: 1.24999857} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 369 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000036, y: -1.42108564e-14, z: -1.00000179} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 370 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999672, y: -1.42108564e-14, z: 0.999998927} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 371 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999976, y: -1.42108564e-14, z: -0.750001252} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 372 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000024, y: -1.42108564e-14, z: -0.500000834} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 373 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000012, y: -1.42108564e-14, z: -1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 374 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999776, y: -1.42108564e-14, z: -0.750001192} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 375 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000024, y: -1.42108564e-14, z: -1.2500006} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 376 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108564e-14, z: 1.24999857} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 377 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 7.25601864, y: 1.55680326e-07, z: -11.2872229} + Rotate: {x: 0, y: 2.30721998, z: 0} + Scale: {x: 0.749779522, y: 0.75, z: 0.749779522} + IsActive: true + Scripts: ~ +- EID: 378 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108547e-14, z: 1.25000048} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 379 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000048, y: -1.42108547e-14, z: -1.00000048} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 380 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999523, y: -1.42108547e-14, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 381 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999952, y: -1.42108547e-14, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 382 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000048, y: -1.42108547e-14, z: -0.500000477} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 383 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.74999952, y: -1.42108547e-14, z: -0.999999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 384 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999523, y: -1.42108547e-14, z: -0.749999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 385 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75, y: -1.42108547e-14, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 386 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108547e-14, z: 1.25000048} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 387 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 4.38531399, y: 1.85469574e-07, z: -15.6559658} + Rotate: {x: 0, y: 2.89864969, z: 0} + Scale: {x: 0.802338541, y: 0.802574933, z: 0.802338541} + IsActive: true + Scripts: ~ +- EID: 388 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000072, y: 2.84217094e-14, z: 1.24999976} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 389 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000095, y: 2.84217094e-14, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 390 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000954, y: 2.84217094e-14, z: 1.00000107} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 391 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999905, y: 2.84217094e-14, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 392 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 2.84217094e-14, z: -0.50000155} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 393 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.74999857, y: 2.84217094e-14, z: -0.999999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 394 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999523, y: 2.84217094e-14, z: -0.750000596} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 395 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000072, y: 2.84217094e-14, z: -1.25000167} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 396 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000072, y: 2.84217094e-14, z: 1.24999976} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 397 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 10.1465569, y: 1.39389343e-07, z: -6.44067621} + Rotate: {x: 0, y: 1.53019583, z: 0} + Scale: {x: 0.802350819, y: 0.802574933, z: 0.802350819} + IsActive: true + Scripts: ~ +- EID: 398 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108547e-14, z: 1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 399 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.2499994, y: -1.42108547e-14, z: -1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 400 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999583, y: -1.42108547e-14, z: 0.999997139} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 401 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000048, y: -1.42108547e-14, z: -0.750000954} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 402 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.49999976, y: -1.42108547e-14, z: -0.500000954} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 403 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000012, y: -1.42108547e-14, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 404 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250000358, y: -1.42108547e-14, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 405 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.74999976, y: -1.42108547e-14, z: -1.25000191} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 406 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108547e-14, z: 1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 407 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -11.3042955, y: 1.0311652e-06, z: -5.21996689} + Rotate: {x: -0, y: 1.85743773, z: 0} + Scale: {x: 0.802347541, y: 0.802574933, z: 0.802347541} + IsActive: true + Scripts: ~ +- EID: 408 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 409 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999952, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 410 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000238, y: 0, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 411 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999952, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 412 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 0, z: -0.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 413 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 414 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250001431, y: 0, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 415 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000048, y: 0, z: -1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 416 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 417 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -11.8055868, y: 1.02849719e-06, z: -0.449734211} + Rotate: {x: 0, y: -1.17325497, z: 0} + Scale: {x: 0.802348375, y: 0.802574933, z: 0.802348375} + IsActive: true + Scripts: ~ +- EID: 418 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 419 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25, y: 0, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 420 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999523, y: 0, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 421 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000048, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 422 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.49999952, y: 0, z: -0.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 423 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000024, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 424 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250002384, y: 0, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 425 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.74999952, y: 0, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 426 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 427 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -10.6890984, y: 1.0175379e-06, z: 5.88018131} + Rotate: {x: 0, y: -1.55548835, z: 0} + Scale: {x: 0.80234766, y: 0.802574933, z: 0.80234766} + IsActive: true + Scripts: ~ +- EID: 428 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: 1.13686838e-13, z: 1.25000191} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 429 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999988, y: 1.13686838e-13, z: -0.999998093} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 430 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000358, y: 1.13686838e-13, z: 1.00000191} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 431 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25, y: 1.13686838e-13, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 432 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000048, y: 1.13686838e-13, z: -0.499999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 433 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.74999976, y: 1.13686838e-13, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 434 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250001878, y: 1.13686838e-13, z: -0.749998093} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 435 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000048, y: 1.13686838e-13, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 436 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: 1.13686838e-13, z: 1.25000191} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 448 + Name: BushCluster + IsActive: true + NumberOfChildren: 10 + Components: + Transform Component: + Translate: {x: 0, y: 0, z: -9.27025223} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Scripts: ~ +- EID: 438 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 5.81465149, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 439 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.331082046, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65976 + Name: Exterior_Bush03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.06180131, y: 0, z: 0.439988136} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 144928031 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 441 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -7.09583855, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 442 + Name: Exterior_Bush03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -4.03810406, y: 0, z: 0.439988136} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 144928031 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 443 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 4.52796364, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 444 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -2.52529955, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 445 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -5.5497098, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 516 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.79356122, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 447 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.18613672, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 515 + Name: BushCluster + IsActive: true + NumberOfChildren: 10 + Components: + Transform Component: + Translate: {x: 0, y: 0, z: 11.2170467} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Scripts: ~ +- EID: 514 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 5.81465149, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 513 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.331082046, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 512 + Name: Exterior_Bush03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.06180131, y: 0, z: 0.439988136} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 144928031 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 511 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -7.09583855, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 510 + Name: Exterior_Bush03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -4.03810406, y: 0, z: 0.439988136} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 144928031 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 509 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 4.52796364, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 508 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -2.52529955, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 507 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -5.5497098, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 506 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.79356122, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 505 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.18613672, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ - EID: 236 Name: ====GameManager==== IsActive: true @@ -4299,8 +7008,6 @@ Enabled: true Score: 50 currCategory: 1 - returnBack: false - firstPostion: [0, 0, 0] density: 1 dontReturn: false soundDistance: 10 @@ -4353,8 +7060,6 @@ Enabled: true Score: 500 currCategory: 2 - returnBack: false - firstPostion: [0, 0, 0] density: 1 dontReturn: false soundDistance: 10 @@ -4407,8 +7112,6 @@ Enabled: true Score: 10 currCategory: 0 - returnBack: false - firstPostion: [0, 0, 0] density: 1 dontReturn: false soundDistance: 10 @@ -4461,8 +7164,6 @@ Enabled: true Score: 10 currCategory: 0 - returnBack: false - firstPostion: [0, 0, 0] density: 1 dontReturn: false soundDistance: 10 diff --git a/Assets/Scenes/Level3.shade b/Assets/Scenes/Level3.shade index 20918ecd..16375e8e 100644 --- a/Assets/Scenes/Level3.shade +++ b/Assets/Scenes/Level3.shade @@ -31,7 +31,7 @@ - EID: 449 Name: Enviroment IsActive: true - NumberOfChildren: 13 + NumberOfChildren: 14 Components: ~ Scripts: ~ - EID: 78 @@ -5792,6 +5792,2535 @@ Rotation Offset: {x: 0, y: 0, z: 0} IsActive: true Scripts: ~ +- EID: 457 + Name: Exterior + IsActive: true + NumberOfChildren: 3 + Components: + Transform Component: + Translate: {x: 0, y: 0, z: 0} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 2.61762547, y: 1, z: 1.02465701} + IsActive: true + Scripts: ~ +- EID: 437 + Name: Trees + IsActive: true + NumberOfChildren: 15 + Components: ~ + Scripts: ~ +- EID: 65842 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 10.1952591, y: 0, z: 10.7309589} + Rotate: {x: 0, y: 1.9471432, z: 0} + Scale: {x: 0.749998093, y: 0.75, z: 0.749998093} + IsActive: true + Scripts: ~ +- EID: 297 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999917, y: 0, z: 1.25000107} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 298 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999964, y: 0, z: -0.999999106} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 299 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.50000006, y: 0, z: 1.00000012} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 300 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000167, y: 0, z: -0.75000006} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 301 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.49999928, y: 0, z: -0.499999076} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 302 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.7500006, y: 0, z: -0.999998152} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 303 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.25000146, y: 0, z: -0.75000006} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 304 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000072, y: 0, z: -1.24999821} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 305 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999917, y: 0, z: 1.25000107} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 307 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -7.94254541, y: 9.95685014e-07, z: 10.1371737} + Rotate: {x: -0, y: -0.934578657, z: 0} + Scale: {x: 0.946708083, y: 0.947038352, z: 0.946708083} + IsActive: true + Scripts: ~ +- EID: 308 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 309 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999964, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 310 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999911, y: 0, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 311 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000024, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 312 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000024, y: 0, z: -0.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 313 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000012, y: 0, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 314 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250002086, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 315 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.74999928, y: 0, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 316 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 317 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 7.0228982, y: 0, z: 14.5601959} + Rotate: {x: 0, y: 0.723479152, z: 0} + Scale: {x: 0.75, y: 0.75, z: 0.75} + IsActive: true + Scripts: ~ +- EID: 318 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999905, y: 0, z: 1.24999952} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 319 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999952, y: 0, z: -1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 320 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.5, y: 0, z: 0.999998093} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 321 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000095, y: 0, z: -0.750000477} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 322 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.49999905, y: 0, z: -0.500001431} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 323 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000048, y: 0, z: -1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 324 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250000954, y: 0, z: -0.750000954} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 325 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.74999905, y: 0, z: -1.25000143} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 326 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999905, y: 0, z: 1.24999952} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 327 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 1.25, y: 0, z: 14.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 0.75, y: 0.75, z: 0.75} + IsActive: true + Scripts: ~ +- EID: 328 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 329 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000012, y: 0, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 330 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000119, y: 0, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 331 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 332 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000048, y: 0, z: -0.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 333 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75, y: 0, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 334 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999881, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 335 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000048, y: 0, z: -1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 336 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 337 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -3.74656153, y: 5.05771936e-07, z: 15.2930593} + Rotate: {x: 0, y: -0.566242754, z: 0} + Scale: {x: 0.749999821, y: 0.75, z: 0.749999821} + IsActive: true + Scripts: ~ +- EID: 338 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999976, y: 0, z: 1.25000167} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 339 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999952, y: 0, z: -0.999999881} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 340 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000954, y: 0, z: 1.00000238} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 341 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000048, y: 0, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 342 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 0, z: -0.499999404} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 343 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75, y: 0, z: -0.999998808} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 344 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999523, y: 0, z: -0.749997854} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 345 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000095, y: 0, z: -1.24999714} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 346 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.99999976, y: 0, z: 1.25000167} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 347 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -8.91827679, y: 1.92174866e-07, z: -11.9713926} + Rotate: {x: 0, y: -2.5559175, z: 0} + Scale: {x: 0.749962032, y: 0.75, z: 0.749962032} + IsActive: true + Scripts: ~ +- EID: 348 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000095, y: 0, z: 1.25000143} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 349 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000095, y: 0, z: -0.999999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 350 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500001907, y: 0, z: 1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 351 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999952, y: 0, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 352 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000095, y: 0, z: -0.499999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 353 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000095, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 354 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.25, y: 0, z: -0.749998569} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 355 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75, y: 0, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 356 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000095, y: 0, z: 1.25000143} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 357 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -3.85509062, y: 1.903868e-07, z: -13.8841438} + Rotate: {x: 0, y: 2.91411972, z: 0} + Scale: {x: 0.749867201, y: 0.75, z: 0.749867201} + IsActive: true + Scripts: ~ +- EID: 460 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: 0, z: 1.25000083} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 359 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000048, y: 0, z: -0.999998808} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 360 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000954, y: 0, z: 1.00000167} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 361 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999976, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 362 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000048, y: 0, z: -0.499998808} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 363 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.74999952, y: 0, z: -0.999998927} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 364 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999046, y: 0, z: -0.749997973} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 365 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000143, y: 0, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 366 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: 0, z: 1.25000083} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 367 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 1.08703649, y: 1.755852e-07, z: -12.8693295} + Rotate: {x: 0, y: -2.83319044, z: 0} + Scale: {x: 0.749794662, y: 0.75, z: 0.749794662} + IsActive: true + Scripts: ~ +- EID: 368 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108564e-14, z: 1.24999857} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 369 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000036, y: -1.42108564e-14, z: -1.00000179} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 370 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999672, y: -1.42108564e-14, z: 0.999998927} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 371 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999976, y: -1.42108564e-14, z: -0.750001252} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 372 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000024, y: -1.42108564e-14, z: -0.500000834} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 373 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000012, y: -1.42108564e-14, z: -1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 374 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999776, y: -1.42108564e-14, z: -0.750001192} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 375 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000024, y: -1.42108564e-14, z: -1.2500006} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 376 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108564e-14, z: 1.24999857} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 377 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 7.25601864, y: 1.55680326e-07, z: -11.2872229} + Rotate: {x: 0, y: 2.30721998, z: 0} + Scale: {x: 0.749779522, y: 0.75, z: 0.749779522} + IsActive: true + Scripts: ~ +- EID: 378 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108547e-14, z: 1.25000048} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 379 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000048, y: -1.42108547e-14, z: -1.00000048} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 380 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999523, y: -1.42108547e-14, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 381 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999952, y: -1.42108547e-14, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 382 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000048, y: -1.42108547e-14, z: -0.500000477} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 383 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.74999952, y: -1.42108547e-14, z: -0.999999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 384 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999523, y: -1.42108547e-14, z: -0.749999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 459 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75, y: -1.42108547e-14, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 458 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108547e-14, z: 1.25000048} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 456 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 4.38531399, y: 1.85469574e-07, z: -15.6559658} + Rotate: {x: 0, y: 2.89864969, z: 0} + Scale: {x: 0.802338541, y: 0.802574933, z: 0.802338541} + IsActive: true + Scripts: ~ +- EID: 455 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000072, y: 2.84217094e-14, z: 1.24999976} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 454 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25000095, y: 2.84217094e-14, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 453 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000954, y: 2.84217094e-14, z: 1.00000107} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 452 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999905, y: 2.84217094e-14, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 451 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 2.84217094e-14, z: -0.50000155} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 450 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.74999857, y: 2.84217094e-14, z: -0.999999523} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 444 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.249999523, y: 2.84217094e-14, z: -0.750000596} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 443 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000072, y: 2.84217094e-14, z: -1.25000167} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 442 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000072, y: 2.84217094e-14, z: 1.24999976} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 441 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: 12.1907196, y: 1.36533259e-07, z: -6.39172125} + Rotate: {x: -0, y: 2.54303765, z: 0} + Scale: {x: 0.802329481, y: 0.802574933, z: 0.802329481} + IsActive: true + Scripts: ~ +- EID: 440 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108547e-14, z: 1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 439 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.2499994, y: -1.42108547e-14, z: -1.00000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 438 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999583, y: -1.42108547e-14, z: 0.999997139} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 436 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000048, y: -1.42108547e-14, z: -0.750000954} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 435 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.49999976, y: -1.42108547e-14, z: -0.500000954} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 434 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000012, y: -2.84217094e-14, z: -1} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 433 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250000358, y: -1.42108547e-14, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 432 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.74999976, y: -1.42108547e-14, z: -1.25000191} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 431 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: -1.42108547e-14, z: 1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 430 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -10.3963461, y: 1.0311652e-06, z: -5.21996689} + Rotate: {x: 0, y: 1.85743773, z: 0} + Scale: {x: 0.802347541, y: 0.802574933, z: 0.802347541} + IsActive: true + Scripts: ~ +- EID: 429 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 428 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999952, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 427 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000238, y: 0, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 426 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.24999952, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 425 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 0, z: -0.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 424 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 423 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250001431, y: 0, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 422 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000048, y: 0, z: -1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 421 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 420 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -11.8055868, y: 1.02849719e-06, z: -0.449734211} + Rotate: {x: 0, y: -1.17325497, z: 0} + Scale: {x: 0.802348375, y: 0.802574933, z: 0.802348375} + IsActive: true + Scripts: ~ +- EID: 418 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 419 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.25, y: 0, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 296 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999523, y: 0, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 273 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000048, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 272 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.49999952, y: 0, z: -0.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 271 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000024, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 270 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250002384, y: 0, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 269 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.74999952, y: 0, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 268 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2, y: 0, z: 1.25} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 267 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -10.6890984, y: 1.0175379e-06, z: 5.88018131} + Rotate: {x: 0, y: -1.55548835, z: 0} + Scale: {x: 0.80234766, y: 0.802574933, z: 0.80234766} + IsActive: true + Scripts: ~ +- EID: 266 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: 1.13686838e-13, z: 1.25000191} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 265 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999988, y: 1.13686838e-13, z: -0.999998093} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 264 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.500000358, y: 1.13686838e-13, z: 1.00000191} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 263 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25, y: 1.13686838e-13, z: -0.749999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 262 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000048, y: 1.13686838e-13, z: -0.499999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 261 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.74999976, y: 1.13686838e-13, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 260 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250001878, y: 1.13686838e-13, z: -0.749998093} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 259 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.75000048, y: 1.13686838e-13, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 258 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000048, y: 1.13686838e-13, z: 1.25000191} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65831 + Name: TreeCluster + IsActive: true + NumberOfChildren: 9 + Components: + Transform Component: + Translate: {x: -13.7129259, y: 1.02942158e-06, z: 3.45037246} + Rotate: {x: 0, y: -1.55548823, z: 0} + Scale: {x: 0.946770251, y: 0.947038352, z: 0.946770251} + IsActive: true + Scripts: ~ +- EID: 65830 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65829 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.24999964, y: 0, z: -0.999999046} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65828 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.499999911, y: 0, z: 1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65827 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -3.25000024, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65826 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.50000024, y: 0, z: -0.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65825 + Name: Exterior_Tree02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.75000012, y: 0, z: -1} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 140386412 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65824 + Name: Exterior_Tree03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -0.250002086, y: 0, z: -0.75} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 146337876 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65823 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.74999928, y: 0, z: -1.24999905} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 65822 + Name: Exterior_Tree01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.00000024, y: 0, z: 1.25000095} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 150881323 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 257 + Name: BushCluster + IsActive: true + NumberOfChildren: 10 + Components: + Transform Component: + Translate: {x: 0, y: 0, z: -9.27025223} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Scripts: ~ +- EID: 256 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 5.81465149, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 255 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.331082046, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 254 + Name: Exterior_Bush03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.06180131, y: 0, z: 0.439988136} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 144928031 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 253 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -7.09583855, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 252 + Name: Exterior_Bush03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -4.03810406, y: 0, z: 0.439988136} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 144928031 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 251 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 4.52796364, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 250 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -2.52529955, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 249 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -5.5497098, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 248 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.79356122, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 247 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.18613672, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 246 + Name: BushCluster + IsActive: true + NumberOfChildren: 10 + Components: + Transform Component: + Translate: {x: 0, y: 0, z: 11.2170467} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Scripts: ~ +- EID: 245 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 5.81465149, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 244 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.331082046, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 243 + Name: Exterior_Bush03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -1.06180131, y: 0, z: 0.439988136} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 144928031 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 240 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -7.09583855, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 236 + Name: Exterior_Bush03 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -4.03810406, y: 0, z: 0.439988136} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 144928031 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 235 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 4.52796364, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 234 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -2.52529955, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 233 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -5.5497098, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 232 + Name: Exterior_Bush01 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 1.79356122, y: -4.76837158e-07, z: 0.386853218} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 143461339 + Material: 131956078 + IsActive: true + Scripts: ~ +- EID: 231 + Name: Exterior_Bush02 + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.18613672, y: 0, z: 0.392630577} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 136373407 + Material: 131956078 + IsActive: true + Scripts: ~ - EID: 553 Name: TweenManager IsActive: true From 57d1adb29203b7cc8f04102d1aa177bdcfdb811a Mon Sep 17 00:00:00 2001 From: Glence Date: Fri, 10 Mar 2023 00:16:38 +0800 Subject: [PATCH 62/69] animation for raccoon WIP --- Assets/Scenes/Level1.shade | 10 ++++++- .../Player/PlayerStates/UT_PlayerIdleState.cs | 7 ++++- .../Player/PlayerStates/UT_PlayerRunState.cs | 8 ++++- .../Player/PlayerStates/UT_PlayerWalkState.cs | 8 ++++- .../Gameplay/Player/SC_PlayerController.cs | 29 +++++++++++++++---- 5 files changed, 53 insertions(+), 9 deletions(-) diff --git a/Assets/Scenes/Level1.shade b/Assets/Scenes/Level1.shade index 5a6d52fb..8219b365 100644 --- a/Assets/Scenes/Level1.shade +++ b/Assets/Scenes/Level1.shade @@ -7591,7 +7591,7 @@ IsActive: true Renderable Component: Mesh: 149697411 - Material: 126974645 + Material: 128805346 IsActive: true RigidBody Component: Type: Dynamic @@ -7621,6 +7621,10 @@ Position Offset: {x: 0, y: 0.300000012, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 + IsActive: true Scripts: - Type: PlayerController Enabled: true @@ -7639,6 +7643,10 @@ heavyMultiper: 0.5 silhouettePlayer: 462 silhouetteBag: 465 + idleClip: 227450439 + walkClip: 229125027 + runClip: 228149757 + pickUpClip: 0 - Type: PickAndThrow Enabled: true throwForce: [8, 10, 8] diff --git a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerIdleState.cs b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerIdleState.cs index 144233a3..8c5044c0 100644 --- a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerIdleState.cs +++ b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerIdleState.cs @@ -3,13 +3,18 @@ using System; public class PlayerIdleState : BaseState { - public PlayerIdleState(StateMachine stateMachine) : base(stateMachine) + private AnimationClipAsset idleClip; + private Animator animator; + public PlayerIdleState(StateMachine stateMachine, Animator ani , AnimationClipAsset clip) : base(stateMachine) { stateName = "Idle State"; + idleClip = clip; + animator = ani; } public override void OnEnter() { //Debug.Log("WALK ENTER"); + animator.Play(idleClip); } public override void update() { diff --git a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs index 314f8950..0ff4be17 100644 --- a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs +++ b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs @@ -6,13 +6,19 @@ public class PlayerRunState : BaseState private float timer; private float delay = 0.25f; - public PlayerRunState(StateMachine stateMachine) : base(stateMachine) + private AnimationClipAsset runClip; + private Animator animator; + + public PlayerRunState(StateMachine stateMachine, Animator ani, AnimationClipAsset clip) : base(stateMachine) { stateName = "Run State"; + animator = ani; + runClip = clip; } public override void OnEnter() { //Debug.Log("WALK ENTER"); + animator.Play(runClip); } public override void update() { diff --git a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs index 1c0ef13a..5609825d 100644 --- a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs +++ b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs @@ -5,14 +5,20 @@ public class PlayerWalkState : BaseState { private float timer; private float delay = 0.5f; - public PlayerWalkState(StateMachine stateMachine) : base(stateMachine) + + private AnimationClipAsset walkClip; + private Animator animator; + public PlayerWalkState(StateMachine stateMachine, Animator ani, AnimationClipAsset clip) : base(stateMachine) { stateName = "Walk State"; + animator = ani; + walkClip = clip; } public override void OnEnter() { //Debug.Log("WALK ENTER"); timer = delay; + animator.Play(walkClip); } public override void update() { diff --git a/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs b/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs index 284b4cc1..dd59975f 100644 --- a/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs +++ b/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs @@ -82,6 +82,21 @@ public class PlayerController : Script public GameObject silhouetteBag; private Renderable silhouetteBagRend; + #region Serialized Fields + [SerializeField] + private AnimationClipAsset idleClip; + [SerializeField] + private AnimationClipAsset walkClip; + [SerializeField] + private AnimationClipAsset runClip; + [SerializeField] + private AnimationClipAsset pickUpClip; + #endregion + + #region Components + public Animator animator { get; private set; } + #endregion + protected override void awake() { //default setup @@ -98,18 +113,22 @@ public class PlayerController : Script //rigidbody check rb = GetComponent(); if (!rb) - Debug.LogError("RigidBody is NULL!"); + Debug.LogError("RigidBody is MISSING!"); //Transform check tranform = GetComponent(); if(!tranform) - Debug.LogError("tranform is NULL!"); + Debug.LogError("tranform is MISSING!"); + + animator = GetComponent(); + if (!animator) + Debug.LogError("Animator is MISSING!"); stateMachine = AddScript(); Dictionary dictionary = new Dictionary(); - dictionary.Add(typeof(PlayerIdleState), new PlayerIdleState(stateMachine)); - dictionary.Add(typeof(PlayerWalkState), new PlayerWalkState(stateMachine)); - dictionary.Add(typeof(PlayerRunState), new PlayerRunState(stateMachine)); + dictionary.Add(typeof(PlayerIdleState), new PlayerIdleState(stateMachine, animator , idleClip)); + dictionary.Add(typeof(PlayerWalkState), new PlayerWalkState(stateMachine, animator , walkClip)); + dictionary.Add(typeof(PlayerRunState), new PlayerRunState(stateMachine, animator, runClip)); dictionary.Add(typeof(PlayerJumpState), new PlayerJumpState(stateMachine)); dictionary.Add(typeof(PlayerFallState), new PlayerFallState(stateMachine)); dictionary.Add(typeof(PlayerLandState), new PlayerLandState(stateMachine)); From 089eb9de261eaca1d8aba027fcbccfaf8bf20798 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 10 Mar 2023 14:11:59 +0800 Subject: [PATCH 63/69] Fixed bug where C# Asset implicit bool conversion operators were internal --- Assets/Scripts/AnimTest.cs | 12 ++++++---- .../src/Assets/AnimationClipAsset.hxx | 21 +++++++++-------- .../src/Assets/AnimationControllerAsset.hxx | 23 ++++++++++--------- .../src/Assets/AnimationRigAsset.hxx | 21 +++++++++-------- SHADE_Managed/src/Assets/FontAsset.hxx | 21 +++++++++-------- SHADE_Managed/src/Assets/MaterialAsset.hxx | 21 +++++++++-------- SHADE_Managed/src/Assets/MeshAsset.hxx | 23 ++++++++++--------- 7 files changed, 76 insertions(+), 66 deletions(-) diff --git a/Assets/Scripts/AnimTest.cs b/Assets/Scripts/AnimTest.cs index 4ceccbe6..584d046f 100644 --- a/Assets/Scripts/AnimTest.cs +++ b/Assets/Scripts/AnimTest.cs @@ -34,19 +34,23 @@ namespace SHADE.Test // Play animations if (Input.GetKeyUp(Input.KeyCode.Equals)) { - playFunc(fullClip); + if (fullClip) + playFunc(fullClip); } else if (Input.GetKeyUp(Input.KeyCode.Alpha1)) { - playFunc(idleClip); + if (idleClip) + playFunc(idleClip); } else if (Input.GetKeyUp(Input.KeyCode.Alpha2)) { - playFunc(runClip); + if (runClip) + playFunc(runClip); } else if (Input.GetKeyUp(Input.KeyCode.Alpha3)) { - playFunc(pickUpClip); + if (pickUpClip) + playFunc(pickUpClip); } } #endregion diff --git a/SHADE_Managed/src/Assets/AnimationClipAsset.hxx b/SHADE_Managed/src/Assets/AnimationClipAsset.hxx index 5a8c7845..2a4e52b3 100644 --- a/SHADE_Managed/src/Assets/AnimationClipAsset.hxx +++ b/SHADE_Managed/src/Assets/AnimationClipAsset.hxx @@ -29,6 +29,17 @@ namespace SHADE /// public value struct AnimationClipAsset { + public: + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a AnimationClip is valid. + /// + /// Asset to check. + /// True if the Asset is valid. + static operator bool(AnimationClipAsset asset); + internal: /*-----------------------------------------------------------------------------*/ /* Properties */ @@ -57,16 +68,6 @@ namespace SHADE /// AssetID to the AnimationClip asset. AnimationClipAsset(AssetID AnimationClipId); - /*-----------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-----------------------------------------------------------------------------*/ - /// - /// Implicit conversion operator to enable checking if a AnimationClip is valid. - /// - /// Asset to check. - /// True if the Asset is valid. - static operator bool(AnimationClipAsset asset); - /*-----------------------------------------------------------------------------*/ /* Conversion Operators */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Assets/AnimationControllerAsset.hxx b/SHADE_Managed/src/Assets/AnimationControllerAsset.hxx index 1be74fb9..7dc3d3d7 100644 --- a/SHADE_Managed/src/Assets/AnimationControllerAsset.hxx +++ b/SHADE_Managed/src/Assets/AnimationControllerAsset.hxx @@ -28,7 +28,18 @@ namespace SHADE /// public value struct AnimationControllerAsset { - internal: + public: + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a AnimationController is valid. + /// + /// Asset to check. + /// True if the Asset is valid. + static operator bool(AnimationControllerAsset asset); + + internal: /*-----------------------------------------------------------------------------*/ /* Properties */ /*-----------------------------------------------------------------------------*/ @@ -56,16 +67,6 @@ namespace SHADE /// AssetID to the AnimationController asset. AnimationControllerAsset(AssetID AnimationControllerId); - /*-----------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-----------------------------------------------------------------------------*/ - /// - /// Implicit conversion operator to enable checking if a AnimationController is valid. - /// - /// Asset to check. - /// True if the Asset is valid. - static operator bool(AnimationControllerAsset asset); - /*-----------------------------------------------------------------------------*/ /* Conversion Operators */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Assets/AnimationRigAsset.hxx b/SHADE_Managed/src/Assets/AnimationRigAsset.hxx index be43b7f0..09964d31 100644 --- a/SHADE_Managed/src/Assets/AnimationRigAsset.hxx +++ b/SHADE_Managed/src/Assets/AnimationRigAsset.hxx @@ -28,6 +28,17 @@ namespace SHADE /// public value struct AnimationRigAsset { + public: + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a AnimationRig is valid. + /// + /// Asset to check. + /// True if the Asset is valid. + static operator bool(AnimationRigAsset asset); + internal: /*-----------------------------------------------------------------------------*/ /* Properties */ @@ -56,16 +67,6 @@ namespace SHADE /// AssetID to the AnimationRig asset. AnimationRigAsset(AssetID AnimationRigId); - /*-----------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-----------------------------------------------------------------------------*/ - /// - /// Implicit conversion operator to enable checking if a AnimationRig is valid. - /// - /// Asset to check. - /// True if the Asset is valid. - static operator bool(AnimationRigAsset asset); - /*-----------------------------------------------------------------------------*/ /* Conversion Operators */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Assets/FontAsset.hxx b/SHADE_Managed/src/Assets/FontAsset.hxx index 89239224..5c3b4e11 100644 --- a/SHADE_Managed/src/Assets/FontAsset.hxx +++ b/SHADE_Managed/src/Assets/FontAsset.hxx @@ -28,6 +28,17 @@ namespace SHADE /// public value struct FontAsset { + public: + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a Font is valid. + /// + /// Asset to check. + /// True if the Asset is valid. + static operator bool(FontAsset asset); + internal: /*-----------------------------------------------------------------------------*/ /* Properties */ @@ -56,16 +67,6 @@ namespace SHADE /// AssetID to the font asset. FontAsset(AssetID fontId); - /*-----------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-----------------------------------------------------------------------------*/ - /// - /// Implicit conversion operator to enable checking if a Font is valid. - /// - /// Asset to check. - /// True if the Asset is valid. - static operator bool(FontAsset asset); - /*-----------------------------------------------------------------------------*/ /* Conversion Operators */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Assets/MaterialAsset.hxx b/SHADE_Managed/src/Assets/MaterialAsset.hxx index 5380b286..a5a0909b 100644 --- a/SHADE_Managed/src/Assets/MaterialAsset.hxx +++ b/SHADE_Managed/src/Assets/MaterialAsset.hxx @@ -28,6 +28,17 @@ namespace SHADE /// public value struct MaterialAsset { + public: + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a Material is valid. + /// + /// Asset to check. + /// True if the Asset is valid. + static operator bool(MaterialAsset asset); + internal: /*-----------------------------------------------------------------------------*/ /* Properties */ @@ -56,16 +67,6 @@ namespace SHADE /// AssetID to the Material asset. MaterialAsset(AssetID MaterialId); - /*-----------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-----------------------------------------------------------------------------*/ - /// - /// Implicit conversion operator to enable checking if a Material is valid. - /// - /// Asset to check. - /// True if the Asset is valid. - static operator bool(MaterialAsset asset); - /*-----------------------------------------------------------------------------*/ /* Conversion Operators */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Assets/MeshAsset.hxx b/SHADE_Managed/src/Assets/MeshAsset.hxx index 26625c1a..63922d65 100644 --- a/SHADE_Managed/src/Assets/MeshAsset.hxx +++ b/SHADE_Managed/src/Assets/MeshAsset.hxx @@ -28,7 +28,18 @@ namespace SHADE /// public value struct MeshAsset { - internal: + public: + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a Mesh is valid. + /// + /// Asset to check. + /// True if the Asset is valid. + static operator bool(MeshAsset asset); + + internal: /*-----------------------------------------------------------------------------*/ /* Properties */ /*-----------------------------------------------------------------------------*/ @@ -56,16 +67,6 @@ namespace SHADE /// AssetID to the Mesh asset. MeshAsset(AssetID meshId); - /*-----------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-----------------------------------------------------------------------------*/ - /// - /// Implicit conversion operator to enable checking if a Mesh is valid. - /// - /// Asset to check. - /// True if the Asset is valid. - static operator bool(MeshAsset asset); - /*-----------------------------------------------------------------------------*/ /* Conversion Operators */ /*-----------------------------------------------------------------------------*/ From 8c0ad47921354512826977e677f38047054d7d7f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 10 Mar 2023 14:55:49 +0800 Subject: [PATCH 64/69] Added timescale for animation system --- Assets/Scenes/anim.shade | 4 +- Assets/Scripts/AnimTest.cs | 9 ++++ .../src/Animation/SHAnimationSystem.cpp | 1 + .../src/Animation/SHAnimationSystem.h | 17 +++++++ .../src/Graphics/AnimationSystem.cxx | 37 +++++++++++++++ .../src/Graphics/AnimationSystem.hxx | 47 +++++++++++++++++++ 6 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 SHADE_Managed/src/Graphics/AnimationSystem.cxx create mode 100644 SHADE_Managed/src/Graphics/AnimationSystem.hxx diff --git a/Assets/Scenes/anim.shade b/Assets/Scenes/anim.shade index 986195f6..5c9c7163 100644 --- a/Assets/Scenes/anim.shade +++ b/Assets/Scenes/anim.shade @@ -38,6 +38,7 @@ idleClip: 227450439 runClip: 229125027 pickUpClip: 219605278 + controlAniSys: true - EID: 1 Name: Default IsActive: true @@ -79,4 +80,5 @@ fullClip: 231416496 idleClip: 0 runClip: 0 - pickUpClip: 0 \ No newline at end of file + pickUpClip: 0 + controlAniSys: false \ No newline at end of file diff --git a/Assets/Scripts/AnimTest.cs b/Assets/Scripts/AnimTest.cs index 584d046f..b0761476 100644 --- a/Assets/Scripts/AnimTest.cs +++ b/Assets/Scripts/AnimTest.cs @@ -13,6 +13,8 @@ namespace SHADE.Test private AnimationClipAsset runClip; [SerializeField] private AnimationClipAsset pickUpClip; + [SerializeField] + private bool controlAniSys = false; #endregion #region Components @@ -52,6 +54,13 @@ namespace SHADE.Test if (pickUpClip) playFunc(pickUpClip); } + + // Play and pause + if (controlAniSys && Input.GetKeyUp(Input.KeyCode.Space)) + { + AnimationSystem.TimeScale = AnimationSystem.TimeScale > 0.0f ? 0.0f + : AnimationSystem.DefaultTimeScale; + } } #endregion } diff --git a/SHADE_Engine/src/Animation/SHAnimationSystem.cpp b/SHADE_Engine/src/Animation/SHAnimationSystem.cpp index 6f41e2aa..e38d2287 100644 --- a/SHADE_Engine/src/Animation/SHAnimationSystem.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationSystem.cpp @@ -32,6 +32,7 @@ namespace SHADE void SHAnimationSystem::UpdateRoutine::Execute(double dt) noexcept { auto& animators = SHComponentManager::GetDense(); + dt *= reinterpret_cast(system)->TimeScale; for (auto& animator : animators) { animator.Update(dt); diff --git a/SHADE_Engine/src/Animation/SHAnimationSystem.h b/SHADE_Engine/src/Animation/SHAnimationSystem.h index 9c2cd073..fd972e47 100644 --- a/SHADE_Engine/src/Animation/SHAnimationSystem.h +++ b/SHADE_Engine/src/Animation/SHAnimationSystem.h @@ -42,6 +42,23 @@ namespace SHADE void Execute(double dt) noexcept override final; }; + /*---------------------------------------------------------------------------------*/ + /* Constants */ + /*---------------------------------------------------------------------------------*/ + /// + /// Default time scale used by the system. + /// + static constexpr double DEFAULT_TIME_SCALE = 1.0; + + /*---------------------------------------------------------------------------------*/ + /* Public Data Members */ + /*---------------------------------------------------------------------------------*/ + /// + /// Used by the system to multiply the given delta time to scale the animation + /// speed. + /// + double TimeScale = DEFAULT_TIME_SCALE; + /*---------------------------------------------------------------------------------*/ /* Constructors */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Graphics/AnimationSystem.cxx b/SHADE_Managed/src/Graphics/AnimationSystem.cxx new file mode 100644 index 00000000..8ed11c28 --- /dev/null +++ b/SHADE_Managed/src/Graphics/AnimationSystem.cxx @@ -0,0 +1,37 @@ +/************************************************************************************//*! +\file AnimationSystem.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 10, 2023 +\brief Contains the definition of the functions of the managed AnimationSystem + static class. + + Note: This file is written in C++17/CLI. + +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. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "AnimationSystem.hxx" +// External Dependencies +#include "ECS_Base/Managers/SHSystemManager.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + double AnimationSystem::TimeScale::get() + { + auto sys = SHSystemManager::GetSystem(); + return sys->TimeScale; + } + void AnimationSystem::TimeScale::set(double value) + { + auto sys = SHSystemManager::GetSystem(); + sys->TimeScale = value; + } +} diff --git a/SHADE_Managed/src/Graphics/AnimationSystem.hxx b/SHADE_Managed/src/Graphics/AnimationSystem.hxx new file mode 100644 index 00000000..fe3bcd59 --- /dev/null +++ b/SHADE_Managed/src/Graphics/AnimationSystem.hxx @@ -0,0 +1,47 @@ +/************************************************************************************//*! +\file AnimationSystem.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Mar 10, 2023 +\brief Contains the definition of the managed AnimationSystem static class. + + Note: This file is written in C++17/CLI. + +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 + +#include "Animation/SHAnimationSystem.h" + +namespace SHADE +{ + /// + /// Static class for interfacing with the animation system. + /// + public ref class AnimationSystem abstract sealed + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constants */ + /*-----------------------------------------------------------------------------*/ + /// + /// Default time scale used by the system. + /// + literal double DefaultTimeScale = SHAnimationSystem::DEFAULT_TIME_SCALE; + + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Used by the system to multiply the given delta time to scale the animation + /// speed. + /// + static property double TimeScale + { + double get(); + void set(double value); + } + }; +} From 0173e7c302b03d079076caa8b88fba86089d2779 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 10 Mar 2023 16:21:18 +0800 Subject: [PATCH 65/69] Fixed RawAnimInspector changing any specific animation clip's values, causing a change in all animation clips' values --- .../RawAnimationInspector/SHRawAnimInspector.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index 563c0f60..6fb53eb5 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -158,8 +158,11 @@ namespace SHADE if (SHEditorUI::CollapsingHeader("Existing Animation Clips")) { ImGui::Indent(); + int i = 0; for (auto animClip : childAnimClips) { + ImGui::PushID(i++); + bool changed = false; std::optional animClipName = SHResourceManager::GetAssetName(animClip); @@ -197,6 +200,8 @@ namespace SHADE SHAssetManager::SaveAsset(assetId.value()); } } + + ImGui::PopID(); } // Extra separator if there is more than one From 9b9cf1a1bbe45c403df5cdf67904faa4a13f6ad1 Mon Sep 17 00:00:00 2001 From: Glence Date: Fri, 10 Mar 2023 16:26:52 +0800 Subject: [PATCH 66/69] WIP for animatons --- Assets/Scenes/Level1.shade | 26 +++++-- .../Player/PlayerStates/UT_PlayerIdleState.cs | 22 ++++-- .../Player/PlayerStates/UT_PlayerRunState.cs | 13 ++-- .../Player/PlayerStates/UT_PlayerWalkState.cs | 27 +++++-- .../Gameplay/Player/SC_PlayerAnimations.cs | 75 +++++++++++++++++++ .../Player/SC_PlayerAnimations.cs.shmeta | 3 + .../Gameplay/Player/SC_PlayerController.cs | 33 +++----- Assets/Scripts/UI/SC_PauseMenu.cs | 2 + Assets/Scripts/Utility/UT_BaseSate.cs | 12 +-- SHADE_Engine/src/Editor/SHEditor.cpp | 7 +- 10 files changed, 158 insertions(+), 62 deletions(-) create mode 100644 Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs create mode 100644 Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs.shmeta diff --git a/Assets/Scenes/Level1.shade b/Assets/Scenes/Level1.shade index 8219b365..ca74f938 100644 --- a/Assets/Scenes/Level1.shade +++ b/Assets/Scenes/Level1.shade @@ -2419,7 +2419,7 @@ Components: Transform Component: Translate: {x: 0, y: 0, z: 0} - Rotate: {x: -1.48352981, y: 0, z: 0} + Rotate: {x: -7.50001717, y: 1.39999998, z: -3.50001717} Scale: {x: 1, y: 1, z: 1} IsActive: true Renderable Component: @@ -7643,10 +7643,6 @@ heavyMultiper: 0.5 silhouettePlayer: 462 silhouetteBag: 465 - idleClip: 227450439 - walkClip: 229125027 - runClip: 228149757 - pickUpClip: 0 - Type: PickAndThrow Enabled: true throwForce: [8, 10, 8] @@ -7660,6 +7656,20 @@ Enabled: true currentStateName: Idle State currentAnimName: "" + - Type: PlayerAnimations + Enabled: true + playerIdleClip: 227450439 + playerWalkClip: 229125027 + playerRunClip: 228149757 + playerPickUpClip: 219605278 + playerCarryIdleClip: 231128260 + playerCarryWalkClip: 227671720 + playerThrowClip: 223399345 + playerJumpStartClip: 223009573 + playerJumpLoopClip: 230974023 + playerJumpEndClip: 228134756 + silhouettePlayer: 51000 + silhouetteBag: 51000 - EID: 65733 Name: HoldingPoint IsActive: true @@ -7722,7 +7732,11 @@ IsActive: true Renderable Component: Mesh: 144838771 - Material: 123745521 + Material: 117923942 + IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 IsActive: true Scripts: ~ - EID: 462 diff --git a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerIdleState.cs b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerIdleState.cs index 8c5044c0..589db690 100644 --- a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerIdleState.cs +++ b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerIdleState.cs @@ -3,18 +3,28 @@ using System; public class PlayerIdleState : BaseState { - private AnimationClipAsset idleClip; - private Animator animator; - public PlayerIdleState(StateMachine stateMachine, Animator ani , AnimationClipAsset clip) : base(stateMachine) + private bool holdItem; + public PlayerIdleState(StateMachine stateMachine, bool hi) : base(stateMachine) { stateName = "Idle State"; - idleClip = clip; - animator = ani; + holdItem = hi; } public override void OnEnter() { //Debug.Log("WALK ENTER"); - animator.Play(idleClip); + if (PlayerAnimations.Instance) + { + if (!holdItem) + { + PlayerAnimations.Instance.playerAnimator.Play(PlayerAnimations.Instance.playerIdleClip); + PlayerAnimations.Instance.BagAnimator.Play(PlayerAnimations.Instance.playerIdleClip); + } + else + { + PlayerAnimations.Instance.playerAnimator.Play(PlayerAnimations.Instance.playerCarryIdleClip); + PlayerAnimations.Instance.BagAnimator.Play(PlayerAnimations.Instance.playerCarryIdleClip); + } + } } public override void update() { diff --git a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs index 0ff4be17..0c786c2d 100644 --- a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs +++ b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs @@ -6,19 +6,18 @@ public class PlayerRunState : BaseState private float timer; private float delay = 0.25f; - private AnimationClipAsset runClip; - private Animator animator; - - public PlayerRunState(StateMachine stateMachine, Animator ani, AnimationClipAsset clip) : base(stateMachine) + public PlayerRunState(StateMachine stateMachine) : base(stateMachine) { stateName = "Run State"; - animator = ani; - runClip = clip; } public override void OnEnter() { //Debug.Log("WALK ENTER"); - animator.Play(runClip); + if (PlayerAnimations.Instance) + { + PlayerAnimations.Instance.playerAnimator.Play(PlayerAnimations.Instance.playerRunClip); + PlayerAnimations.Instance.BagAnimator.Play(PlayerAnimations.Instance.playerRunClip); + } } public override void update() { diff --git a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs index 5609825d..98a0dd69 100644 --- a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs +++ b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs @@ -5,20 +5,33 @@ public class PlayerWalkState : BaseState { private float timer; private float delay = 0.5f; - - private AnimationClipAsset walkClip; - private Animator animator; - public PlayerWalkState(StateMachine stateMachine, Animator ani, AnimationClipAsset clip) : base(stateMachine) + private bool holdItem; + public PlayerWalkState(StateMachine stateMachine, bool hi) : base(stateMachine) { stateName = "Walk State"; - animator = ani; - walkClip = clip; + holdItem = hi; } public override void OnEnter() { //Debug.Log("WALK ENTER"); timer = delay; - animator.Play(walkClip); + if (PlayerAnimations.Instance) + { + if (!holdItem) + { + if(PlayerAnimations.Instance.playerWalkClip) + PlayerAnimations.Instance.playerAnimator.Play(PlayerAnimations.Instance.playerWalkClip); + if(PlayerAnimations.Instance.playerWalkClip) + PlayerAnimations.Instance.BagAnimator.Play(PlayerAnimations.Instance.playerWalkClip); + } + else + { + if(PlayerAnimations.Instance.playerCarryWalkClip) + PlayerAnimations.Instance.playerAnimator.Play(PlayerAnimations.Instance.playerCarryWalkClip); + if(PlayerAnimations.Instance.playerCarryWalkClip) + PlayerAnimations.Instance.BagAnimator.Play(PlayerAnimations.Instance.playerCarryWalkClip); + } + } } public override void update() { diff --git a/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs b/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs new file mode 100644 index 00000000..46ba8120 --- /dev/null +++ b/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs @@ -0,0 +1,75 @@ +using SHADE; +using System; +using System.Collections.Generic; + + +public class PlayerAnimations : Script +{ + #region Raccoon + [SerializeField] + public AnimationClipAsset playerIdleClip; // done + [SerializeField] + public AnimationClipAsset playerWalkClip; // done + [SerializeField] + public AnimationClipAsset playerRunClip; // done + [SerializeField] + public AnimationClipAsset playerPickUpClip; + [SerializeField] + public AnimationClipAsset playerCarryIdleClip; // done + [SerializeField] + public AnimationClipAsset playerCarryWalkClip; // done + [SerializeField] + public AnimationClipAsset playerThrowClip; + [SerializeField] + public AnimationClipAsset playerJumpStartClip; + [SerializeField] + public AnimationClipAsset playerJumpLoopClip; + [SerializeField] + public AnimationClipAsset playerJumpEndClip; + #endregion + + #region Animator + public Animator playerAnimator { get; private set; } + public Animator BagAnimator { get; private set; } + public Animator silhoPlayerAnimator { get; private set; } + public Animator silhoBagAnimator { get; private set; } + #endregion + + #region silhouette + public GameObject silhouettePlayer; + public GameObject silhouetteBag; + #endregion + + public static PlayerAnimations Instance { get; private set; } + + protected override void awake() + { + if (Instance != null && Instance != this) + RemoveScript(); + else + Instance = this; + + playerAnimator = GetComponent(); + if (!playerAnimator) + Debug.LogError("Player Animator is MISSING!"); + + BagAnimator = GetComponentInChildren(); + if (!BagAnimator) + Debug.LogError("Bag Animator is MISSING!"); + + silhoPlayerAnimator = silhouettePlayer.GetComponent(); + if (!silhoPlayerAnimator) + Debug.LogError("Silho Player Animator is MISSING!"); + + silhoBagAnimator = silhouetteBag.GetComponent(); + if (!silhoBagAnimator) + Debug.LogError("Silho Player Animator is MISSING!"); + } + + protected override void onDestroy() + { + if (Instance == this) + Instance = null; + } +} + diff --git a/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs.shmeta b/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs.shmeta new file mode 100644 index 00000000..b8cd1620 --- /dev/null +++ b/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs.shmeta @@ -0,0 +1,3 @@ +Name: SC_PlayerAnimations +ID: 159045981 +Type: 9 diff --git a/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs b/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs index dd59975f..ecde7698 100644 --- a/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs +++ b/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs @@ -32,7 +32,7 @@ public class PlayerController : Script private float delayTimer = 0.0f; [Tooltip("The current state fo the raccoon")] - public RaccoonStates currentState = RaccoonStates.IDLE; + public RaccoonStates currentState; //Movement variables============================================================ [Tooltip("Max vel for walking")] @@ -82,21 +82,6 @@ public class PlayerController : Script public GameObject silhouetteBag; private Renderable silhouetteBagRend; - #region Serialized Fields - [SerializeField] - private AnimationClipAsset idleClip; - [SerializeField] - private AnimationClipAsset walkClip; - [SerializeField] - private AnimationClipAsset runClip; - [SerializeField] - private AnimationClipAsset pickUpClip; - #endregion - - #region Components - public Animator animator { get; private set; } - #endregion - protected override void awake() { //default setup @@ -120,15 +105,11 @@ public class PlayerController : Script if(!tranform) Debug.LogError("tranform is MISSING!"); - animator = GetComponent(); - if (!animator) - Debug.LogError("Animator is MISSING!"); - stateMachine = AddScript(); Dictionary dictionary = new Dictionary(); - dictionary.Add(typeof(PlayerIdleState), new PlayerIdleState(stateMachine, animator , idleClip)); - dictionary.Add(typeof(PlayerWalkState), new PlayerWalkState(stateMachine, animator , walkClip)); - dictionary.Add(typeof(PlayerRunState), new PlayerRunState(stateMachine, animator, runClip)); + dictionary.Add(typeof(PlayerIdleState), new PlayerIdleState(stateMachine, holdItem)); + dictionary.Add(typeof(PlayerWalkState), new PlayerWalkState(stateMachine, holdItem)); + dictionary.Add(typeof(PlayerRunState), new PlayerRunState(stateMachine)); dictionary.Add(typeof(PlayerJumpState), new PlayerJumpState(stateMachine)); dictionary.Add(typeof(PlayerFallState), new PlayerFallState(stateMachine)); dictionary.Add(typeof(PlayerLandState), new PlayerLandState(stateMachine)); @@ -152,6 +133,12 @@ public class PlayerController : Script } } + protected override void start() + { + currentState = RaccoonStates.IDLE; + stateMachine.SetState(typeof(PlayerIdleState)); + } + protected override void lateUpdate() { } diff --git a/Assets/Scripts/UI/SC_PauseMenu.cs b/Assets/Scripts/UI/SC_PauseMenu.cs index 32b59a85..7dd528b0 100644 --- a/Assets/Scripts/UI/SC_PauseMenu.cs +++ b/Assets/Scripts/UI/SC_PauseMenu.cs @@ -50,6 +50,7 @@ public class PauseMenu : Script if (canvas) canvas.SetActive(false); Application.FixDeltaTime = Time.DefaultFixDeltaTime; + AnimationSystem.TimeScale = AnimationSystem.DefaultTimeScale; } }); } @@ -106,6 +107,7 @@ public class PauseMenu : Script if (canvas) canvas.SetActive(true); Application.FixDeltaTime = 0; + AnimationSystem.TimeScale = 0; } } diff --git a/Assets/Scripts/Utility/UT_BaseSate.cs b/Assets/Scripts/Utility/UT_BaseSate.cs index 521f5936..483a289b 100644 --- a/Assets/Scripts/Utility/UT_BaseSate.cs +++ b/Assets/Scripts/Utility/UT_BaseSate.cs @@ -15,17 +15,14 @@ public abstract class BaseState } public virtual void OnEnter() - { - } + {} public abstract void update(); public abstract void fixedUpdate(); public virtual void OnExit() - { - - } + {} public string GetStateName() { @@ -37,11 +34,6 @@ public abstract class BaseState return animationName; } - public virtual float GetAnimPercent() - { - return 1.0f; - } - public virtual void onCollisionEnter(CollisionInfo info) { } diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 268af73e..c8ba7b68 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -113,14 +113,15 @@ namespace SHADE SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + //Add popup windows SHEditorWindowManager::CreatePopupWindow(); From 1d171710c534aae60db609623fbd06528909b5ea Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 10 Mar 2023 17:11:09 +0800 Subject: [PATCH 67/69] Fixed bug where sub assets were not being loading properly Implemented saving of parent container when cips are changed for animation --- .../Asset Types/SHAnimClipContainerAsset.h | 2 +- .../Libraries/Loaders/SHBinaryLoader.cpp | 19 ++++++------ SHADE_Engine/src/Assets/SHAssetManager.cpp | 30 +++++++++++++++---- .../SHRawAnimInspector.cpp | 4 +-- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h index 733119c0..28d3b697 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h @@ -31,6 +31,6 @@ namespace SHADE struct SH_API SHAnimClipContainerAsset final : SHAssetData { AssetID animRawDataAssetId; - std::vector clips{}; + std::vector clips{}; }; } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp index b59f6807..119bd9aa 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp @@ -66,19 +66,19 @@ namespace SHADE for (auto const& clip : anim.clips) { - uint32_t charCount {static_cast(clip.name.size())}; + uint32_t charCount {static_cast(clip->name.size())}; file.write( reinterpret_cast(&charCount), sizeof(uint32_t) ); file.write( - clip.name.data(), + clip->name.data(), charCount ); file.write( - reinterpret_cast(&clip.firstIndex), + reinterpret_cast(&clip->firstIndex), sizeof(uint32_t) * 2 ); } @@ -99,28 +99,29 @@ namespace SHADE reinterpret_cast(&size), sizeof(uint32_t) ); + data->clips.resize(size); - for (auto i{0}; i < size; ++i) + for (auto& clip : data->clips) { - auto& clip {data->clips.emplace_back()}; + clip = new SHAnimClipAsset; uint32_t charCount; file.read( reinterpret_cast(&charCount), sizeof(uint32_t) ); - clip.name.resize(charCount); + clip->name.resize(charCount); file.read( - clip.name.data(), + clip->name.data(), charCount ); file.read( - reinterpret_cast(&clip.firstIndex), + reinterpret_cast(&clip->firstIndex), sizeof(uint32_t) * 2 ); - clip.animRawDataAssetId = data->animRawDataAssetId; + clip->animRawDataAssetId = data->animRawDataAssetId; } result = data; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index fcd9c5b1..8cddaf2c 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -314,10 +314,10 @@ namespace SHADE .parent = parent }; auto& newClip {animContainer->clips.emplace_back()}; - newClip.name = name; + newClip->name = name; assetCollection.emplace(id, asset); assetCollection[parent].subAssets.push_back(&assetCollection[id]); - assetData.emplace(id, &newClip); + assetData.emplace(id, newClip); return id; } @@ -639,6 +639,25 @@ namespace SHADE assetData.emplace(asset.id, data); } + switch (asset.type) + { + case AssetType::ANIM_CONTAINER: + { + auto container = reinterpret_cast(data); + for (auto i{0}; i < asset.subAssets.size(); ++i) + { + assetData.emplace( + asset.subAssets[i]->id, + container->clips[i] + ); + } + } + break; + + default: + break; + } + return data; } @@ -646,7 +665,6 @@ namespace SHADE { auto const& parent = assetCollection[asset.parent]; auto parentData = loaders[static_cast(parent.type)]->Load(parent.path); - if (parentData == nullptr) { SHLOG_ERROR("[Asset Manager] Unable to load asset into memory: {}\n", parent.path.string()); @@ -676,7 +694,7 @@ namespace SHADE { assetData.emplace( parent.subAssets[i]->id, - &parentContainer->clips[i] + parentContainer->clips[i] ); } } @@ -859,7 +877,7 @@ namespace SHADE for(auto& clip : data->clips) { SHAsset subAsset{ - .name = clip.name, + .name = clip->name, .id = GenerateAssetID(AssetType::ANIM_CLIP), .type = AssetType::ANIM_CLIP, .isSubAsset = true, @@ -869,7 +887,7 @@ namespace SHADE assetCollection.emplace(subAsset.id, subAsset); assetCollection[newAsset.id].subAssets.push_back(&assetCollection[subAsset.id]); - assetData.emplace(subAsset.id, &clip); + assetData.emplace(subAsset.id, clip); } SHAssetMetaHandler::WriteMetaData(assetCollection[newAsset.id]); diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index 6fb53eb5..332bf6e9 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -194,10 +194,10 @@ namespace SHADE auto assetId = SHResourceManager::GetAssetID(animClip); if (assetId.has_value()) { - auto animAsset = SHAssetManager::GetData(assetId.value()); + auto const animAsset = SHAssetManager::GetData(assetId.value()); animAsset->firstIndex = firstIndex; animAsset->lastIndex = endIndex; - SHAssetManager::SaveAsset(assetId.value()); + SHAssetManager::SaveAsset(containerAsset->id); } } From a3318d500d6081d8e326ea1f44e8c34cf59565e0 Mon Sep 17 00:00:00 2001 From: Glence Date: Fri, 10 Mar 2023 17:21:49 +0800 Subject: [PATCH 68/69] change old audio code --- .../Gameplay/Player/PlayerStates/UT_PlayerRunState.cs | 3 ++- .../Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs | 5 +++-- Assets/Scripts/Gameplay/Player/SC_PlayerController.cs | 5 ++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs index 0c786c2d..dc39c045 100644 --- a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs +++ b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerRunState.cs @@ -1,4 +1,5 @@ using SHADE; +using SHADE_Scripting.Audio; using System; public class PlayerRunState : BaseState @@ -26,7 +27,7 @@ public class PlayerRunState : BaseState if (timer > delay) { - Audio.PlaySFXOnce2D("event:/Raccoon/raccoon_footsteps"); + AudioHandler.audioClipHandlers["footsteps"].Play(); timer = 0; } } diff --git a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs index 98a0dd69..12cdc860 100644 --- a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs +++ b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerWalkState.cs @@ -1,4 +1,5 @@ using SHADE; +using SHADE_Scripting.Audio; using System; public class PlayerWalkState : BaseState @@ -39,8 +40,8 @@ public class PlayerWalkState : BaseState timer += Time.DeltaTimeF; if (timer > delay) - { - Audio.PlaySFXOnce2D("event:/Raccoon/raccoon_footsteps"); + { + AudioHandler.audioClipHandlers["footsteps"].Play(); timer = 0; } } diff --git a/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs b/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs index ecde7698..78b92b84 100644 --- a/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs +++ b/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs @@ -1,6 +1,7 @@ using SHADE; using System; -using System.Collections.Generic; +using System.Collections.Generic; +using SHADE_Scripting.Audio; using static Item; public class PlayerController : Script @@ -131,6 +132,8 @@ public class PlayerController : Script silhouetteBagRend = silhouetteBag.GetComponent(); silhouetteBagRend.Material.SetProperty("data.offset", 0.1f); } + + AudioHandler.audioClipHandlers["footsteps"] = Audio.CreateAudioClip("event:/Raccoon/raccoon_footsteps"); } protected override void start() From 3f4674e38f2bf18c017e031e0b336549d96d5409 Mon Sep 17 00:00:00 2001 From: Glence Date: Fri, 10 Mar 2023 17:25:41 +0800 Subject: [PATCH 69/69] minor fix --- Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs b/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs index 46ba8120..22b87d55 100644 --- a/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs +++ b/Assets/Scripts/Gameplay/Player/SC_PlayerAnimations.cs @@ -57,11 +57,17 @@ public class PlayerAnimations : Script if (!BagAnimator) Debug.LogError("Bag Animator is MISSING!"); - silhoPlayerAnimator = silhouettePlayer.GetComponent(); + if(!silhouettePlayer) + silhoPlayerAnimator = silhouettePlayer.GetComponent(); + else + Debug.LogError("Silho Player is MISSING!"); if (!silhoPlayerAnimator) Debug.LogError("Silho Player Animator is MISSING!"); - silhoBagAnimator = silhouetteBag.GetComponent(); + if(!silhouetteBag) + silhoBagAnimator = silhouetteBag.GetComponent(); + else + Debug.LogError("Silho bag is MISSING!"); if (!silhoBagAnimator) Debug.LogError("Silho Player Animator is MISSING!"); }