Bläddra i källkod

Changing 3DS parsing routines to work iteratively instead of recursively. This hopefully avoids unwanted stack overflowing with deeply-nested model hierarchies.
Updating revision number.

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

aramis_acg 16 år sedan
förälder
incheckning
2d994c514c
2 ändrade filer med 45 tillägg och 74 borttagningar
  1. 44 73
      code/3DSLoader.cpp
  2. 1 1
      mkutil/revision.h

+ 44 - 73
code/3DSLoader.cpp

@@ -58,13 +58,15 @@ using namespace Assimp;
 // - Reads the current chunk and validates it
 // - computes its length
 #define ASSIMP_3DS_BEGIN_CHUNK()                                         \
-	if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk))  \
+	while (true) {                                                       \
+	if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)){ \
 		return;                                                          \
+	}                                                                    \
 	Discreet3DS::Chunk chunk;                                            \
 	ReadChunk(&chunk);                                                   \
 	int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk);	             \
 	const int oldReadLimit = stream->GetReadLimit();                     \
-	stream->SetReadLimit(stream->GetCurrentPos() + chunkSize);		 
+	stream->SetReadLimit(stream->GetCurrentPos() + chunkSize);           \
 	
 
 // ------------------------------------------------------------------------------------------------
@@ -74,7 +76,8 @@ using namespace Assimp;
 	stream->SkipToReadLimit();                  \
 	stream->SetReadLimit(oldReadLimit);         \
 	if (stream->GetRemainingSizeToLimit() == 0) \
-		return;
+		return;                                 \
+	}
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
@@ -284,8 +287,6 @@ void Discreet3DSImporter::ParseEditorChunk()
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseEditorChunk();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -348,8 +349,6 @@ void Discreet3DSImporter::ParseObjectChunk()
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseObjectChunk();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -443,18 +442,17 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
 
 		// Read the lense angle
 		camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() );
-		if (camera->mHorizontalFOV < 0.001f)
+		if (camera->mHorizontalFOV < 0.001f)  {
 			camera->mHorizontalFOV = AI_DEG_TO_RAD(45.f);
 		}
 
 		// Now check for further subchunks 
-		if (!bIsPrj) /* fixme */
+		if (!bIsPrj) /* fixme */ {
 			ParseCameraChunk();
+		}}
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseChunk(name,num);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -503,8 +501,6 @@ void Discreet3DSImporter::ParseLightChunk()
 	};
 
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseLightChunk();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -524,8 +520,6 @@ void Discreet3DSImporter::ParseCameraChunk()
 	}
 
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseCameraChunk();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -549,9 +543,6 @@ void Discreet3DSImporter::ParseKeyframeChunk()
 	};
 
 	ASSIMP_3DS_END_CHUNK();
-
-	// recursively continue processing this hierarchy level
-	return ParseKeyframeChunk();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -564,9 +555,9 @@ void Discreet3DSImporter::InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCur
 	}
 
 	if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos)	{
-		if(pcCurrent->mParent)
+		if(pcCurrent->mParent) {
 			pcCurrent->mParent->push_back(pcNode);
-
+		}
 		else pcCurrent->push_back(pcNode);
 		return;
 	}
@@ -609,16 +600,21 @@ void Discreet3DSImporter::SkipTCBInfo()
 		DefaultLogger::get()->warn("3DS: Skipping TCB animation info");
 	}
 
-	if (flags & Discreet3DS::KEY_USE_TENS)
+	if (flags & Discreet3DS::KEY_USE_TENS) {
 		stream->IncPtr(4);
-	if (flags & Discreet3DS::KEY_USE_BIAS)
+	}
+	if (flags & Discreet3DS::KEY_USE_BIAS) {
 		stream->IncPtr(4);
-	if (flags & Discreet3DS::KEY_USE_CONT)
+	}
+	if (flags & Discreet3DS::KEY_USE_CONT) {
 		stream->IncPtr(4);
-	if (flags & Discreet3DS::KEY_USE_EASE_FROM)
+	}
+	if (flags & Discreet3DS::KEY_USE_EASE_FROM) {
 		stream->IncPtr(4);
-	if (flags & Discreet3DS::KEY_USE_EASE_TO)
+	}
+	if (flags & Discreet3DS::KEY_USE_EASE_TO) {
 		stream->IncPtr(4);
+	}
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -664,20 +660,19 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		pcNode->mHierarchyIndex = mLastNodeIndex;
 
 		// And find a proper position in the graph for it
-		if (mCurrentNode && mCurrentNode->mHierarchyPos == hierarchy) 
-		{
+		if (mCurrentNode && mCurrentNode->mHierarchyPos == hierarchy)	{
+
 			// add to the parent of the last touched node
 			mCurrentNode->mParent->push_back(pcNode);
 			mLastNodeIndex++;	
 		}
-		else if(hierarchy >= mLastNodeIndex)
-		{
+		else if(hierarchy >= mLastNodeIndex)	{
+
 			// place it at the current position in the hierarchy
 			mCurrentNode->push_back(pcNode);
 			mLastNodeIndex = hierarchy;
 		}
-		else
-		{
+		else	{
 			// need to go back to the specified position in the hierarchy.
 			InverseNodeSearch(pcNode,mCurrentNode);
 			mLastNodeIndex++;	
@@ -729,15 +724,13 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		// This could also be meant as the target position for
 		// (targeted) lights and cameras
 		std::vector<aiVectorKey>* l;
-		if ( Discreet3DS::CHUNK_TRACKCAMTGT == parent || Discreet3DS::CHUNK_TRACKLIGTGT == parent)
-		{
+		if ( Discreet3DS::CHUNK_TRACKCAMTGT == parent || Discreet3DS::CHUNK_TRACKLIGTGT == parent)	{
 			l = & mCurrentNode->aTargetPositionKeys;
 		}
 		else l = & mCurrentNode->aPositionKeys;
 
 		l->reserve(numFrames);
-		for (unsigned int i = 0; i < numFrames;++i)
-		{
+		for (unsigned int i = 0; i < numFrames;++i)	{
 			const unsigned int fidx = stream->GetI4();
 
 			// Setup a new position key
@@ -758,8 +751,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		}
 
 		// Sort all keys with ascending time values and remove duplicates?
-		if (sortKeys)
-		{
+		if (sortKeys)	{
 			std::stable_sort(l->begin(),l->end());
 			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
 		}}
@@ -771,8 +763,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 	case Discreet3DS::CHUNK_TRACKROLL:
 		{
 		// roll keys are accepted for cameras only
-		if (parent != Discreet3DS::CHUNK_TRACKCAMERA)
-		{
+		if (parent != Discreet3DS::CHUNK_TRACKCAMERA)	{
 			DefaultLogger::get()->warn("3DS: Ignoring roll track for non-camera object");
 			break;
 		}
@@ -782,8 +773,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		stream->IncPtr(10);
 		const unsigned int numFrames = stream->GetI4();
 		l->reserve(numFrames);
-		for (unsigned int i = 0; i < numFrames;++i)
-		{
+		for (unsigned int i = 0; i < numFrames;++i)	{
 			const unsigned int fidx = stream->GetI4();
 
 			// Setup a new position key
@@ -803,8 +793,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		}
 
 		// Sort all keys with ascending time values and remove duplicates?
-		if (sortKeys)
-		{
+		if (sortKeys)	{
 			std::stable_sort(l->begin(),l->end());
 			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiFloatKey>), l->end() );
 		}}
@@ -832,8 +821,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		std::vector<aiQuatKey>* l = &mCurrentNode->aRotationKeys;
 		l->reserve(numFrames);
 
-		for (unsigned int i = 0; i < numFrames;++i)
-		{
+		for (unsigned int i = 0; i < numFrames;++i)	{
 			const unsigned int fidx = stream->GetI4();
 			SkipTCBInfo();
 
@@ -861,8 +849,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 			l->push_back(v);
 		}
 		// Sort all keys with ascending time values and remove duplicates?
-		if (sortKeys)
-		{
+		if (sortKeys)	{
 			std::stable_sort(l->begin(),l->end());
 			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiQuatKey>), l->end() );
 		}}
@@ -880,8 +867,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		std::vector<aiVectorKey>* l = &mCurrentNode->aScalingKeys;
 		l->reserve(numFrames);
 
-		for (unsigned int i = 0; i < numFrames;++i)
-		{
+		for (unsigned int i = 0; i < numFrames;++i)	{
 			const unsigned int fidx = stream->GetI4();
 			SkipTCBInfo();
 
@@ -898,16 +884,15 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 			if (!l->empty() && v.mTime <= l->back().mTime)
 				sortKeys = true;
 			
-			// Remove zero-scalings
-			if (!v.mValue.x)v.mValue.x = 1.f;
-			if (!v.mValue.y)v.mValue.y = 1.f;
-			if (!v.mValue.z)v.mValue.z = 1.f;
+			// Remove zero-scalings on singular axes - they've been reported to be there erroneously in some strange files
+			if (!v.mValue.x) v.mValue.x = 1.f;
+			if (!v.mValue.y) v.mValue.y = 1.f;
+			if (!v.mValue.z) v.mValue.z = 1.f;
 
 			l->push_back(v);
 		}
 		// Sort all keys with ascending time values and remove duplicates?
-		if (sortKeys)
-		{
+		if (sortKeys)	{
 			std::stable_sort(l->begin(),l->end());
 			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
 		}}
@@ -915,8 +900,6 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 	};
 
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseHierarchyChunk(parent);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -975,8 +958,6 @@ void Discreet3DSImporter::ParseFaceChunk()
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseFaceChunk();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1065,8 +1046,6 @@ void Discreet3DSImporter::ParseMeshChunk()
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseMeshChunk();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1225,8 +1204,6 @@ void Discreet3DSImporter::ParseMaterialChunk()
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseMaterialChunk();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1311,8 +1288,6 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
 	};
 
 	ASSIMP_3DS_END_CHUNK();
-	// recursively continue processing this hierarchy level
-	return ParseTextureChunk(pcOut);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1353,8 +1328,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
 		bGamma = true;
 
 	case Discreet3DS::CHUNK_RGBF:
-		if (sizeof(float) * 3 > diff)
-		{
+		if (sizeof(float) * 3 > diff)	{
 			*out = clrError;
 			return;
 		}
@@ -1366,8 +1340,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
 	case Discreet3DS::CHUNK_LINRGBB:
 		bGamma = true;
 	case Discreet3DS::CHUNK_RGBB:
-		if (sizeof(char) * 3 > diff)
-		{
+		if (sizeof(char) * 3 > diff)	{
 			*out = clrError;
 			return;
 		}
@@ -1378,8 +1351,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
 
 	// Percentage chunks are accepted, too.
 	case Discreet3DS::CHUNK_PERCENTF:
-		if (acceptPercent && 4 <= diff)
-		{
+		if (acceptPercent && 4 <= diff)	{
 			out->g = out->b = out->r = stream->GetF4();
 			break;
 		}
@@ -1387,8 +1359,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
 		return;
 
 	case Discreet3DS::CHUNK_PERCENTW:
-		if (acceptPercent && 1 <= diff)
-		{
+		if (acceptPercent && 1 <= diff)	{
 			out->g = out->b = out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
 			break;
 		}

+ 1 - 1
mkutil/revision.h

@@ -1 +1 @@
-#define SVNRevision  423 
+#define SVNRevision  433