diff --git a/code/AssetLib/3DS/3DSConverter.cpp b/code/AssetLib/3DS/3DSConverter.cpp index 7d1c24cd6..50600ba10 100644 --- a/code/AssetLib/3DS/3DSConverter.cpp +++ b/code/AssetLib/3DS/3DSConverter.cpp @@ -643,11 +643,17 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, } // Allocate storage for children - pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size(); + const unsigned int size = static_cast(pcIn->mChildren.size()); + + pcOut->mNumChildren = size; + if (size == 0) { + return; + } + pcOut->mChildren = new aiNode *[pcIn->mChildren.size()]; // Recursively process all children - const unsigned int size = static_cast(pcIn->mChildren.size()); + for (unsigned int i = 0; i < size; ++i) { pcOut->mChildren[i] = new aiNode(); pcOut->mChildren[i]->mParent = pcOut; diff --git a/code/AssetLib/COB/COBLoader.cpp b/code/AssetLib/COB/COBLoader.cpp index f0899bddd..6c85edfc9 100644 --- a/code/AssetLib/COB/COBLoader.cpp +++ b/code/AssetLib/COB/COBLoader.cpp @@ -372,9 +372,11 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi } // add children recursively - nd->mChildren = new aiNode *[root.temp_children.size()](); - for (const Node *n : root.temp_children) { - (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd; + if (!root.temp_children.empty()) { + nd->mChildren = new aiNode *[root.temp_children.size()](); + for (const Node *n : root.temp_children) { + (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd; + } } return nd; diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index fd54c63f4..d9718685d 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -357,12 +357,12 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) if (nodes.empty()) { parent->mNumChildren = 0; parent->mChildren = nullptr; - } - - parent->mChildren = new aiNode *[nodes.size()](); - parent->mNumChildren = static_cast(nodes.size()); - for (unsigned int i = 0; i < nodes.size(); ++i) { - parent->mChildren[i] = nodes[i].mOwnership.release(); + } else { + parent->mChildren = new aiNode *[nodes.size()](); + parent->mNumChildren = static_cast(nodes.size()); + for (unsigned int i = 0; i < nodes.size(); ++i) { + parent->mChildren[i] = nodes[i].mOwnership.release(); + } } } diff --git a/code/AssetLib/SMD/SMDLoader.cpp b/code/AssetLib/SMD/SMDLoader.cpp index 1eac5d934..5d7c8f94a 100644 --- a/code/AssetLib/SMD/SMDLoader.cpp +++ b/code/AssetLib/SMD/SMDLoader.cpp @@ -400,8 +400,12 @@ void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent) { } } + // nothing to do + if (pcNode->mNumChildren == 0) + return; + // now allocate the output array - pcNode->mChildren = new aiNode*[pcNode->mNumChildren]; + pcNode->mChildren = new aiNode *[pcNode->mNumChildren]; // and fill all subnodes unsigned int qq( 0 ); diff --git a/code/PostProcessing/ValidateDataStructure.cpp b/code/PostProcessing/ValidateDataStructure.cpp index 8441b48be..bd62e6c90 100644 --- a/code/PostProcessing/ValidateDataStructure.cpp +++ b/code/PostProcessing/ValidateDataStructure.cpp @@ -891,6 +891,9 @@ void ValidateDSProcess::Validate(const aiNode *pNode) { ReportError("aiNode \"%s\" child %i \"%s\" parent is someone else: \"%s\"", pNode->mName.C_Str(), i, pChild->mName.C_Str(), parentName); } } + } else if (pNode->mChildren) { + ReportError("aiNode::mChildren is not nullptr for empty node %s (aiNode::mNumChildren is %i)", + nodeName, pNode->mNumChildren); } }