From 16d9addf7bbd885a49cb10a9c1efd5eaf9a1ca0d Mon Sep 17 00:00:00 2001 From: Alov Maxim Date: Tue, 20 Jan 2015 18:02:33 +0400 Subject: [PATCH] Added new process - Scale-to-unit-box This allows to transform input meshes, scaling its vertices to unit box in order to let mesh become visible for small scenes or limited frustums. --- code/CMakeLists.txt | 2 + code/PostStepRegistry.cpp | 6 +++ code/ScaleToUnitBoxProcess.cpp | 87 ++++++++++++++++++++++++++++++++++ code/ScaleToUnitBoxProcess.h | 59 +++++++++++++++++++++++ include/assimp/postprocess.h | 14 +++++- 5 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 code/ScaleToUnitBoxProcess.cpp create mode 100644 code/ScaleToUnitBoxProcess.h diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 4f651c7c5..96959656d 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -482,6 +482,8 @@ SET( PostProcessing_SRCS RemoveRedundantMaterials.h RemoveVCProcess.cpp RemoveVCProcess.h + ScaleToUnitBoxProcess.cpp + ScaleToUnitBoxProcess.h SortByPTypeProcess.cpp SortByPTypeProcess.h SplitLargeMeshes.cpp diff --git a/code/PostStepRegistry.cpp b/code/PostStepRegistry.cpp index 5593a7f41..ea6558a5e 100644 --- a/code/PostStepRegistry.cpp +++ b/code/PostStepRegistry.cpp @@ -121,6 +121,9 @@ corresponding preprocessor flag to selectively disable steps. #ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS # include "DeboneProcess.h" #endif +#ifndef ASSIMP_BUILD_NO_SCALETOUNITBOX_PROCESS +# include "ScaleToUnitBoxProcess.h" +#endif namespace Assimp { @@ -190,6 +193,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) #if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS) out.push_back( new GenFaceNormalsProcess()); #endif +#if (!defined ASSIMP_BUILD_NO_SCALETOUNITBOX_PROCESS) + out.push_back( new ScaleToUnitBoxProcess()); +#endif // ......................................................................... // DON'T change the order of these five .. diff --git a/code/ScaleToUnitBoxProcess.cpp b/code/ScaleToUnitBoxProcess.cpp new file mode 100644 index 000000000..d3b4ef972 --- /dev/null +++ b/code/ScaleToUnitBoxProcess.cpp @@ -0,0 +1,87 @@ +/* + * ScaleToUnitBoxProcess.cpp + * + * Created on: Jan 20, 2015 + * Author: Alov Maxim + */ + +/// @file ScaleToUnitBoxProcess.cpp +/// Implementation of the ScaleToUnitBox postprocessing step + +#include "AssimpPCH.h" + +// internal headers of the post-processing framework +#include "ScaleToUnitBoxProcess.h" + +using namespace Assimp; + +// ------------------------------------------------------------------------------------------------ +// Constructor +ScaleToUnitBoxProcess::ScaleToUnitBoxProcess() +{ + // nothing to do here +} + +// ------------------------------------------------------------------------------------------------ +// Destructor +ScaleToUnitBoxProcess::~ScaleToUnitBoxProcess() +{ + // nothing to do here +} + +// ------------------------------------------------------------------------------------------------ +// Returns whether the processing step is present in the given flag. +bool ScaleToUnitBoxProcess::IsActive( unsigned int pFlags) const +{ + return !!(pFlags & aiProcess_ScaleToUnitBox); +} + +// ------------------------------------------------------------------------------------------------ +// Updates internal properties +void ScaleToUnitBoxProcess::SetupProperties(const Importer* pImp) +{ + // nothing to do here +} + +// ------------------------------------------------------------------------------------------------ +// Executes the post processing step on the given imported data. +void ScaleToUnitBoxProcess::Execute( aiScene* pScene) +{ + DefaultLogger::get()->debug("ScaleToUnitBoxProcess begin"); + + if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) { + throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); + } + + for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { + this->ScaleMesh( pScene->mMeshes[a]); + } + DefaultLogger::get()->info("ScaleToUnitBoxProcess finished. " + "Mesh vertices have been scaled to unit box"); +} + +// ------------------------------------------------------------------------------------------------ +// Scales all vertices of the given mesh to conform unit box. +void ScaleToUnitBoxProcess::ScaleMesh( const aiMesh* pMesh) const +{ + aiVector3D center = aiVector3D(0.0f, 0.0f, 0.0f); + for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) { + center += pMesh->mVertices[i]; + } + center /= float(pMesh->mNumVertices); + float radius = 0.0f; + for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) { + aiVector3D distanceValues = center; + distanceValues -= pMesh->mVertices[i]; + float vDistance = distanceValues.Length(); + if (vDistance > radius) { + radius = vDistance; + } + } + for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) { + aiVector3D segment = pMesh->mVertices[i]; + segment -= center; + segment /= radius; + pMesh->mVertices[i].Set(segment.x, segment.y, segment.z); + } +} diff --git a/code/ScaleToUnitBoxProcess.h b/code/ScaleToUnitBoxProcess.h new file mode 100644 index 000000000..3eac53b57 --- /dev/null +++ b/code/ScaleToUnitBoxProcess.h @@ -0,0 +1,59 @@ +/* + * ScaleToUnitBoxProcess.h + * + * Created on: Jan 20, 2015 + * Author: Alov Maxim + */ + +/// @file ScaleToUnitBoxProcess.h +/// Defines a post processing step to scale mesh vertices into unit box +#ifndef AI_SCALETOUNITBOXPROCESS_H_INC +#define AI_SCALETOUNITBOXPROCESS_H_INC + +#include +#include "BaseProcess.h" + +#include "../include/assimp/mesh.h" +#include "../include/assimp/scene.h" + +namespace Assimp +{ + +class ScaleToUnitBoxProcess : public BaseProcess +{ +public: + + ScaleToUnitBoxProcess(); + ~ScaleToUnitBoxProcess(); + +public: + /** Returns whether the processing step is present in the given flag. + * @param pFlags The processing flags the importer was called with. A + * bitwise combination of #aiPostProcessSteps. + * @return true if the process is present in this flag fields, + * false if not. + */ + bool IsActive( unsigned int pFlags) const; + + /** Called prior to ExecuteOnScene(). + * The function is a request to the process to update its configuration + * basing on the Importer's configuration property list. + */ + virtual void SetupProperties(const Importer* pImp); + +protected: + /** Executes the post processing step on the given imported data. + * At the moment a process is not supposed to fail. + * @param pScene The imported data to work at. + */ + void Execute( aiScene* pScene); + + /// Scales all vertices of the given mesh to conform unit box. + /// @param pMesh the Mesh which vertices to be scaled. + void ScaleMesh( const aiMesh* pMesh) const; +}; + +} // end of namespace Assimp + + +#endif // !!AI_SCALETOUNITBOXPROCESS_H_INC diff --git a/include/assimp/postprocess.h b/include/assimp/postprocess.h index f078fd692..0f24e35cc 100644 --- a/include/assimp/postprocess.h +++ b/include/assimp/postprocess.h @@ -523,11 +523,23 @@ enum aiPostProcessSteps * Use #AI_CONFIG_PP_DB_ALL_OR_NONE if you want bones removed if and * only if all bones within the scene qualify for removal. */ - aiProcess_Debone = 0x4000000 + aiProcess_Debone = 0x4000000, // aiProcess_GenEntityMeshes = 0x100000, // aiProcess_OptimizeAnimations = 0x200000 // aiProcess_FixTexturePaths = 0x200000 + + // ------------------------------------------------------------------------- + /** + *
This step scales meshes' vertices to unit box obtaining + * center and radius of resulting scene. + * + * It is recommended to use this flag with aiProcess_GenNormals or + * aiProcess_GenSmoothNormals to ensure normals being recomputed. + * + * Alov Maxim + */ + aiProcess_ScaleToUnitBox = 0x8000000 };