update: replace some clear / push-back by resize( 0 ) / push_back to avoid redundat allocations.

Signed-off-by: Kim Kulling <kim.kulling@googlemail.com>
pull/309/head
Kim Kulling 2014-06-29 21:16:37 +02:00
parent 3bb815097f
commit 0856ff9659
1 changed files with 45 additions and 32 deletions

View File

@ -47,22 +47,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS #ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
using namespace Assimp; using namespace Assimp;
#include "OptimizeMeshes.h" #include "OptimizeMeshes.h"
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include "SceneCombiner.h" #include "SceneCombiner.h"
static const unsigned int NotSet = 0xffffffff;
static const unsigned int DeadBeef = 0xdeadbeef;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
OptimizeMeshesProcess::OptimizeMeshesProcess() OptimizeMeshesProcess::OptimizeMeshesProcess()
: pts (false) : pts (false)
, max_verts (0xffffffff) , max_verts( NotSet )
, max_faces (0xffffffff) , max_faces( NotSet ) {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
OptimizeMeshesProcess::~OptimizeMeshesProcess() OptimizeMeshesProcess::~OptimizeMeshesProcess() {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
@ -74,17 +80,17 @@ bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const
// That's a serious design flaw, consider redesign. // That's a serious design flaw, consider redesign.
if( 0 != (pFlags & aiProcess_OptimizeMeshes) ) { if( 0 != (pFlags & aiProcess_OptimizeMeshes) ) {
pts = (0 != (pFlags & aiProcess_SortByPType)); pts = (0 != (pFlags & aiProcess_SortByPType));
max_verts = (0 != (pFlags & aiProcess_SplitLargeMeshes)) ? 0xdeadbeef : max_verts; max_verts = ( 0 != ( pFlags & aiProcess_SplitLargeMeshes ) ) ? DeadBeef : max_verts;
return true; return true;
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup properties for the postprocessing step // Setup properties for the post-processing step
void OptimizeMeshesProcess::SetupProperties(const Importer* pImp) void OptimizeMeshesProcess::SetupProperties(const Importer* pImp)
{ {
if (max_verts == 0xdeadbeef /* magic hack */) { if( max_verts == DeadBeef /* magic hack */ ) {
max_faces = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES); max_faces = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
max_verts = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES); max_verts = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
} }
@ -104,35 +110,36 @@ void OptimizeMeshesProcess::Execute( aiScene* pScene)
mScene = pScene; mScene = pScene;
// need to clear persistent members from previous runs // need to clear persistent members from previous runs
merge_list.clear(); merge_list.resize( 0 );
output.clear(); output.resize( 0 );
// ensure we have the right sizes
merge_list.reserve(pScene->mNumMeshes); merge_list.reserve(pScene->mNumMeshes);
output.reserve(pScene->mNumMeshes); output.reserve(pScene->mNumMeshes);
// Prepare lookup tables // Prepare lookup tables
meshes.resize(pScene->mNumMeshes); meshes.resize(pScene->mNumMeshes);
FindInstancedMeshes(pScene->mRootNode); FindInstancedMeshes(pScene->mRootNode);
if (max_verts == 0xdeadbeef) /* undo the magic hack */ if( max_verts == DeadBeef ) /* undo the magic hack */
max_verts = 0xffffffff; max_verts = NotSet;
// ... instanced meshes are immediately processed and added to the output list // ... instanced meshes are immediately processed and added to the output list
for (unsigned int i = 0, n = 0; i < pScene->mNumMeshes;++i) { for (unsigned int i = 0, n = 0; i < pScene->mNumMeshes;++i) {
meshes[i].vertex_format = GetMeshVFormatUnique(pScene->mMeshes[i]); meshes[i].vertex_format = GetMeshVFormatUnique(pScene->mMeshes[i]);
if (meshes[i].instance_cnt > 1 && meshes[i].output_id == 0xffffffff) { if (meshes[i].instance_cnt > 1 && meshes[i].output_id == NotSet ) {
meshes[i].output_id = n++; meshes[i].output_id = n++;
output.push_back(mScene->mMeshes[i]); output.push_back(mScene->mMeshes[i]);
} }
} }
// and process all nodes in the scenegraoh recursively // and process all nodes in the scenegraph recursively
ProcessNode(pScene->mRootNode); ProcessNode(pScene->mRootNode);
if (!output.size()) { if (!output.size()) {
throw DeadlyImportError("OptimizeMeshes: No meshes remaining; there's definitely something wrong"); throw DeadlyImportError("OptimizeMeshes: No meshes remaining; there's definitely something wrong");
} }
meshes.clear(); meshes.resize( 0 );
ai_assert(output.size() <= num_old); ai_assert(output.size() <= num_old);
mScene->mNumMeshes = output.size(); mScene->mNumMeshes = output.size();
@ -142,8 +149,9 @@ void OptimizeMeshesProcess::Execute( aiScene* pScene)
char tmp[512]; char tmp[512];
::sprintf(tmp,"OptimizeMeshesProcess finished. Input meshes: %i, Output meshes: %i",num_old,pScene->mNumMeshes); ::sprintf(tmp,"OptimizeMeshesProcess finished. Input meshes: %i, Output meshes: %i",num_old,pScene->mNumMeshes);
DefaultLogger::get()->info(tmp); DefaultLogger::get()->info(tmp);
} else {
DefaultLogger::get()->debug( "OptimizeMeshesProcess finished" );
} }
else DefaultLogger::get()->debug("OptimizeMeshesProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -157,7 +165,7 @@ void OptimizeMeshesProcess::ProcessNode( aiNode* pNode)
im = meshes[im].output_id; im = meshes[im].output_id;
} }
else { else {
merge_list.clear(); merge_list.resize( 0 );
unsigned int verts = 0, faces = 0; unsigned int verts = 0, faces = 0;
// Find meshes to merge with us // Find meshes to merge with us
@ -170,8 +178,9 @@ void OptimizeMeshesProcess::ProcessNode( aiNode* pNode)
faces += mScene->mMeshes[am]->mNumFaces; faces += mScene->mMeshes[am]->mNumFaces;
--pNode->mNumMeshes; --pNode->mNumMeshes;
for (unsigned int n = a; n < pNode->mNumMeshes; ++n) for( unsigned int n = a; n < pNode->mNumMeshes; ++n ) {
pNode->mMeshes[n] = pNode->mMeshes[n+1]; pNode->mMeshes[ n ] = pNode->mMeshes[ n + 1 ];
}
--a; --a;
} }
@ -184,8 +193,7 @@ void OptimizeMeshesProcess::ProcessNode( aiNode* pNode)
aiMesh* out; aiMesh* out;
SceneCombiner::MergeMeshes(&out,0,merge_list.begin(),merge_list.end()); SceneCombiner::MergeMeshes(&out,0,merge_list.begin(),merge_list.end());
output.push_back(out); output.push_back(out);
} } else {
else {
output.push_back(mScene->mMeshes[im]); output.push_back(mScene->mMeshes[im]);
} }
im = output.size()-1; im = output.size()-1;
@ -193,8 +201,9 @@ void OptimizeMeshesProcess::ProcessNode( aiNode* pNode)
} }
for (unsigned int i = 0; i < pNode->mNumChildren; ++i) for( unsigned int i = 0; i < pNode->mNumChildren; ++i ) {
ProcessNode(pNode->mChildren[i]); ProcessNode( pNode->mChildren[ i ] );
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -206,8 +215,8 @@ bool OptimizeMeshesProcess::CanJoin ( unsigned int a, unsigned int b, unsigned i
aiMesh* ma = mScene->mMeshes[a], *mb = mScene->mMeshes[b]; aiMesh* ma = mScene->mMeshes[a], *mb = mScene->mMeshes[b];
if ((0xffffffff != max_verts && verts+mb->mNumVertices > max_verts) || if ((NotSet != max_verts && verts+mb->mNumVertices > max_verts) ||
(0xffffffff != max_faces && faces+mb->mNumFaces > max_faces)) { (NotSet != max_faces && faces+mb->mNumFaces > max_faces)) {
return false; return false;
} }
@ -221,7 +230,7 @@ bool OptimizeMeshesProcess::CanJoin ( unsigned int a, unsigned int b, unsigned i
return false; return false;
// If both meshes are skinned, check whether we have many bones defined in both meshes. // If both meshes are skinned, check whether we have many bones defined in both meshes.
// If yes, we can savely join them. // If yes, we can join them.
if (ma->HasBones()) { if (ma->HasBones()) {
// TODO // TODO
return false; return false;
@ -230,14 +239,18 @@ bool OptimizeMeshesProcess::CanJoin ( unsigned int a, unsigned int b, unsigned i
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Buidl a LUT of all instanced meshes // Build a LUT of all instanced meshes
void OptimizeMeshesProcess::FindInstancedMeshes (aiNode* pNode) void OptimizeMeshesProcess::FindInstancedMeshes (aiNode* pNode)
{ {
for (unsigned int i = 0; i < pNode->mNumMeshes;++i) for( unsigned int i = 0; i < pNode->mNumMeshes; ++i ) {
++meshes[pNode->mMeshes[i]].instance_cnt; ++meshes[ pNode->mMeshes[ i ] ].instance_cnt;
}
for (unsigned int i = 0; i < pNode->mNumChildren; ++i) for( unsigned int i = 0; i < pNode->mNumChildren; ++i ) {
FindInstancedMeshes(pNode->mChildren[i]); FindInstancedMeshes( pNode->mChildren[ i ] );
}
} }
// ------------------------------------------------------------------------------------------------
#endif // !! ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS #endif // !! ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS