Selaa lähdekoodia

MD5 parser will now reject files with version!=10.
3DS Loader -> improved light and camera handling.
DXF -> minor fixes, refactoring.
Updating DLL revision number.


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

aramis_acg 16 vuotta sitten
vanhempi
commit
bcfbc37301
5 muutettua tiedostoa jossa 91 lisäystä ja 103 poistoa
  1. 12 12
      code/3DSConverter.cpp
  2. 53 75
      code/3DSLoader.cpp
  3. 24 14
      code/DXFLoader.cpp
  4. 1 1
      code/MD5Parser.cpp
  5. 1 1
      mkutil/revision.h

+ 12 - 12
code/3DSConverter.cpp

@@ -594,22 +594,22 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
 			nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
 			::memcpy(nda->mPositionKeys,&distanceTrack[0],
 				sizeof(aiVectorKey)*nda->mNumPositionKeys);
+		}
+#endif
 
-			// The target animation is now encoded in the local transformation
-			// matrix of the camera, so we must clear the corresponding
-			// fields in aiCamera or aiLight.
-			for (unsigned int n = 0; n < pcSOut->mNumCameras;++n)	{
-				if (pcSOut->mCameras[n]->mName == pcOut->mName) {
-					pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f,0.f,1.f);
-				}
+		// Cameras or lights define their transformation in their parent node and in the
+		// corresponding light or camera chunks. However, we read and process the latter
+		// to to be able to return valid cameras/lights even if no scenegraph is given.
+		for (unsigned int n = 0; n < pcSOut->mNumCameras;++n)	{
+			if (pcSOut->mCameras[n]->mName == pcOut->mName) {
+				pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f,0.f,1.f);
 			}
-			for (unsigned int n = 0; n < pcSOut->mNumLights;++n)	{
-				if (pcSOut->mLights[n]->mName == pcOut->mName) {
-					pcSOut->mLights[n]->mDirection = aiVector3D(0.f,0.f,1.f);
-				}
+		}
+		for (unsigned int n = 0; n < pcSOut->mNumLights;++n)	{
+			if (pcSOut->mLights[n]->mName == pcOut->mName) {
+				pcSOut->mLights[n]->mDirection = aiVector3D(0.f,0.f,1.f);
 			}
 		}
-#endif
 
 		// Allocate a new node anim and setup its name
 		aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();

+ 53 - 75
code/3DSLoader.cpp

@@ -357,6 +357,11 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
 {
 	ASSIMP_3DS_BEGIN_CHUNK();
 
+	// IMPLEMENTATION NOTE;
+	// Cameras or lights define their transformation in their parent node and in the
+	// corresponding light or camera chunks. However, we read and process the latter
+	// to to be able to return valid cameras/lights even if no scenegraph is given.
+
 	// get chunk type
 	switch (chunk.Flag)
 	{
@@ -410,13 +415,8 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
 		// This starts a new camera
 		aiCamera* camera = new aiCamera();
 		mScene->mCameras.push_back(camera);
-
 		camera->mName.Set(std::string(name, num));
 
-		// Camera position and look-at vector are difficult to handle. If an animation track is given,
-		// we must make sure that the track is relative to these values - or , easier we must copy the
-		// information here to the node matrix of the camera's parent in the graph.
-
 		// First read the position of the camera
 		camera->mPosition.x = stream->GetF4();
 		camera->mPosition.y = stream->GetF4();
@@ -429,7 +429,7 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
 		float len = camera->mLookAt.Length();
 		if (len < 1e-5f) {
 			
-			// There are some files with lookat == position. Don't know why or whether it's ok.
+			// There are some files with lookat == position. Don't know why or whether it's ok or not.
 			DefaultLogger::get()->error("3DS: Unable to read proper camera look-at vector");
 			camera->mLookAt = aiVector3D(0.f,1.f,0.f);
 
@@ -558,14 +558,15 @@ void Discreet3DSImporter::ParseKeyframeChunk()
 // Little helper function for ParseHierarchyChunk
 void Discreet3DSImporter::InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent)
 {
-	if (!pcCurrent)
-	{
+	if (!pcCurrent)	{
 		mRootNode->push_back(pcNode);
 		return;
 	}
-	if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos)
-	{
-		if(pcCurrent->mParent)pcCurrent->mParent->push_back(pcNode);
+
+	if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos)	{
+		if(pcCurrent->mParent)
+			pcCurrent->mParent->push_back(pcNode);
+
 		else pcCurrent->push_back(pcNode);
 		return;
 	}
@@ -576,12 +577,12 @@ void Discreet3DSImporter::InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCur
 // Find a node with a specific name in the import hierarchy
 D3DS::Node* FindNode(D3DS::Node* root, const std::string& name)
 {
-	if (root->mName == name)return root;
-	for (std::vector<D3DS::Node*>::iterator it = root->mChildren.begin();
-		it != root->mChildren.end(); ++it)
-	{
+	if (root->mName == name)
+		return root;
+	for (std::vector<D3DS::Node*>::iterator it = root->mChildren.begin();it != root->mChildren.end(); ++it)	{
 		D3DS::Node* nd;
-		if (( nd = FindNode(*it,name)))return nd;
+		if (( nd = FindNode(*it,name)))
+			return nd;
 	}
 	return NULL;
 }
@@ -631,9 +632,8 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 	{
 	case Discreet3DS::CHUNK_TRACKOBJNAME:
 
-		// This is the name of the object to which the track applies
-		// The chunk also defines the position of this object in the
-		// hierarchy.
+		// This is the name of the object to which the track applies. The chunk also
+		// defines the position of this object in the hierarchy.
 		{
 
 		// First of all: get the name of the object
@@ -643,9 +643,8 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		while (stream->GetI1())++cnt;
 		std::string name = std::string(sz,cnt);
 
-		// Now find out whether we have this node already
-		// (target animation channels are stored with a
-		//  separate object ID)
+		// Now find out whether we have this node already (target animation channels 
+		// are stored with a separate object ID)
 		D3DS::Node* pcNode = FindNode(mRootNode,name);
 		if (pcNode)
 		{
@@ -694,9 +693,8 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		{
 			const char* sz = (const char*) stream->GetPtr();
 			while (stream->GetI1());
-			// mCurrentNode->mDummyName = std::string(sz);
 
-			// FIX: if object name is DUMMY, take this one instead
+			// If object name is DUMMY, take this one instead
 			if (mCurrentNode->mName == "$$$DUMMY")	{
 				//DefaultLogger::get()->warn("3DS: Skipping dummy object name for non-dummy object");
 				mCurrentNode->mName = std::string(sz);
@@ -933,16 +931,12 @@ void Discreet3DSImporter::ParseFaceChunk()
 	// Get chunk type
 	switch (chunk.Flag)
 	{
-
 	case Discreet3DS::CHUNK_SMOOLIST:
 		{
-		// This is the list of smoothing groups - a bitfield for
-		// every frame. Up to 32 smoothing groups assigned to a
-		// face.
+		// This is the list of smoothing groups - a bitfield for every face. 
+		// Up to 32 smoothing groups assigned to a single face.
 		unsigned int num = chunkSize/4, m = 0;
-		for (std::vector<D3DS::Face>::iterator i =  mMesh.mFaces.begin();
-			 m != num;++i, ++m)
-		{
+		for (std::vector<D3DS::Face>::iterator i =  mMesh.mFaces.begin(); m != num;++i, ++m)	{
 			// nth bit is set for nth smoothing group
 			(*i).iSmoothGroup = stream->GetI4();
 		}}
@@ -956,26 +950,15 @@ void Discreet3DSImporter::ParseFaceChunk()
 
 		// find the index of the material
 		unsigned int idx = 0xcdcdcdcd, cnt = 0;
-		for (std::vector<D3DS::Material>::const_iterator
-			i =  mScene->mMaterials.begin();
-			i != mScene->mMaterials.end();++i,++cnt)
-		{
-			// compare case-independent to be sure it works
-			if ((*i).mName.length() && !ASSIMP_stricmp(sz, (*i).mName.c_str()))
-			{
+		for (std::vector<D3DS::Material>::const_iterator i =  mScene->mMaterials.begin();i != mScene->mMaterials.end();++i,++cnt)	{
+			// use case independent comparisons. hopefully it will work.
+			if ((*i).mName.length() && !ASSIMP_stricmp(sz, (*i).mName.c_str()))	{
 				idx = cnt;
 				break;
 			}
 		}
-		if (0xcdcdcdcd == idx)
-		{
+		if (0xcdcdcdcd == idx)	{
 			DefaultLogger::get()->error(std::string("3DS: Unknown material: ") + sz);
-
-			// --------------------------------------------------------------
-			// This material is not known. Ignore this. We will later
-			// assign the default material to all faces using *this*
-			// material. We use 0xcdcdcdcd as special value to indicate this.
-			// --------------------------------------------------------------
 		}
 
 		// Now continue and read all material indices
@@ -1013,8 +996,7 @@ void Discreet3DSImporter::ParseMeshChunk()
 		// This is the list of all vertices in the current mesh
 		int num = (int)(uint16_t)stream->GetI2();
 		mMesh.mPositions.reserve(num);
-		while (num-- > 0)
-		{
+		while (num-- > 0)	{
 			aiVector3D v;
 			v.x = stream->GetF4();
 			v.y = stream->GetF4();
@@ -1024,8 +1006,8 @@ void Discreet3DSImporter::ParseMeshChunk()
 		break;
 	case Discreet3DS::CHUNK_TRMATRIX:
 		{
-		// This is the RLEATIVE transformation matrix of the
-		// current mesh. However, all vertices are pretransformed
+		// This is the RLEATIVE transformation matrix of the current mesh. Vertices are
+		// pretransformed by this matrix wonder.
 		mMesh.mMat.a1 = stream->GetF4();
 		mMesh.mMat.b1 = stream->GetF4();
 		mMesh.mMat.c1 = stream->GetF4();
@@ -1046,8 +1028,7 @@ void Discreet3DSImporter::ParseMeshChunk()
 		// This is the list of all UV coords in the current mesh
 		int num = (int)(uint16_t)stream->GetI2();
 		mMesh.mTexCoords.reserve(num);
-		while (num-- > 0)
-		{
+		while (num-- > 0)	{
 			aiVector3D v;
 			v.x = stream->GetF4();
 			v.y = stream->GetF4();
@@ -1060,8 +1041,7 @@ void Discreet3DSImporter::ParseMeshChunk()
 		// This is the list of all faces in the current mesh
 		int num = (int)(uint16_t)stream->GetI2();
 		mMesh.mFaces.reserve(num);
-		while (num-- > 0)
-		{
+		while (num-- > 0)	{
 			// 3DS faces are ALWAYS triangles
 			mMesh.mFaces.push_back(D3DS::Face());
 			D3DS::Face& sFace = mMesh.mFaces.back();
@@ -1073,9 +1053,8 @@ void Discreet3DSImporter::ParseMeshChunk()
 			stream->IncPtr(2); // skip edge visibility flag
 		}
 
-		// Resize the material array (0xcdcdcdcd marks the
-		// default material; so if a face is not referenced
-		// by a material $$DEFAULT will be assigned to it)
+		// Resize the material array (0xcdcdcdcd marks the default material; so if a face is 
+		// not referenced by a material, $$DEFAULT will be assigned to it)
 		mMesh.mFaceMaterials.resize(mMesh.mFaces.size(),0xcdcdcdcd);
 
 		// Larger 3DS files could have multiple FACE chunks here
@@ -1095,21 +1074,18 @@ void Discreet3DSImporter::ParseMeshChunk()
 void Discreet3DSImporter::ParseMaterialChunk()
 {
 	ASSIMP_3DS_BEGIN_CHUNK();
-
-	// get chunk type
 	switch (chunk.Flag)
 	{
 	case Discreet3DS::CHUNK_MAT_MATNAME:
 
 		{
-		// The material name string is already zero-terminated, but
-		// we need to be sure ...
+		// The material name string is already zero-terminated, but we need to be sure ...
 		const char* sz = (const char*)stream->GetPtr();
 		unsigned int cnt = 0;
-		while (stream->GetI1())++cnt;
+		while (stream->GetI1())
+			++cnt;
 
-		if (!cnt)
-		{
+		if (!cnt)	{
 			// This may not be, we use the default name instead
 			DefaultLogger::get()->error("3DS: Empty material name");
 		}
@@ -1172,7 +1148,8 @@ void Discreet3DSImporter::ParseMaterialChunk()
 		*pcf = ParsePercentageChunk();
 
 		// NOTE: transparency, not opacity
-		if (is_qnan(*pcf))*pcf = 1.0f;
+		if (is_qnan(*pcf))
+			*pcf = 1.0f;
 		else *pcf = 1.0f - *pcf * (float)0xFFFF / 100.0f;
 		}
 		break;
@@ -1191,7 +1168,8 @@ void Discreet3DSImporter::ParseMaterialChunk()
 		{ // This is the shininess of the material
 		float* pcf = &mScene->mMaterials.back().mSpecularExponent;
 		*pcf = ParsePercentageChunk();
-		if (is_qnan(*pcf))*pcf = 0.0f;
+		if (is_qnan(*pcf))
+			*pcf = 0.0f;
 		else *pcf *= (float)0xFFFF;
 		}
 		break;
@@ -1200,7 +1178,8 @@ void Discreet3DSImporter::ParseMaterialChunk()
 		{ // This is the shininess strength of the material
 		float* pcf = &mScene->mMaterials.back().mShininessStrength;
 		*pcf = ParsePercentageChunk();
-		if (is_qnan(*pcf))*pcf = 0.0f;
+		if (is_qnan(*pcf))
+			*pcf = 0.0f;
 		else *pcf *= (float)0xffff / 100.0f;
 		}
 		break;
@@ -1208,7 +1187,8 @@ void Discreet3DSImporter::ParseMaterialChunk()
 	case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
 		{ // This is the self illumination strength of the material
 		float f = ParsePercentageChunk();
-		if (is_qnan(f))f = 0.0f;
+		if (is_qnan(f))
+			f = 0.0f;
 		else f *= (float)0xFFFF / 100.0f;
 		mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
 		}
@@ -1259,11 +1239,11 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
 	{
 	case Discreet3DS::CHUNK_MAPFILE:
 		{
-		// The material name string is already zero-terminated, but
-		// we need to be sure ...
+		// The material name string is already zero-terminated, but we need to be sure ...
 		const char* sz = (const char*)stream->GetPtr();
 		unsigned int cnt = 0;
-		while (stream->GetI1())++cnt;
+		while (stream->GetI1())
+			++cnt;
 		pcOut->mMapName = std::string(sz,cnt);
 		}
 		break;
@@ -1284,8 +1264,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
 		pcOut->mScaleU = stream->GetF4();
 		if (0.0f == pcOut->mScaleU)
 		{
-			DefaultLogger::get()->warn("Texture coordinate scaling in the "
-				"x direction is zero. Assuming 1");
+			DefaultLogger::get()->warn("Texture coordinate scaling in the x direction is zero. Assuming 1.");
 			pcOut->mScaleU = 1.0f;
 		}
 		break;
@@ -1294,8 +1273,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
 		pcOut->mScaleV = stream->GetF4();
 		if (0.0f == pcOut->mScaleV)
 		{
-			DefaultLogger::get()->warn("Texture coordinate scaling in the "
-				"y direction is zero. Assuming 1");
+			DefaultLogger::get()->warn("Texture coordinate scaling in the y direction is zero. Assuming 1.");
 			pcOut->mScaleV = 1.0f;
 		}
 		break;

+ 24 - 14
code/DXFLoader.cpp

@@ -112,7 +112,8 @@ bool DXFImporter::GetNextLine()
 {
 	if(!SkipLine(&buffer))
 		return false;
-	if(!SkipSpaces(&buffer))return GetNextLine();
+	if(!SkipSpaces(&buffer))
+		return GetNextLine();
 	else if (*buffer == '{')	{
 		// some strange meta data ...
 		while (true)
@@ -139,11 +140,12 @@ bool DXFImporter::GetNextToken()
 
 	SkipSpaces(&buffer);
 	groupCode = strtol10s(buffer,&buffer);
-	if(!GetNextLine())return false;
+	if(!GetNextLine())
+		return false;
 	
 	// copy the data line to a separate buffer
 	char* m = cursor, *end = &cursor[4096];
-	while (!IsLineEnd ( *buffer ) && m < end)
+	while (!IsSpaceOrNewLine( *buffer ) && m < end)
 		*m++ = *buffer++;
 	
 	*m = '\0';
@@ -163,7 +165,7 @@ void DXFImporter::InternReadFile( const std::string& pFile,
 		throw new ImportErrorException( "Failed to open DXF file " + pFile + "");
 
 	// read the contents of the file in a buffer
-	unsigned int m = (unsigned int)file->FileSize();
+	size_t m = file->FileSize();
 	std::vector<char> buffer2(m+1);
 	buffer = &buffer2[0];
 	file->Read( &buffer2[0], m,1);
@@ -182,13 +184,17 @@ void DXFImporter::InternReadFile( const std::string& pFile,
 		if (2 == groupCode)	{
 
 			// ENTITIES and BLOCKS sections - skip the whole rest, no need to waste our time with them
-			if (!::strcmp(cursor,"ENTITIES") || !::strcmp(cursor,"BLOCKS"))
-				if (!ParseEntities())break; else bRepeat = true;
+			if (!::strcmp(cursor,"ENTITIES") || !::strcmp(cursor,"BLOCKS")) {
+				if (!ParseEntities())
+					break; 
+				else bRepeat = true;
+			}
 
 			// other sections - skip them to make sure there will be no name conflicts
 			else	{
-				while (GetNextToken())	{
-					if (!groupCode && !::strcmp(cursor,"ENDSEC"))break;
+				while ( GetNextToken())	{
+					if (!::strcmp(cursor,"ENDSEC"))
+						break;
 				}
 			}
 		}
@@ -202,7 +208,8 @@ void DXFImporter::InternReadFile( const std::string& pFile,
 
 	// find out how many valud layers we have
 	for (std::vector<LayerInfo>::const_iterator it = mLayers.begin(),end = mLayers.end(); it != end;++it)	{
-		if (!(*it).vPositions.empty())++pScene->mNumMeshes;
+		if (!(*it).vPositions.empty())
+			++pScene->mNumMeshes;
 	}
 
 	if (!pScene->mNumMeshes)
@@ -476,8 +483,7 @@ bool DXFImporter::ParsePolyLineVertex(aiVector3D& out,aiColor4D& clr, unsigned i
 		case 0: ret = true;
 			break;
 
-		// todo - handle the correct layer for the vertex
-		// At the moment it is assumed that all vertices of 
+		// todo - handle the correct layer for the vertex. At the moment it is assumed that all vertices of 
 		// a polyline are placed on the same global layer.
 
 		// x position of the first corner
@@ -519,7 +525,9 @@ bool DXFImporter::Parse3DFace()
 
 	while (GetNextToken())	{
 		switch (groupCode)	{
-		case 0: ret = true;break;
+		case 0: 
+			ret = true;
+			break;
 
 		// 8 specifies the layer
 		case 8:	{
@@ -572,10 +580,12 @@ bool DXFImporter::Parse3DFace()
 		// color
 		case 62: clr = g_aclrDxfIndexColors[strtol10(cursor) % AI_DXF_NUM_INDEX_COLORS]; break;
 		};
-		if (ret)break;
+		if (ret)
+			break;
 	}
 
-	if (!bThird)vip[2] = vip[1];
+	if (!bThird)
+		vip[2] = vip[1];
 
 	// use a default layer if necessary
 	if (!out) {

+ 1 - 1
code/MD5Parser.cpp

@@ -115,7 +115,7 @@ void MD5Parser::ParseHeader()
 	SkipSpaces();
 	unsigned int iVer = ::strtol10(buffer,(const char**)&buffer);
 	if (10 != iVer)	{
-		ReportWarning("MD5 version tag is unknown (10 is expected)");
+		ReportError("MD5 version tag is unknown (10 is expected)");
 	}
 	SkipLine();
 

+ 1 - 1
mkutil/revision.h

@@ -1 +1 @@
-#define SVNRevision  369 
+#define SVNRevision  377