diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index d86fbaade..df061f851 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -77,10 +77,17 @@ ObjFileImporter::~ObjFileImporter() // ------------------------------------------------------------------------------------------------ // Returns true, fi file is an obj file -bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* /* pIOHandler */, bool /*checkSig */) const +bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const { - // fixme: auto detection - return SimpleExtensionCheck( pFile,"obj" ); + if(!checkSig) //Check File Extension + { + return SimpleExtensionCheck(pFile,"obj"); + } + else //Check file Header + { + const char* tokens[] = {"mtllib","usemtl","vt ","vn ","o "}; + return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, tokens, 5); + } } // ------------------------------------------------------------------------------------------------ diff --git a/code/PretransformVertices.cpp b/code/PretransformVertices.cpp index d9c9bbc99..c58816d22 100644 --- a/code/PretransformVertices.cpp +++ b/code/PretransformVertices.cpp @@ -79,8 +79,9 @@ bool PretransformVertices::IsActive( unsigned int pFlags) const // Setup import configuration void PretransformVertices::SetupProperties(const Importer* pImp) { - // Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY + // Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY and AI_CONFIG_PP_PTV_NORMALIZE configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,0)); + configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE,0)); } // ------------------------------------------------------------------------------------------------ @@ -468,8 +469,8 @@ void PretransformVertices::Execute( aiScene* pScene) if (apcOutMeshes.size() > 0) { aiMesh** npp = new aiMesh*[pScene->mNumMeshes + apcOutMeshes.size()]; - ::memcpy(npp,pScene->mMeshes,sizeof(aiMesh*)*pScene->mNumMeshes); - ::memcpy(npp+pScene->mNumMeshes,&apcOutMeshes[0],sizeof(aiMesh*)*apcOutMeshes.size()); + memcpy(npp,pScene->mMeshes,sizeof(aiMesh*)*pScene->mNumMeshes); + memcpy(npp+pScene->mNumMeshes,&apcOutMeshes[0],sizeof(aiMesh*)*apcOutMeshes.size()); pScene->mNumMeshes += apcOutMeshes.size(); delete[] pScene->mMeshes; pScene->mMeshes = npp; @@ -661,6 +662,32 @@ void PretransformVertices::Execute( aiScene* pScene) MakeIdentityTransform(pScene->mRootNode); } + if (configNormalize) { + // compute the boundary of all meshes + aiVector3D min,max; + MinMaxChooser ()(min,max); + + for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) { + aiMesh* m = pScene->mMeshes[a]; + for (unsigned int i = 0; i < m->mNumVertices;++i) { + min = std::min(m->mVertices[i],min); + max = std::max(m->mVertices[i],max); + } + } + + // find the dominant axis + aiVector3D d = max-min; + const float div = std::max(d.x,std::max(d.y,d.z))*0.5f; + + d = min+d*0.5f; + for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) { + aiMesh* m = pScene->mMeshes[a]; + for (unsigned int i = 0; i < m->mNumVertices;++i) { + m->mVertices[i] = (m->mVertices[i]-d)/div; + } + } + } + // print statistics if (!DefaultLogger::isNullLogger()) { @@ -668,15 +695,15 @@ void PretransformVertices::Execute( aiScene* pScene) DefaultLogger::get()->debug("PretransformVerticesProcess finished"); - ::sprintf(buffer,"Removed %i nodes and %i animation channels (%i output nodes)", + sprintf(buffer,"Removed %i nodes and %i animation channels (%i output nodes)", iOldNodes,iOldAnimationChannels,CountNodes(pScene->mRootNode)); DefaultLogger::get()->info(buffer); - ::sprintf(buffer,"Kept %i lights and %i cameras", + sprintf(buffer,"Kept %i lights and %i cameras", pScene->mNumLights,pScene->mNumCameras); DefaultLogger::get()->info(buffer); - ::sprintf(buffer,"Moved %i meshes to WCS (number of output meshes: %i)", + sprintf(buffer,"Moved %i meshes to WCS (number of output meshes: %i)", iOldMeshes,pScene->mNumMeshes); DefaultLogger::get()->info(buffer); } diff --git a/code/PretransformVertices.h b/code/PretransformVertices.h index 2327cc0e3..07acf3bca 100644 --- a/code/PretransformVertices.h +++ b/code/PretransformVertices.h @@ -157,7 +157,7 @@ private: //! Configuration option: keep scene hierarchy as long as possible - bool configKeepHierarchy; + bool configKeepHierarchy, configNormalize; }; diff --git a/include/aiConfig.h b/include/aiConfig.h index be190a3cc..95adb0323 100644 --- a/include/aiConfig.h +++ b/include/aiConfig.h @@ -129,11 +129,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // --------------------------------------------------------------------------- /** @brief Configures the #aiProcess_PretransformVertices step to * keep the scene hierarchy. Meshes are moved to worldspace, but - * no optimization is performed (means: meshes are not joined. The total - * number of meshes won't change). + * no optimization is performed (read: meshes with equal materials are not + * joined. The total number of meshes won't change). * * This option could be of use for you if the scene hierarchy contains - * important additional information which you want to interpret. + * important additional information which you intend to parse. * For rendering, you can still render all meshes in the scene without * any transformations. * Property type: integer (0: false; !0: true). Default value: false. @@ -141,6 +141,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AI_CONFIG_PP_PTV_KEEP_HIERARCHY \ "PP_PTV_KEEP_HIERARCHY" +// --------------------------------------------------------------------------- +/** @brief Configures the #aiProcess_PretransformVertices step to normalize + * all vertex components into the -1...1 range. That is, a bounding box + * for the whole scene is computed, the maximum component is taken and all + * meshes are scaled appropriately (uniformly of course!). + * This might be useful if you don't know the spatial dimension of the input + * data*/ +#define AI_CONFIG_PP_PTV_NORMALIZE \ + "PP_PTV_NORMALIZE" + // --------------------------------------------------------------------------- /** @brief Configures the #aiProcess_FindDegenerates step to * remove degenerated primitives from the import - immediately. diff --git a/include/aiPostProcess.h b/include/aiPostProcess.h index 9272da986..9861d911b 100644 --- a/include/aiPostProcess.h +++ b/include/aiPostProcess.h @@ -203,12 +203,15 @@ enum aiPostProcessSteps * each mesh referencing one material. For rendering, you can * simply render all meshes in order, you don't need to pay * attention to local transformations and the node hierarchy. - * Animations are removed during this step. - * This step is intended for applications that have no scenegraph. + * Animations are removed during this step. + * This step is intended for applications without a scenegraph. * The step CAN cause some problems: if e.g. a mesh of the asset * contains normals and another, using the same material index, does not, * they will be brought together, but the first meshes's part of - * the normal list will be zeroed. + * the normal list is zeroed. However, these artifacts are rare. + * @note The #AI_CONFIG_PP_PTV_NORMALIZE configuration property + * can be set to normalize the scene's spatial dimension to the -1...1 + * range. */ aiProcess_PreTransformVertices = 0x100,