Ver código fonte

FEATURE: Adding format auto-detection to OBJ loader basing on some distinct keywords.
FEATURE: PretransformVertices step is now optionally able to normalize meshes (-1...1 range).

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@488 67173fc5-114c-0410-ac8e-9d2fd5bffc1f

aramis_acg 16 anos atrás
pai
commit
cc1ff304df

+ 10 - 3
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);
+	}
 }
 
 // ------------------------------------------------------------------------------------------------

+ 33 - 6
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<aiVector3D> ()(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);
 	}

+ 1 - 1
code/PretransformVertices.h

@@ -157,7 +157,7 @@ private:
 
 
 	//! Configuration option: keep scene hierarchy as long as possible
-	bool configKeepHierarchy;
+	bool configKeepHierarchy, configNormalize;
 
 };
 

+ 13 - 3
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.

+ 6 - 3
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 <tt>#AI_CONFIG_PP_PTV_NORMALIZE</tt> configuration property
+	* can be set to normalize the scene's spatial dimension to the -1...1
+	* range. 
 	*/
 	aiProcess_PreTransformVertices = 0x100,