From 78fe5e7f04c39698459d4c6dde0a4b01bbc7be36 Mon Sep 17 00:00:00 2001 From: Joe Schutte Date: Mon, 3 Sep 2018 11:33:56 -0700 Subject: [PATCH] Fix expensive memory allocation and memory copying occurring in obj files with a large number of meshes. --- code/ObjFileImporter.cpp | 43 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 2b6730e4e..cac0e8fa0 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -211,12 +211,29 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene } if (pModel->m_Objects.size() > 0) { + + unsigned int meshCount = 0; + unsigned int childCount = 0; + + for(size_t index = 0; index < pModel->m_Objects.size(); ++index) { + if(pModel->m_Objects[index] > 0) { + ++childCount; + meshCount += (unsigned int)pModel->m_Objects[index]->m_Meshes.size(); + } + } + + // Allocate space for the child nodes on the root node + pScene->mRootNode->mChildren = new aiNode*[ childCount ]; + // Create nodes for the whole scene std::vector MeshArray; + MeshArray.reserve(meshCount); for (size_t index = 0; index < pModel->m_Objects.size(); ++index) { createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray); } + ai_assert(pScene->mRootNode->mNumChildren == childCount); + // Create mesh pointer buffer for this scene if (pScene->mNumMeshes > 0) { pScene->mMeshes = new aiMesh*[MeshArray.size()]; @@ -287,9 +304,8 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile pNode->mName = pObject->m_strObjName; // If we have a parent node, store it - if( pParent != NULL ) { - appendChildToParentNode( pParent, pNode ); - } + ai_assert( NULL != pParent ); + appendChildToParentNode( pParent, pNode ); for ( size_t i=0; i< pObject->m_Meshes.size(); ++i ) { unsigned int meshId = pObject->m_Meshes[ i ]; @@ -442,8 +458,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, pMesh->mNumVertices = numIndices; if (pMesh->mNumVertices == 0) { throw DeadlyImportError( "OBJ: no vertices" ); - } else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) { - throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" ); + } else if (pMesh->mNumVertices > AI_MAX_VERTICES) { + throw DeadlyImportError( "OBJ: Too many vertices" ); } pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; @@ -770,25 +786,8 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) // Assign parent to child pChild->mParent = pParent; - // If already children was assigned to the parent node, store them in a - std::vector temp; - if (pParent->mChildren != NULL) - { - ai_assert( 0 != pParent->mNumChildren ); - for (size_t index = 0; index < pParent->mNumChildren; index++) - { - temp.push_back(pParent->mChildren [ index ] ); - } - delete [] pParent->mChildren; - } - // Copy node instances into parent node pParent->mNumChildren++; - pParent->mChildren = new aiNode*[ pParent->mNumChildren ]; - for (size_t index = 0; index < pParent->mNumChildren-1; index++) - { - pParent->mChildren[ index ] = temp [ index ]; - } pParent->mChildren[ pParent->mNumChildren-1 ] = pChild; }