From c89107a117fe11c1d4b6c7921a7017a5ae2eb6b1 Mon Sep 17 00:00:00 2001 From: aramis_acg Date: Mon, 21 Sep 2009 17:41:57 +0000 Subject: [PATCH] FEATURE: FindInvalidData step now provides a configuration option to fine-tune the accuracy of floating-point comparisons. Ogre-Importer now compiles with -noboost. Fixing GCC complaints about inproper 'address of temporary' in Ogre-Importer. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@480 67173fc5-114c-0410-ac8e-9d2fd5bffc1f --- code/FindInvalidDataProcess.cpp | 174 ++++++++++++++++++++------------ code/FindInvalidDataProcess.h | 33 +++--- code/OgreImporter.cpp | 25 +++-- code/OgreImporter.h | 4 +- include/aiConfig.h | 67 ++++++------ include/aiPostProcess.h | 10 +- 6 files changed, 183 insertions(+), 130 deletions(-) diff --git a/code/FindInvalidDataProcess.cpp b/code/FindInvalidDataProcess.cpp index 7cff0877b..c606d7f56 100644 --- a/code/FindInvalidDataProcess.cpp +++ b/code/FindInvalidDataProcess.cpp @@ -73,32 +73,39 @@ bool FindInvalidDataProcess::IsActive( unsigned int pFlags) const return 0 != (pFlags & aiProcess_FindInvalidData); } +// ------------------------------------------------------------------------------------------------ +// Setup import configuration +void FindInvalidDataProcess::SetupProperties(const Importer* pImp) +{ + // Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY + configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY,0.f)); +} + // ------------------------------------------------------------------------------------------------ // Update mesh references in the node graph void UpdateMeshReferences(aiNode* node, const std::vector& meshMapping) { - if (node->mNumMeshes) - { + if (node->mNumMeshes) { unsigned int out = 0; - for (unsigned int a = 0; a < node->mNumMeshes;++a) - { + for (unsigned int a = 0; a < node->mNumMeshes;++a) { + register unsigned int ref = node->mMeshes[a]; - if (0xffffffff != (ref = meshMapping[ref])) - { + if (0xffffffff != (ref = meshMapping[ref])) { node->mMeshes[out++] = ref; } } // just let the members that are unused, that's much cheaper // than a full array realloc'n'copy party ... - if(!(node->mNumMeshes = out)) - { + if(!(node->mNumMeshes = out)) { + delete[] node->mMeshes; node->mMeshes = NULL; } } // recursively update all children - for (unsigned int i = 0; i < node->mNumChildren;++i) + for (unsigned int i = 0; i < node->mNumChildren;++i) { UpdateMeshReferences(node->mChildren[i],meshMapping); + } } // ------------------------------------------------------------------------------------------------ @@ -112,14 +119,13 @@ void FindInvalidDataProcess::Execute( aiScene* pScene) unsigned int real = 0; // Process meshes - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) - { + for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { + int result; - if ((result = ProcessMesh( pScene->mMeshes[a]))) - { + if ((result = ProcessMesh( pScene->mMeshes[a]))) { out = true; - if (2 == result) - { + + if (2 == result) { // remove this mesh delete pScene->mMeshes[a]; AI_DEBUG_INVALIDATE_PTR(pScene->mMeshes[a]); @@ -133,17 +139,16 @@ void FindInvalidDataProcess::Execute( aiScene* pScene) } // Process animations - for (unsigned int a = 0; a < pScene->mNumAnimations;++a) + for (unsigned int a = 0; a < pScene->mNumAnimations;++a) { ProcessAnimation( pScene->mAnimations[a]); + } - if (out) - { - if ( real != pScene->mNumMeshes) - { - if (!real) + if (out) { + if ( real != pScene->mNumMeshes) { + if (!real) { throw new ImportErrorException("No meshes remaining"); - + } // we need to remove some meshes. // therefore we'll also need to remove all references @@ -172,24 +177,25 @@ inline const char* ValidateArrayContents(const aiVector3D* arr, unsi { bool b = false; unsigned int cnt = 0; - for (unsigned int i = 0; i < size;++i) - { - if (dirtyMask.size() && dirtyMask[i])continue; + for (unsigned int i = 0; i < size;++i) { + + if (dirtyMask.size() && dirtyMask[i]) { + continue; + } ++cnt; const aiVector3D& v = arr[i]; - if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) - { + if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) { return "INF/NAN was found in a vector component"; } - if (!mayBeZero && !v.x && !v.y && !v.z ) - { + if (!mayBeZero && !v.x && !v.y && !v.z ) { return "Found zero-length vector"; } if (i && v != arr[i-1])b = true; } - if (cnt > 1 && !b && !mayBeIdentical) + if (cnt > 1 && !b && !mayBeIdentical) { return "All vectors are identical"; + } return NULL; } @@ -198,10 +204,8 @@ template inline bool ProcessArray(T*& in, unsigned int num,const char* name, const std::vector& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) { - const char* err = ValidateArrayContents(in,num,dirtyMask, - mayBeIdentical,mayBeZero); - if (err) - { + const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero); + if (err) { DefaultLogger::get()->error(std::string("FindInvalidDataProcess fails on mesh ") + name + ": " + err); delete[] in; @@ -213,12 +217,55 @@ inline bool ProcessArray(T*& in, unsigned int num,const char* name, // ------------------------------------------------------------------------------------------------ template -inline bool AllIdentical(T* in, unsigned int num) +AI_FORCE_INLINE bool EpsilonCompare(const T& n, const T& s, float epsilon); + +// ------------------------------------------------------------------------------------------------ +AI_FORCE_INLINE bool EpsilonCompare(float n, float s, float epsilon) { + return fabs(n-s)>epsilon; +} + +// ------------------------------------------------------------------------------------------------ +template <> +bool EpsilonCompare(const aiVectorKey& n, const aiVectorKey& s, float epsilon) { + return + EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) && + EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) && + EpsilonCompare(n.mValue.z,s.mValue.z,epsilon); +} + +// ------------------------------------------------------------------------------------------------ +template <> +bool EpsilonCompare(const aiQuatKey& n, const aiQuatKey& s, float epsilon) { + return + EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) && + EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) && + EpsilonCompare(n.mValue.z,s.mValue.z,epsilon) && + EpsilonCompare(n.mValue.w,s.mValue.w,epsilon); +} + +// ------------------------------------------------------------------------------------------------ +template +inline bool AllIdentical(T* in, unsigned int num, float epsilon) { - if (num <= 1)return true; - for (unsigned int i = 0; i < num-1;++i) - { - if (in[i] != in[i+1])return false; + if (num <= 1) { + return true; + } + + if (epsilon > 0.f) { + for (unsigned int i = 0; i < num-1;++i) { + + if (!EpsilonCompare(in[i],in[i+1],epsilon)) { + return false; + } + } + } + else { + for (unsigned int i = 0; i < num-1;++i) { + + if (in[i] != in[i+1]) { + return false; + } + } } return true; } @@ -228,8 +275,9 @@ inline bool AllIdentical(T* in, unsigned int num) void FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim) { // Process all animation channels - for (unsigned int a = 0; a < anim->mNumChannels;++a) + for (unsigned int a = 0; a < anim->mNumChannels;++a) { ProcessAnimationChannel( anim->mChannels[a]); + } } // ------------------------------------------------------------------------------------------------ @@ -243,7 +291,7 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) // Check whether all values in a tracks are identical - in this case // we can remove al keys except one. // POSITIONS - if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys)) + if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys,configEpsilon)) { aiVectorKey v = anim->mPositionKeys[0]; @@ -255,7 +303,7 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) } // ROTATIONS - if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys)) + if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys,configEpsilon)) { aiQuatKey v = anim->mRotationKeys[0]; @@ -267,7 +315,7 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) } // SCALINGS - if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys)) + if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys,configEpsilon)) { aiVectorKey v = anim->mScalingKeys[0]; @@ -290,29 +338,26 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh) // Ignore elements that are not referenced by vertices. // (they are, for example, caused by the FindDegenerates step) - for (unsigned int m = 0; m < pMesh->mNumFaces;++m) - { + for (unsigned int m = 0; m < pMesh->mNumFaces;++m) { const aiFace& f = pMesh->mFaces[m]; - for (unsigned int i = 0; i < f.mNumIndices;++i) + + for (unsigned int i = 0; i < f.mNumIndices;++i) { dirtyMask[f.mIndices[i]] = false; + } } // Process vertex positions - if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask)) - { + if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask)) { DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions"); return 2; } // process texture coordinates - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i) - { - if (!pMesh->mTextureCoords[i])break; - if (ProcessArray(pMesh->mTextureCoords[i],pMesh->mNumVertices,"uvcoords",dirtyMask)) - { + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i];++i) { + if (ProcessArray(pMesh->mTextureCoords[i],pMesh->mNumVertices,"uvcoords",dirtyMask)) { + // delete all subsequent texture coordinate sets. - for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) - { + for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) { delete[] pMesh->mTextureCoords[a]; pMesh->mTextureCoords[a] = NULL; } ret = true; @@ -323,8 +368,8 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh) // they are invalid or not. // Normals and tangents are undefined for point and line faces. - if (pMesh->mNormals || pMesh->mTangents) - { + if (pMesh->mNormals || pMesh->mTangents) { + if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes || aiPrimitiveType_LINE & pMesh->mPrimitiveTypes) { @@ -336,11 +381,12 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh) { const aiFace& f = pMesh->mFaces[m]; - if (f.mNumIndices < 3) - { + if (f.mNumIndices < 3) { dirtyMask[f.mIndices[0]] = true; - if (f.mNumIndices == 2) + + if (f.mNumIndices == 2) { dirtyMask[f.mIndices[1]] = true; + } } } } @@ -355,17 +401,13 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh) ret = true; // Process mesh tangents - if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices, - "tangents",dirtyMask)) - { + if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,"tangents",dirtyMask)) { delete[] pMesh->mBitangents; pMesh->mBitangents = NULL; ret = true; } // Process mesh bitangents - if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices, - "bitangents",dirtyMask)) - { + if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,"bitangents",dirtyMask)) { delete[] pMesh->mTangents; pMesh->mTangents = NULL; ret = true; } diff --git a/code/FindInvalidDataProcess.h b/code/FindInvalidDataProcess.h index 51382f39a..cbc5e27a7 100644 --- a/code/FindInvalidDataProcess.h +++ b/code/FindInvalidDataProcess.h @@ -48,18 +48,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct aiMesh; class FindInvalidDataProcessTest; - -namespace Assimp -{ +namespace Assimp { // --------------------------------------------------------------------------- /** The FindInvalidData postprocessing step. It searches the mesh data * for parts that are obviously invalid and removes them. * * Originally this was a workaround for some models written by Blender - * which have zero normal vectors. - */ -class ASSIMP_API FindInvalidDataProcess : public BaseProcess + * which have zero normal vectors. */ +class ASSIMP_API FindInvalidDataProcess + : public BaseProcess { friend class Importer; friend class ::FindInvalidDataProcessTest; @@ -75,13 +73,15 @@ protected: public: // ------------------------------------------------------------------- - /** - */ + // bool IsActive( unsigned int pFlags) const; // ------------------------------------------------------------------- - /** - */ + // Setup import settings + void SetupProperties(const Importer* pImp); + + // ------------------------------------------------------------------- + // Run the step void Execute( aiScene* pScene); protected: @@ -89,22 +89,21 @@ protected: // ------------------------------------------------------------------- /** Executes the postprocessing step on the given mesh * @param pMesh The mesh to process. - * @return 0 - nothing, 1 - removed sth, 2 - please delete me - */ + * @return 0 - nothing, 1 - removed sth, 2 - please delete me */ int ProcessMesh( aiMesh* pMesh); - // ------------------------------------------------------------------- /** Executes the postprocessing step on the given animation - * @param anim The animation to process. - */ + * @param anim The animation to process. */ void ProcessAnimation (aiAnimation* anim); // ------------------------------------------------------------------- /** Executes the postprocessing step on the given anim channel - * @param anim The animation channel to process. - */ + * @param anim The animation channel to process.*/ void ProcessAnimationChannel (aiNodeAnim* anim); + +private: + float configEpsilon; }; } // end of namespace Assimp diff --git a/code/OgreImporter.cpp b/code/OgreImporter.cpp index e1ffb9e49..a174df9cd 100644 --- a/code/OgreImporter.cpp +++ b/code/OgreImporter.cpp @@ -6,8 +6,8 @@ #include using namespace std; -#include "boost/format.hpp" -#include "boost/foreach.hpp" +//#include "boost/format.hpp" +//#include "boost/foreach.hpp" using namespace boost; #include "OgreImporter.h" @@ -340,7 +340,9 @@ void OgreImporter::ReadSubMesh(SubMesh &theSubMesh, XmlReader *Reader) aiMaterial* OgreImporter::LoadMaterial(std::string MaterialName) { MaterialHelper *NewMaterial=new MaterialHelper(); - NewMaterial->AddProperty(&aiString(MaterialName.c_str()), AI_MATKEY_NAME); + + aiString ts(MaterialName.c_str()); + NewMaterial->AddProperty(&ts, AI_MATKEY_NAME); /*For bettetr understanding of the material parser, here is a material example file: material Sarg @@ -449,7 +451,8 @@ aiMaterial* OgreImporter::LoadMaterial(std::string MaterialName) if(Line=="texture") { ss >> Line; - NewMaterial->AddProperty(&aiString(Line.c_str()), AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); + aiString ts(Line.c_str()); + NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); } }//end of texture unit } @@ -478,12 +481,14 @@ aiMaterial* OgreImporter::LoadMaterial(std::string MaterialName) if(Line=="$colormap") { ss >> Line; - NewMaterial->AddProperty(&aiString(Line.c_str()), AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); + aiString ts(Line.c_str()); + NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); } if(Line=="$normalmap") { ss >> Line; - NewMaterial->AddProperty(&aiString(Line.c_str()), AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); + aiString ts(Line.c_str()); + NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); } } }//end of material @@ -569,7 +574,7 @@ void OgreImporter::LoadSkeleton(std::string FileName) XmlRead(SkeletonFile); } //The bones in the file a not neccesarly ordered by there id's so we do it now: - sort(Bones.begin(), Bones.end()); + std::sort(Bones.begin(), Bones.end()); //now the id of each bone should be equal to its position in the vector: //so we do a simple check: { @@ -779,10 +784,12 @@ aiNode* CreateAiNodeFromBone(int BoneId, std::vector Bones, aiNode* Parent //----Create the node for this bone and set its values----- aiNode* NewNode=new aiNode(Bones[BoneId].Name); NewNode->mParent=ParentNode; + + aiMatrix4x4 t0,t1; //create a matrix from the transformation values of the ogre bone - NewNode->mTransformation=aiMatrix4x4::Translation(Bones[BoneId].Position, aiMatrix4x4()) + NewNode->mTransformation=aiMatrix4x4::Translation(Bones[BoneId].Position, t0) * - aiMatrix4x4::Rotation(Bones[BoneId].RotationAngle, Bones[BoneId].RotationAxis, aiMatrix4x4()) + aiMatrix4x4::Rotation(Bones[BoneId].RotationAngle, Bones[BoneId].RotationAxis, t1) ; //__________________________________________________________ diff --git a/code/OgreImporter.h b/code/OgreImporter.h index c095ce4aa..076f9e88d 100644 --- a/code/OgreImporter.h +++ b/code/OgreImporter.h @@ -146,10 +146,10 @@ struct Bone ///ctor Bone(): Id(-1), ParentId(-1), RotationAngle(0.0f) {} ///this operator is needed to sort the bones after Id's - bool operator<(const Bone& rval) + bool operator<(const Bone& rval) const {return Id - bool operator==(const std::string& rval) + bool operator==(const std::string& rval) const {return Name==rval; } }; diff --git a/include/aiConfig.h b/include/aiConfig.h index aec5bc6e6..be190a3cc 100644 --- a/include/aiConfig.h +++ b/include/aiConfig.h @@ -197,7 +197,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * This is used by the "SplitLargeMeshes" PostProcess-Step to determine * whether a mesh must be split or not. * @note The default value is AI_SLM_DEFAULT_MAX_VERTICES - * Property type: integer. + * Property type: integer. */ #define AI_CONFIG_PP_SLM_VERTEX_LIMIT \ "PP_SLM_VERTEX_LIMIT" @@ -212,8 +212,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This is used by the #aiProcess_LimitBoneWeights PostProcess-Step. * @note The default value is AI_LBW_MAX_WEIGHTS - * Property type: integer. - */ + * Property type: integer.*/ #define AI_CONFIG_PP_LBW_MAX_WEIGHTS \ "PP_LBW_MAX_WEIGHTS" @@ -243,71 +242,59 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // --------------------------------------------------------------------------- /** @brief Enumerates components of the aiScene and aiMesh data structures - * that can be excluded from the import by using the RemoveComponent step. + * that can be excluded from the import using the #aiPrpcess_RemoveComponent step. * * See the documentation to #aiProcess_RemoveComponent for more details. */ enum aiComponent { - /** Normal vectors - */ + /** Normal vectors */ aiComponent_NORMALS = 0x2u, - /** Tangents and bitangents go always together ... - */ + /** Tangents and bitangents go always together ... */ aiComponent_TANGENTS_AND_BITANGENTS = 0x4u, /** ALL color sets - * Use aiComponent_COLORn(N) to specify the N'th set - */ + * Use aiComponent_COLORn(N) to specify the N'th set */ aiComponent_COLORS = 0x8, /** ALL texture UV sets - * aiComponent_TEXCOORDn(N) to specify the N'th set - */ + * aiComponent_TEXCOORDn(N) to specify the N'th set */ aiComponent_TEXCOORDS = 0x10, /** Removes all bone weights from all meshes. * The scenegraph nodes corresponding to the bones are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this - */ + * use the #aiProcess_OptimizeGraph step to do this */ aiComponent_BONEWEIGHTS = 0x20, /** Removes all node animations (aiScene::mAnimations). * The corresponding scenegraph nodes are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this - */ + * use the #aiProcess_OptimizeGraph step to do this */ aiComponent_ANIMATIONS = 0x40, - /** Removes all embedded textures (aiScene::mTextures) - */ + /** Removes all embedded textures (aiScene::mTextures) */ aiComponent_TEXTURES = 0x80, /** Removes all light sources (aiScene::mLights). * The corresponding scenegraph nodes are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this - */ + * use the #aiProcess_OptimizeGraph step to do this */ aiComponent_LIGHTS = 0x100, /** Removes all light sources (aiScene::mCameras). * The corresponding scenegraph nodes are NOT removed. - * use the #aiProcess_OptimizeGraph step to do this - */ + * use the #aiProcess_OptimizeGraph step to do this */ aiComponent_CAMERAS = 0x200, - /** Removes all meshes (aiScene::mMeshes). - */ + /** Removes all meshes (aiScene::mMeshes). */ aiComponent_MESHES = 0x400, /** Removes all materials. One default material will - * be generated, so aiScene::mNumMaterials will be 1. - */ + * be generated, so aiScene::mNumMaterials will be 1. */ aiComponent_MATERIALS = 0x800, /** This value is not used. It is just there to force the - * compiler to map this enum to a 32 Bit integer. - */ + * compiler to map this enum to a 32 Bit integer. */ _aiComponent_Force32Bit = 0x9fffffff }; @@ -344,6 +331,18 @@ enum aiComponent #define AI_CONFIG_PP_SBP_REMOVE \ "PP_SBP_REMOVE" +// --------------------------------------------------------------------------- +/** @brief Input parameter to the #aiProcess_FindInvalidData step: + * Specifies the floating-point accuracy for animation values. The step + * checks for animation tracks where all frame values are absolutely equal + * and removes them. This tweakable controls the epsilon for floating-point + * comparisons - two keys are considered equal if the invariant + * abs(n0-n1)>epsilon holds true for all vector respectively quaternion + * components. The default value is 0.f - comparisons are exact then. + */ +#define AI_CONFIG_PP_FID_ANIM_ACCURACY \ + "PP_FID_ANIM_ACCURACY" + // TransformUVCoords evaluates UV scalings #define AI_UVTRAFO_SCALING 0x1 @@ -552,11 +551,13 @@ enum aiComponent #define AI_CONFIG_IMPORT_IRR_ANIM_FPS \ "IMPORT_IRR_ANIM_FPS" -/// Ogre Importer will try to load this Materialfile -/** -Ogre Mehs contain only the MaterialName, not the MaterialFile. If there is no material file -with the same name as the material, Ogre Importer will try to load this file and search the material in it. -*/ + +// --------------------------------------------------------------------------- +/** Ogre Importer will try to load this Materialfile + * Ogre Mehs contain only the MaterialName, not the MaterialFile. If there + * is no material file with the same name as the material, Ogre Importer will + * try to load this file and search the material in it. + */ #define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE "IMPORT_OGRE_MATERIAL_FILE" diff --git a/include/aiPostProcess.h b/include/aiPostProcess.h index 4e31b9997..9272da986 100644 --- a/include/aiPostProcess.h +++ b/include/aiPostProcess.h @@ -358,12 +358,16 @@ enum aiPostProcessSteps // ------------------------------------------------------------------------- /**
This step searches all meshes for invalid data, such as zeroed - * normal vectors or invalid UV coords and removes them. + * normal vectors or invalid UV coords and removes/fixes them. This is + * intended to get rid of some common exporter errors. * * This is especially useful for normals. If they are invalid, and * the step recognizes this, they will be removed and can later - * be computed by one of the other steps.
- * The step will also remove meshes that are infinitely small. + * be recomputed, i.e. by the #aiProcess_GenSmoothNormals flag.
+ * The step will also remove meshes that are infinitely small and reduce + * animation tracks consisting of hundreds if redundant keys to a single + * key. The AI_CONFIG_PP_FID_ANIM_ACCURACY config property decides + * the accuracy of the check for duplicate animation tracks. */ aiProcess_FindInvalidData = 0x20000,