|
@@ -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_faces (0xffffffff)
|
|
|
|
-{}
|
|
|
|
|
|
+, max_verts( NotSet )
|
|
|
|
+, 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();
|
|
|
|
- output.clear();
|
|
|
|
|
|
+ merge_list.resize( 0 );
|
|
|
|
+ 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 */
|
|
|
|
- max_verts = 0xffffffff;
|
|
|
|
|
|
+ if( max_verts == DeadBeef ) /* undo the magic hack */
|
|
|
|
+ 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)
|
|
|
|
- pNode->mMeshes[n] = pNode->mMeshes[n+1];
|
|
|
|
|
|
+ for( unsigned int n = a; n < pNode->mNumMeshes; ++n ) {
|
|
|
|
+ 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)
|
|
|
|
- ProcessNode(pNode->mChildren[i]);
|
|
|
|
|
|
+ for( unsigned int i = 0; i < pNode->mNumChildren; ++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) ||
|
|
|
|
- (0xffffffff != max_faces && faces+mb->mNumFaces > max_faces)) {
|
|
|
|
|
|
+ if ((NotSet != max_verts && verts+mb->mNumVertices > max_verts) ||
|
|
|
|
+ (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)
|
|
|
|
- ++meshes[pNode->mMeshes[i]].instance_cnt;
|
|
|
|
|
|
+ for( unsigned int i = 0; i < pNode->mNumMeshes; ++i ) {
|
|
|
|
+ ++meshes[ pNode->mMeshes[ i ] ].instance_cnt;
|
|
|
|
+ }
|
|
|
|
|
|
- for (unsigned int i = 0; i < pNode->mNumChildren; ++i)
|
|
|
|
- FindInstancedMeshes(pNode->mChildren[i]);
|
|
|
|
|
|
+ for( unsigned int i = 0; i < pNode->mNumChildren; ++i ) {
|
|
|
|
+ FindInstancedMeshes( pNode->mChildren[ i ] );
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// ------------------------------------------------------------------------------------------------
|
|
|
|
+
|
|
#endif // !! ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
|
|
#endif // !! ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
|