diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 923fb876..25a42a53 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -71,7 +71,7 @@ namespace SHADE Play(); // Set to initial pose - if (rig && rig->GetRootNode()) + if (rig && !rig->GetRootNodes().empty()) { updateCurrentAnimatorState(currClip, 0.0f); } @@ -124,7 +124,7 @@ namespace SHADE std::fill(boneMatrices.begin(), boneMatrices.end(), SHMatrix::Identity); // Do not do anything if is not playing or there's nothing to animate - if (!rig || !rig->GetRootNode()) + if (!rig || rig->GetRootNodes().empty()) return; // We want to still display a paused pose, so we only prevent progression @@ -274,7 +274,7 @@ namespace SHADE void SHAnimatorComponent::updateCurrentAnimatorState(Handle clip, float playbackTime) { // Nothing to animate - if (!clip || !rig || !rig->GetRootNode()) + if (!clip || !rig || rig->GetRootNodes().empty()) return; // Check that we have animation data @@ -286,7 +286,10 @@ namespace SHADE } void SHAnimatorComponent::updatePoseWithClip(Handle clip, float poseTime) { - updatePoseWithClip(poseTime, clip->GetRawAnimation(), rig->GetRootNode(), SHMatrix::Identity); + for (auto rootNode : rig->GetRootNodes()) + { + updatePoseWithClip(poseTime, clip->GetRawAnimation(), rootNode, SHMatrix::Identity); + } } void SHAnimatorComponent::updatePoseWithClip(float poseTime, Handle rawAnimData, Handle node, const SHMatrix& parentMatrix) diff --git a/SHADE_Engine/src/Animation/SHRig.cpp b/SHADE_Engine/src/Animation/SHRig.cpp index f6fad3d5..05d8b4d9 100644 --- a/SHADE_Engine/src/Animation/SHRig.cpp +++ b/SHADE_Engine/src/Animation/SHRig.cpp @@ -33,22 +33,21 @@ namespace SHADE } // Do a recursive depth first traversal to populate the rig - rootNode = recurseCreateNode(asset, asset.root, nodeStore); + auto rootNode = recurseCreateNode(asset, asset.root, nodeStore); if (rootNode) { - globalInverseMatrix = SHMatrix::Inverse(rootNode->TransformMatrix); + rootNodes.emplace_back(rootNode); } } SHRig::SHRig(SHRig&& rhs) - : rootNode { rhs.rootNode } + : rootNodes { std::move(rhs.rootNodes) } , nodeNames { std::move(rhs.nodeNames) } , nodesByName { std::move(rhs.nodesByName) } , nodes { std::move(rhs.nodes) } , nodeIndexMap { std::move(rhs.nodeIndexMap) } - , globalInverseMatrix { std::move(rhs.globalInverseMatrix) } { - rhs.rootNode = {}; + rhs.nodes = {}; } SHRig::~SHRig() { @@ -63,17 +62,17 @@ namespace SHADE SHRig& SHRig::operator=(SHRig&& rhs) { - rootNode = rhs.rootNode; + rootNodes = std::move(rhs.rootNodes); nodeNames = std::move(rhs.nodeNames); nodesByName = std::move(rhs.nodesByName); nodes = std::move(rhs.nodes); nodeIndexMap = std::move(rhs.nodeIndexMap); - globalInverseMatrix = std::move(rhs.globalInverseMatrix); - rhs.rootNode = {}; + rhs.rootNodes = {}; return *this; } + /*-----------------------------------------------------------------------------------*/ /* Usage Functions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Animation/SHRig.h b/SHADE_Engine/src/Animation/SHRig.h index ae198317..9a9a7106 100644 --- a/SHADE_Engine/src/Animation/SHRig.h +++ b/SHADE_Engine/src/Animation/SHRig.h @@ -104,11 +104,10 @@ namespace SHADE /// const std::string& GetName(Handle node) const noexcept; /// - /// Retrieves the root node of the rig. + /// Retrieves a read only reference to the root nodes of this rig. /// - /// Handle to the root node of the rig. - Handle GetRootNode() const noexcept { return rootNode; } - const SHMatrix& GetGlobalInverseMatrix() const noexcept { return globalInverseMatrix; } + /// Vector of handles to the root node of the rig. + const std::vector>& GetRootNodes() const noexcept { return rootNodes; } /// /// Retrieves a node via name. /// @@ -132,12 +131,11 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ - Handle rootNode; + std::vector> rootNodes; std::unordered_map, std::string> nodeNames; std::unordered_map> nodesByName; std::vector> nodes; std::unordered_map, int> nodeIndexMap; - SHMatrix globalInverseMatrix; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp index 724c31a0..749f6180 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp @@ -822,6 +822,16 @@ namespace SHADE instance->setVolume(volume); } + bool AudioClip::GetDestroyOnSceneExit() + { + return destroyOnSceneExit; + } + + void AudioClip::SetDestroyOnSceneExit(bool value) + { + destroyOnSceneExit = value; + } + SHEventHandle SHAudioSystem::onStop(SHEventPtr onStopEvent) { StopAllSounds(); @@ -841,8 +851,11 @@ namespace SHADE auto [begin, end] = audioClipLibrary.GetDenseAccess(); for (auto& it = begin; it != end; ++it) { - it->instance->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT); - it->instance->release(); + if(it->destroyOnSceneExit) + { + it->instance->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT); + it->instance->release(); + } } return onSceneExitEvent->handle; diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h index 7e2fac11..1c285b62 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h @@ -37,10 +37,13 @@ namespace SHADE float GetParameterValue(const char* paramName); float GetVolume(); void SetVolume(float volume); + bool GetDestroyOnSceneExit(); + void SetDestroyOnSceneExit(bool value); friend class SHAudioSystem; private: FMOD::Studio::EventInstance* instance = nullptr; EntityID transformRef = MAX_EID; + bool destroyOnSceneExit = true; }; class SH_API SHAudioSystem : public SHSystem diff --git a/SHADE_Managed/src/Audio/AudioClip.cxx b/SHADE_Managed/src/Audio/AudioClip.cxx index 062b543e..c4cad5cf 100644 --- a/SHADE_Managed/src/Audio/AudioClip.cxx +++ b/SHADE_Managed/src/Audio/AudioClip.cxx @@ -44,6 +44,16 @@ namespace SHADE return SHResourceManagerInterface::GetAssetID(Convert::ToNative(audioClipInstHandle)).value_or(INVALID_ASSET_ID); } + bool AudioClipHandler::DestroyOnSceneExit::get() + { + return NativeObject->GetDestroyOnSceneExit(); + } + + void AudioClipHandler::DestroyOnSceneExit::set(bool value) + { + NativeObject->SetDestroyOnSceneExit(value); + } + /*---------------------------------------------------------------------------------*/ /* Constructors/Destructor */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Audio/AudioClip.hxx b/SHADE_Managed/src/Audio/AudioClip.hxx index 317c5bad..a6c969db 100644 --- a/SHADE_Managed/src/Audio/AudioClip.hxx +++ b/SHADE_Managed/src/Audio/AudioClip.hxx @@ -54,6 +54,12 @@ namespace SHADE AssetID get(); } + property bool DestroyOnSceneExit + { + bool get(); + void set(bool value); + } + /*-----------------------------------------------------------------------------*/ /* Constructors/Destructor */ /*-----------------------------------------------------------------------------*/