Fixed crash caused by loading more than one SHRig

This commit is contained in:
Kah Wei 2023-01-29 15:39:48 +08:00
parent 1472823dc0
commit 3f1a25c95b
5 changed files with 73 additions and 12 deletions

View File

@ -23,7 +23,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------------*/
SHRig::SHRig(const SHRigAsset& asset)
SHRig::SHRig(const SHRigAsset& asset, SHResourceLibrary<SHRigNode>& nodeStore)
{
// Don't bother if empty
if (asset.root == nullptr)
@ -33,13 +33,47 @@ namespace SHADE
}
// Do a recursive depth first traversal to populate the rig
rootNode = recurseCreateNode(asset, asset.root);
rootNode = recurseCreateNode(asset, asset.root, nodeStore);
if (rootNode)
{
globalInverseMatrix = SHMatrix::Inverse(rootNode->TransformMatrix);
}
}
SHRig::SHRig(SHRig&& rhs)
: rootNode { rhs.rootNode }
, 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 = {};
}
SHRig::~SHRig()
{
// Unload all nodes
for (auto node : nodes)
{
if (node)
node.Free();
}
nodes.clear();
}
SHRig& SHRig::operator=(SHRig&& rhs)
{
rootNode = rhs.rootNode;
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 = {};
return *this;
}
/*-----------------------------------------------------------------------------------*/
/* Usage Functions */
/*-----------------------------------------------------------------------------------*/
@ -79,7 +113,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------------*/
Handle<SHRigNode> SHRig::recurseCreateNode(const SHRigAsset& asset, const SHRigNodeAsset* sourceNode)
Handle<SHRigNode> SHRig::recurseCreateNode(const SHRigAsset& asset, const SHRigNodeAsset* sourceNode, SHResourceLibrary<SHRigNode>& nodeStore)
{
// Construct the node
auto newNode = nodeStore.Create();
@ -106,7 +140,7 @@ namespace SHADE
continue;
// Recursively create children
auto childNode = recurseCreateNode(asset, child); // Not sure why this works but it is required for
auto childNode = recurseCreateNode(asset, child, nodeStore); // Not sure why this works but it is required for
newNode->Children.emplace_back(childNode); // the emplace_back operation to not crash
}

View File

@ -53,19 +53,43 @@ namespace SHADE
};
/// <summary>
///
/// Represents an animation skeletal rig for a model.
/// </summary>
class SH_API SHRig
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors */
/* Constructors/Destructors */
/*---------------------------------------------------------------------------------*/
/// <summary>
///
/// Constructs a rig from a SHRigAsset.
/// </summary>
/// <param name="asset"></param>
explicit SHRig(const SHRigAsset& asset);
/// <param name="asset">
/// SHRigAsset to load.
/// </param>
/// <param name="nodeStore">
/// Reference to a ResourceLibrary to use to create the rig's nodes.
/// </param>
explicit SHRig(const SHRigAsset& asset, SHResourceLibrary<SHRigNode>& nodeStore);
/// <summary>
/// Move Constructor
/// </summary>
/// <param name="rhs>SHRig to move from.</param>
SHRig(SHRig&& rhs);
/// <summary>
/// Default destructor.
/// </summary>
~SHRig();
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Move assignment operator.
/// </summary>
/// <param name="rhs>SHRig to move from.</param>
/// <returns>Reference to this object.</returns>
SHRig& operator=(SHRig&& rhs);
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
@ -114,11 +138,10 @@ namespace SHADE
std::vector<Handle<SHRigNode>> nodes;
std::unordered_map<Handle<SHRigNode>, int> nodeIndexMap;
SHMatrix globalInverseMatrix;
SHResourceLibrary<SHRigNode> nodeStore;
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHRigNode> recurseCreateNode(const SHRigAsset& asset, const SHRigNodeAsset* sourceNode);
Handle<SHRigNode> recurseCreateNode(const SHRigAsset& asset, const SHRigNodeAsset* sourceNode, SHResourceLibrary<SHRigNode>& nodeStore);
};
}

View File

@ -20,6 +20,7 @@ namespace SHADE
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHResourceHub SHResourceManager::resourceHub;
SHResourceLibrary<SHRigNode> SHResourceManager::rigNodeStore;
std::unordered_map<std::type_index, std::unordered_map<AssetID, Handle<void>>> SHResourceManager::handlesMap;
std::unordered_map<std::type_index, SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
std::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;

View File

@ -13,6 +13,7 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes
#include <unordered_map>
// Project Includes
#include "SH_API.h"
#include "SHResourceLibrary.h"
@ -36,6 +37,7 @@ namespace SHADE
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMaterial;
struct SHRigNode;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
@ -176,6 +178,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
// Handles
static SHResourceHub resourceHub;
static SHResourceLibrary<SHRigNode> rigNodeStore;
static std::unordered_map<std::type_index, AssetHandleMap> handlesMap;
static std::unordered_map<std::type_index, HandleAssetMap> assetIdMap;
static std::unordered_map<std::type_index, std::function<void(AssetID)>> typedFreeFuncMap;

View File

@ -353,7 +353,7 @@ namespace SHADE
else if constexpr (std::is_same_v<ResourceType, SHRig>)
{
loadedAssetData.emplace_back(assetId);
return resourceHub.Create<ResourceType>(assetData.rig);
return resourceHub.Create<ResourceType>(assetData.rig, rigNodeStore);
}
else if constexpr (std::is_same_v<ResourceType, SHAnimationClip>)
{