Motion Matching: Fixed crash on empty KD-tree

Signed-off-by: Benjamin Jillich <jillich@amazon.com>
monroegm-disable-blank-issue-2
Benjamin Jillich 4 years ago
parent a01500eaaa
commit 83869d7064

@ -17,7 +17,7 @@
//! Enable in case you want to use the Eigen SDK Eigen::Matrix as base for the feature matrix (https://eigen.tuxfamily.org/) //! Enable in case you want to use the Eigen SDK Eigen::Matrix as base for the feature matrix (https://eigen.tuxfamily.org/)
//! In case Eigen is disabled, a small simple NxM wrapper class is provided by default. //! In case Eigen is disabled, a small simple NxM wrapper class is provided by default.
#define O3DE_USE_EIGEN //#define O3DE_USE_EIGEN
#define O3DE_MM_FLOATTYPE float #define O3DE_MM_FLOATTYPE float
#ifdef O3DE_USE_EIGEN #ifdef O3DE_USE_EIGEN

@ -48,11 +48,13 @@ namespace EMotionFX::MotionMatching
Clear(); Clear();
// Verify the dimensions. // Verify the dimensions.
// Going above a 20 dimensional tree would start eating up too much memory.
m_numDimensions = CalcNumDimensions(features); m_numDimensions = CalcNumDimensions(features);
if (m_numDimensions == 0 || m_numDimensions > 20)
// Going above a 48 dimensional tree would start eating up too much memory.
const size_t maxNumDimensions = 48;
if (m_numDimensions == 0 || m_numDimensions > maxNumDimensions)
{ {
AZ_Error("Motion Matching", false, "Cannot initialize KD-tree. KD-tree dimension (%d) has to be between 1 and 20. Please use Feature::SetIncludeInKdTree(false) on some features.", m_numDimensions); AZ_Error("Motion Matching", false, "Cannot initialize KD-tree. KD-tree dimension (%d) has to be between 1 and %zu. Please use Feature::SetIncludeInKdTree(false) on some features.", m_numDimensions, maxNumDimensions);
return false; return false;
} }
@ -203,6 +205,12 @@ namespace EMotionFX::MotionMatching
void KdTree::MergeSmallLeafNodesToParents() void KdTree::MergeSmallLeafNodesToParents()
{ {
// If the tree is empty or only has a single node, there is nothing to merge.
if (m_nodes.size() < 2)
{
return;
}
AZStd::vector<Node*> nodesToRemove; AZStd::vector<Node*> nodesToRemove;
for (Node* node : m_nodes) for (Node* node : m_nodes)
{ {
@ -410,7 +418,7 @@ namespace EMotionFX::MotionMatching
} }
else else
{ {
// We have both a left and right node, so we're not at a leaf yet. // We have either a left and right node, so we're not at a leaf yet.
if (curNode->m_leftNode) if (curNode->m_leftNode)
{ {
if (frameFloats[d] <= curNode->m_median) if (frameFloats[d] <= curNode->m_median)

@ -34,12 +34,10 @@ namespace EMotionFX::MotionMatching
size_t maxDepth=10, size_t maxDepth=10,
size_t minFramesPerLeaf=1000); size_t minFramesPerLeaf=1000);
/** //! Calculate the number of dimensions or values for the given feature set.
* Calculate the number of dimensions or values for the given feature set. //! Each feature might store one or multiple values inside the feature matrix and the number of
* Each feature might store one or multiple values inside the feature matrix and the number of //! values each feature holds varies with the feature type. This calculates the sum of the number of
* values each feature holds varies with the feature type. This calculates the sum of the number of //! values of the given feature set.
* values of the given feature set.
*/
static size_t CalcNumDimensions(const AZStd::vector<Feature*>& features); static size_t CalcNumDimensions(const AZStd::vector<Feature*>& features);
void Clear(); void Clear();

Loading…
Cancel
Save