Bladeren bron

FIX: 3DS loader skips TCB keys correctly now.
Further work on 3DS light and camera support + target animation.
Removed obsolete files & directories.
AssimpPCH.h outputs the current build config now (MSVC only)
Simplified foreach workaround
Fixed compilation error in the DLL build

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

aramis_acg 16 jaren geleden
bovenliggende
commit
9b53b2aa1a

+ 27 - 8
code/3DSHelper.h

@@ -97,6 +97,16 @@ public:
 		Blinn = 0x5
 	} shadetype3ds;
 
+	// Flags for animated keys
+	enum
+	{
+		KEY_USE_TENS         = 0x1,
+		KEY_USE_CONT         = 0x2,
+		KEY_USE_BIAS         = 0x4,
+		KEY_USE_EASE_TO      = 0x8,
+		KEY_USE_EASE_FROM    = 0x10
+	} ;
+
 	enum 
 	{
 
@@ -283,8 +293,20 @@ public:
 		CHUNK_TRACKLIGHT	= 0xB005,
 		CHUNK_TRACKLIGTGT	= 0xB006,
 		CHUNK_TRACKSPOTL	= 0xB007,
-		CHUNK_FRAMES		= 0xB008
+		CHUNK_FRAMES		= 0xB008,
 		// ********************************************************************
+
+		// light sub-chunks
+		CHUNK_DL_OFF                 = 0x4620,
+		CHUNK_DL_OUTER_RANGE         = 0x465A,
+		CHUNK_DL_INNER_RANGE         = 0x4659,
+		CHUNK_DL_MULTIPLIER          = 0x465B,
+		CHUNK_DL_EXCLUDE             = 0x4654,
+		CHUNK_DL_ATTENUATE           = 0x4625,
+		CHUNK_DL_SPOTLIGHT           = 0x4610,
+
+		// camera sub-chunks
+		CHUNK_CAM_RANGES             = 0x4720
 	};
 };
 
@@ -347,9 +369,7 @@ struct Material
 	mShading(Discreet3DS::Gouraud),
 	mTransparency		(1.0f),
 	mBumpHeight			(1.0f),
-	mTwoSided			(false),
-	iBakeUVTransform	(0),
-	pcSingleTexture		(NULL)
+	mTwoSided			(false)
 	{
 		static int iCnt = 0;
 		
@@ -395,10 +415,6 @@ struct Material
 	Texture sTexAmbient;
 	//! True if the material must be rendered from two sides
 	bool mTwoSided;
-
-	//! Used internally
-	unsigned int iBakeUVTransform;
-	Texture* pcSingleTexture;
 };
 
 // ---------------------------------------------------------------------------
@@ -451,6 +467,9 @@ struct aiFloatKey
 	bool operator < (const aiFloatKey& o) const
 		{return mTime < o.mTime;}
 
+	bool operator > (const aiFloatKey& o) const
+		{return mTime < o.mTime;}
+
 #endif
 };
 

+ 156 - 151
code/3DSLoader.cpp

@@ -236,7 +236,6 @@ void Discreet3DSImporter::ParseMainChunk()
 	};
 
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseMainChunk();
 }
@@ -271,7 +270,6 @@ void Discreet3DSImporter::ParseEditorChunk()
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseEditorChunk();
 }
@@ -310,43 +308,32 @@ void Discreet3DSImporter::ParseObjectChunk()
 		if (is_qnan(mClrAmbient.r))
 		{
 			// We failed to read the ambient base color.
-			// Set it to black so it won't have affect
-			// the rendering 
-			mClrAmbient.r = 0.0f;
-			mClrAmbient.g = 0.0f;
-			mClrAmbient.b = 0.0f;
+			DefaultLogger::get()->error("3DS: Failed to read ambient base color");
+			mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f;
 		}
 		break;
 
 	case Discreet3DS::CHUNK_BIT_MAP:
 		{
-		// Specifies the background image. The string
-		// should already be properly 0 terminated but we
-		// need to be sure
+		// Specifies the background image. The string should already be 
+		// properly 0 terminated but we need to be sure
 		unsigned int cnt = 0;
 		const char* sz = (const char*)stream->GetPtr();
 		while (stream->GetI1())++cnt;
-
 		mBackgroundImage = std::string(sz,cnt);
 		}
 		break;
 
-
 	case Discreet3DS::CHUNK_BIT_MAP_EXISTS:
 		bHasBG = true;
 		break;
 
-
 	case Discreet3DS::CHUNK_MASTER_SCALE:
-
 		// Scene master scaling factor
 		mMasterScale = stream->GetF4();
 		break;
-
-
 	};
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseObjectChunk();
 }
@@ -386,23 +373,15 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
 		light->mPosition.y = stream->GetF4();
 		light->mPosition.z = stream->GetF4();
 
+		light->mColorDiffuse = aiColor3D(1.f,1.f,1.f);
+
 		// Now check for further subchunks (excluding color)
 		int8_t* p = stream->GetPtr();
 		ParseLightChunk();
 
-		// Now read the color
-		stream->SetPtr(p);
-		ParseColorChunk(&light->mColorDiffuse,true);
-		if (is_qnan(light->mColorDiffuse.r))
-		{
-			// it could be there is no color subchunk
-			light->mColorDiffuse = aiColor3D(1.f,1.f,1.f);
-		}
-
-		// The specular light color is identical to
-		// the diffuse light color. The ambient light
-		// color is equal to the ambient base color of
-		// the whole scene.
+		// The specular light color is identical the the diffuse light
+		// color. The ambient light color is equal to the ambient base 
+		// color of the whole scene.
 		light->mColorSpecular = light->mColorDiffuse;
 		light->mColorAmbient  = mClrAmbient;
 
@@ -421,10 +400,11 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
 
 		camera->mName.Set(std::string(name, num));
 
-		// The camera position and look-at vector are
-		// difficult to handle. Later we'll copy these
-		// values to the local transformation of the
-		// camera's node.
+		// 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();
@@ -435,8 +415,6 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
 		camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
 		camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
 		camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
-
-		// We wouldn't need to normalize here, but we do it
 		camera->mLookAt.Normalize();
 
 		// And finally - the camera rotation angle, in
@@ -446,13 +424,13 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
 		camera->mUp = quat.GetMatrix() * aiVector3D(0.f,1.f,0.f);
 
 		// Read the lense angle
-		// TODO
 		camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() );
+		if (camera->mHorizontalFOV < 0.001f)
+			camera->mHorizontalFOV = AI_DEG_TO_RAD(45.f);
 		}
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseChunk(name,num);
 }
@@ -467,32 +445,67 @@ void Discreet3DSImporter::ParseLightChunk()
 	switch (chunk.Flag)
 	{
 	case Discreet3DS::CHUNK_SPOTLIGHT:
-		{
-			// Now we can be sure that the light is a spot light
-			light->mType = aiLightSource_SPOT;
+		// Now we can be sure that the light is a spot light
+		light->mType = aiLightSource_SPOT;
 
-			// We wouldn't need to normalize here, but we do it
-			light->mDirection.x = stream->GetF4() - light->mPosition.x;
-			light->mDirection.y = stream->GetF4() - light->mPosition.y;
-			light->mDirection.z = stream->GetF4() - light->mPosition.z;
-			light->mDirection.Normalize();
+		// We wouldn't need to normalize here, but we do it
+		light->mDirection.x = stream->GetF4() - light->mPosition.x;
+		light->mDirection.y = stream->GetF4() - light->mPosition.y;
+		light->mDirection.z = stream->GetF4() - light->mPosition.z;
+		light->mDirection.Normalize();
 
-			// Now the hotspot and falloff angles - in degrees
-			light->mAngleInnerCone = AI_DEG_TO_RAD( stream->GetF4() );
-			light->mAngleOuterCone = AI_DEG_TO_RAD( stream->GetF4() );
+		// Now the hotspot and falloff angles - in degrees
+		light->mAngleInnerCone = AI_DEG_TO_RAD( stream->GetF4() );
 
-			// We assume linear attenuation
-			light->mAttenuationLinear = 1;
-		}
+		// FIX: the falloff angle is just an offset
+		light->mAngleOuterCone = light->mAngleInnerCone+AI_DEG_TO_RAD( stream->GetF4() );
 		break; 
+
+		// intensity multiplier
+	case Discreet3DS::CHUNK_DL_MULTIPLIER:
+		light->mColorDiffuse = light->mColorDiffuse * stream->GetF4();
+		break;
+
+		// light color
+	case Discreet3DS::CHUNK_RGBF:
+	case Discreet3DS::CHUNK_LINRGBF:
+		light->mColorDiffuse.r *= stream->GetF4();
+		light->mColorDiffuse.g *= stream->GetF4();
+		light->mColorDiffuse.b *= stream->GetF4();
+		break;
+
+		// light attenuation
+	case Discreet3DS::CHUNK_DL_ATTENUATE: 
+		light->mAttenuationLinear = stream->GetF4();
+		break;
 	};
 
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseLightChunk();
 }
 
+// ------------------------------------------------------------------------------------------------
+void Discreet3DSImporter::ParseCameraChunk()
+{
+	ASSIMP_3DS_BEGIN_CHUNK();
+	aiCamera* camera = mScene->mCameras.back();
+
+	// get chunk type
+	switch (chunk.Flag)
+	{
+		// near and far clip plane
+	case Discreet3DS::CHUNK_CAM_RANGES:
+		camera->mClipPlaneNear = stream->GetF4();
+		camera->mClipPlaneFar  = stream->GetF4();
+		break;
+	}
+
+	ASSIMP_3DS_END_CHUNK();
+	// recursively continue processing this hierarchy level
+	return ParseCameraChunk();
+}
+
 // ------------------------------------------------------------------------------------------------
 void Discreet3DSImporter::ParseKeyframeChunk()
 {
@@ -558,6 +571,34 @@ bool KeyUniqueCompare(const T& first, const T& second)
 	return first.mTime == second.mTime;
 }
 
+// ------------------------------------------------------------------------------------------------
+void Discreet3DSImporter::SkipTCBInfo()
+{
+	unsigned int flags = stream->GetI2();
+
+	if (!flags)
+	{
+		// ******************************************************************
+		// Currently we can't do anything with these values. They occur
+		// quite rare, so it wouldn't be worth the effort implementing
+		// them. 3DS ist not really suitable for complex animations,
+		// so full support is not required.
+		// ******************************************************************
+		DefaultLogger::get()->warn("3DS: Skipping TCB animation info");
+	}
+
+	if (flags & Discreet3DS::KEY_USE_TENS)
+		stream->IncPtr(4);
+	if (flags & Discreet3DS::KEY_USE_BIAS)
+		stream->IncPtr(4);
+	if (flags & Discreet3DS::KEY_USE_CONT)
+		stream->IncPtr(4);
+	if (flags & Discreet3DS::KEY_USE_EASE_FROM)
+		stream->IncPtr(4);
+	if (flags & Discreet3DS::KEY_USE_EASE_TO)
+		stream->IncPtr(4);
+}
+
 // ------------------------------------------------------------------------------------------------
 void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 {
@@ -661,15 +702,13 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 	case Discreet3DS::CHUNK_TRACKPOS:
 		{
 		stream->IncPtr(10);
-		unsigned int numFrames = stream->GetI2();
-		stream->IncPtr(2);
+		const unsigned int numFrames = stream->GetI4();
 		bool sortKeys = false;
 
 		// 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;
 		}
@@ -678,13 +717,13 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		l->reserve(numFrames);
 		for (unsigned int i = 0; i < numFrames;++i)
 		{
-			unsigned int fidx = stream->GetI2();
+			const unsigned int fidx = stream->GetI4();
 
 			// Setup a new position key
 			aiVectorKey v;
 			v.mTime = (double)fidx;
 
-			stream->IncPtr(4);
+			SkipTCBInfo();
 			v.mValue.x = stream->GetF4();
 			v.mValue.y = stream->GetF4();
 			v.mValue.z = stream->GetF4();
@@ -697,12 +736,11 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 			l->push_back(v);
 		}
 
-		// Sort all keys with ascending time values?
+		// Sort all keys with ascending time values and remove duplicates?
 		if (sortKeys)
 		{
-			std::sort   (l->begin(),l->end());
-			std::unique (l->begin(),l->end(),
-				std::ptr_fun(&KeyUniqueCompare<aiVectorKey>));
+			std::stable_sort(l->begin(),l->end());
+			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
 		}}
 
 		break;
@@ -721,20 +759,18 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 		std::vector<aiFloatKey>* l = &mCurrentNode->aCameraRollKeys;
 
 		stream->IncPtr(10);
-		unsigned int numFrames = stream->GetI2();
+		const unsigned int numFrames = stream->GetI4();
 		l->reserve(numFrames);
-		stream->IncPtr(2);
-
 		for (unsigned int i = 0; i < numFrames;++i)
 		{
-			unsigned int fidx = stream->GetI2();
+			const unsigned int fidx = stream->GetI4();
 
 			// Setup a new position key
 			aiFloatKey v;
 			v.mTime = (double)fidx;
 
 			// This is just a single float 
-			stream->IncPtr(4);
+			SkipTCBInfo();
 			v.mValue = stream->GetF4();
 
 			// Check whether we'll need to sort the keys
@@ -745,12 +781,11 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 			l->push_back(v);
 		}
 
-		// Sort all keys with ascending time values?
+		// Sort all keys with ascending time values and remove duplicates?
 		if (sortKeys)
 		{
-			std::sort   (l->begin(),l->end());
-			std::unique (l->begin(),l->end(),
-				std::ptr_fun(&KeyUniqueCompare<aiFloatKey>));
+			std::stable_sort(l->begin(),l->end());
+			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiFloatKey>), l->end() );
 		}}
 		break;
 
@@ -770,8 +805,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 	case Discreet3DS::CHUNK_TRACKROTATE:
 		{
 		stream->IncPtr(10);
-		unsigned int numFrames = stream->GetI2();
-		stream->IncPtr(2);
+		const unsigned int numFrames = stream->GetI4();
 
 		bool sortKeys = false;
 		std::vector<aiQuatKey>* l = &mCurrentNode->aRotationKeys;
@@ -779,15 +813,14 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 
 		for (unsigned int i = 0; i < numFrames;++i)
 		{
-			unsigned int fidx = stream->GetI2();
-
-			stream->IncPtr(4);
+			const unsigned int fidx = stream->GetI4();
+			SkipTCBInfo();
 
 			aiQuatKey v;
 			v.mTime = (double)fidx;
 
 			// The rotation keyframe is given as an axis-angle pair
-			float rad = stream->GetF4();
+			const float rad = stream->GetF4();
 			aiVector3D axis;
 			axis.x = stream->GetF4();
 			axis.y = stream->GetF4();
@@ -806,12 +839,11 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 			// add the new keyframe to the list
 			l->push_back(v);
 		}
-		// Sort all keys with ascending time values?
+		// Sort all keys with ascending time values and remove duplicates?
 		if (sortKeys)
 		{
-			std::sort   (l->begin(),l->end());
-			std::unique (l->begin(),l->end(),
-				std::ptr_fun(&KeyUniqueCompare<aiQuatKey>));
+			std::stable_sort(l->begin(),l->end());
+			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiQuatKey>), l->end() );
 		}}
 		break;
 
@@ -820,7 +852,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 	case Discreet3DS::CHUNK_TRACKSCALE:
 		{
 		stream->IncPtr(10);
-		unsigned int numFrames = stream->GetI2();
+		const unsigned int numFrames = stream->GetI2();
 		stream->IncPtr(2);
 
 		bool sortKeys = false;
@@ -829,8 +861,8 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 
 		for (unsigned int i = 0; i < numFrames;++i)
 		{
-			unsigned int fidx = stream->GetI2();
-			stream->IncPtr(4);
+			const unsigned int fidx = stream->GetI4();
+			SkipTCBInfo();
 
 			// Setup a new key
 			aiVectorKey v;
@@ -852,18 +884,16 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 
 			l->push_back(v);
 		}
-		// Sort all keys with ascending time values?
+		// Sort all keys with ascending time values and remove duplicates?
 		if (sortKeys)
 		{
-			std::sort   (l->begin(),l->end());
-			std::unique (l->begin(),l->end(),
-				std::ptr_fun(&KeyUniqueCompare<aiVectorKey>));
+			std::stable_sort(l->begin(),l->end());
+			l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
 		}}
 		break;
 	};
 
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseHierarchyChunk(parent);
 }
@@ -916,12 +946,11 @@ void Discreet3DSImporter::ParseFaceChunk()
 		{
 			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. Use 0xcdcdcdcd as special value to indicate
-			// this.
-			// *********************************************************
+			// material. We use 0xcdcdcdcd as special value to indicate this.
+			// ******************************************************************
 		}
 
 		// Now continue and read all material indices
@@ -940,7 +969,6 @@ void Discreet3DSImporter::ParseFaceChunk()
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseFaceChunk();
 }
@@ -1062,7 +1090,6 @@ void Discreet3DSImporter::ParseMeshChunk()
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseMeshChunk();
 }
@@ -1101,7 +1128,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
 		if (is_qnan(pc->r))
 		{
 			// color chunk is invalid. Simply ignore it
-			DefaultLogger::get()->error("Unable to read DIFFUSE chunk");
+			DefaultLogger::get()->error("3DS: Unable to read DIFFUSE chunk");
 			pc->r = pc->g = pc->b = 1.0f;
 		}}
 		break;
@@ -1114,7 +1141,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
 		if (is_qnan(pc->r))
 		{
 			// color chunk is invalid. Simply ignore it
-			DefaultLogger::get()->error("Unable to read SPECULAR chunk");
+			DefaultLogger::get()->error("3DS: Unable to read SPECULAR chunk");
 			pc->r = pc->g = pc->b = 1.0f;
 		}}
 		break;
@@ -1127,7 +1154,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
 		if (is_qnan(pc->r))
 		{
 			// color chunk is invalid. Simply ignore it
-			DefaultLogger::get()->error("Unable to read AMBIENT chunk");
+			DefaultLogger::get()->error("3DS: Unable to read AMBIENT chunk");
 			pc->r = pc->g = pc->b = 0.0f;
 		}}
 		break;
@@ -1140,7 +1167,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
 		if (is_qnan(pc->r))
 		{
 			// color chunk is invalid. Simply ignore it
-			DefaultLogger::get()->error("Unable to read EMISSIVE chunk");
+			DefaultLogger::get()->error("3DS: Unable to read EMISSIVE chunk");
 			pc->r = pc->g = pc->b = 0.0f;
 		}}
 		break;
@@ -1187,11 +1214,10 @@ void Discreet3DSImporter::ParseMaterialChunk()
 
 	case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
 		{ // This is the self illumination strength of the material
-		// TODO: need to multiply with emissive base color?
-		float* pcf = &mScene->mMaterials.back().sTexEmissive.mTextureBlend;
-		*pcf = ParsePercentageChunk();
-		if (is_qnan(*pcf))*pcf = 0.0f;
-		else *pcf = *pcf * (float)0xFFFF / 100.0f;
+		float f = ParsePercentageChunk();
+		if (is_qnan(f))f = 0.0f;
+		else f *= (float)0xFFFF / 100.0f;
+		mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
 		}
 		break;
 
@@ -1221,14 +1247,12 @@ void Discreet3DSImporter::ParseMaterialChunk()
 		ParseTextureChunk(&mScene->mMaterials.back().sTexEmissive);
 		break;
 	case Discreet3DS::CHUNK_MAT_REFLMAP:
-
 		// Reflection map - no support in Assimp
 		DefaultLogger::get()->warn("3DS: Found reflection map in file. This is not supported");
 
 		break;
 	};
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseMaterialChunk();
 }
@@ -1301,7 +1325,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
 
 	case Discreet3DS::CHUNK_MAT_MAP_TILING:
 		{
-		uint16_t iFlags = stream->GetI2();
+		const uint16_t iFlags = stream->GetI2();
 
 		// Get the mapping mode (for both axes)
 		if (iFlags & 0x2u)
@@ -1317,7 +1341,6 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
 	};
 
 	ASSIMP_3DS_END_CHUNK();
-
 	// recursively continue processing this hierarchy level
 	return ParseTextureChunk(pcOut);
 }
@@ -1330,28 +1353,22 @@ float Discreet3DSImporter::ParsePercentageChunk()
 	ReadChunk(&chunk);
 
 	if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag)
-	{
 		return stream->GetF4();
-	}
 	else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag)
-	{
 		return (float)((uint16_t)stream->GetI2()) / (float)0xFFFF;
-	}
 	return std::numeric_limits<float>::quiet_NaN();
 }
 
 // ------------------------------------------------------------------------------------------------
-// Read a color chunk. If a percentage chunk is found instead, it will be converted
-// to a grayscale color value
-void Discreet3DSImporter::ParseColorChunk(aiColor3D* p_pcOut,
-	bool p_bAcceptPercent)
+// Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
+void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
+	bool acceptPercent)
 {
-	ai_assert(p_pcOut != NULL);
+	ai_assert(out != NULL);
 
 	// error return value
-	static const aiColor3D clrError = aiColor3D(std::numeric_limits<float>::quiet_NaN(),
-		std::numeric_limits<float>::quiet_NaN(),
-		std::numeric_limits<float>::quiet_NaN());
+	const float qnan = std::numeric_limits<float>::quiet_NaN();
+	static const aiColor3D clrError = aiColor3D(qnan,qnan,qnan);
 
 	Discreet3DS::Chunk chunk;
 	ReadChunk(&chunk);
@@ -1368,12 +1385,12 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* p_pcOut,
 	case Discreet3DS::CHUNK_RGBF:
 		if (sizeof(float) * 3 > diff)
 		{
-			*p_pcOut = clrError;
+			*out = clrError;
 			return;
 		}
-		p_pcOut->r = stream->GetF4();
-		p_pcOut->g = stream->GetF4();
-		p_pcOut->b = stream->GetF4();
+		out->r = stream->GetF4();
+		out->g = stream->GetF4();
+		out->b = stream->GetF4();
 		break;
 
 	case Discreet3DS::CHUNK_LINRGBB:
@@ -1381,49 +1398,37 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* p_pcOut,
 	case Discreet3DS::CHUNK_RGBB:
 		if (sizeof(char) * 3 > diff)
 		{
-			*p_pcOut = clrError;
+			*out = clrError;
 			return;
 		}
-		p_pcOut->r = (float)(uint8_t)stream->GetI1() / 255.0f;
-		p_pcOut->g = (float)(uint8_t)stream->GetI1() / 255.0f;
-		p_pcOut->b = (float)(uint8_t)stream->GetI1() / 255.0f;
+		out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
+		out->g = (float)(uint8_t)stream->GetI1() / 255.0f;
+		out->b = (float)(uint8_t)stream->GetI1() / 255.0f;
 		break;
 
-	// Percentage chunks: accepted to be compatible with various
-	// .3ds files with very curious content
+	// Percentage chunks are accepted, too.
 	case Discreet3DS::CHUNK_PERCENTF:
-		if (p_bAcceptPercent && 4 <= diff)
+		if (acceptPercent && 4 <= diff)
 		{
-			p_pcOut->r = stream->GetF4();
-			p_pcOut->g = p_pcOut->b = p_pcOut->r;
+			out->g = out->b = out->r = stream->GetF4();
 			break;
 		}
-		*p_pcOut = clrError;
+		*out = clrError;
 		return;
 
 	case Discreet3DS::CHUNK_PERCENTW:
-		if (p_bAcceptPercent && 1 <= diff)
+		if (acceptPercent && 1 <= diff)
 		{
-			p_pcOut->r = (float)(uint8_t)stream->GetI1() / 255.0f;
-			p_pcOut->g = p_pcOut->b = p_pcOut->r;
+			out->g = out->b = out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
 			break;
 		}
-		*p_pcOut = clrError;
+		*out = clrError;
 		return;
 
 	default:
+		stream->IncPtr(diff);
 
-		// skip unknown chunks, hope this won't cause any problems.
-		return ParseColorChunk(p_pcOut,p_bAcceptPercent);
+		// Skip unknown chunks, hope this won't cause any problems.
+		return ParseColorChunk(out,acceptPercent);
 	};
-
-	// Do a gamma correction ... I'm not sure whether this is correct
-	// or not but I'm too tired now to think of it
-	if (bGamma)
-	{
-		p_pcOut->r = powf(p_pcOut->r, 1.0f / 2.2f);
-		p_pcOut->g = powf(p_pcOut->g, 1.0f / 2.2f);
-		p_pcOut->b = powf(p_pcOut->b, 1.0f / 2.2f);
-	}
-	return;
 }

+ 10 - 0
code/3DSLoader.h

@@ -176,6 +176,11 @@ protected:
 	*/
 	void ParseLightChunk();
 
+	// -------------------------------------------------------------------
+	/** Parse a camera chunk in the file
+	*/
+	void ParseCameraChunk();
+
 	// -------------------------------------------------------------------
 	/** Parse a face list chunk in the file
 	*/
@@ -238,6 +243,11 @@ protected:
 	*/
 	void CheckIndices(D3DS::Mesh& sMesh);
 
+	// -------------------------------------------------------------------
+	/** Skip the TCB info in a track key
+	*/
+	void SkipTCBInfo();
+
 protected:
 
 	/** Stream to read from */

+ 18 - 0
code/AssimpPCH.h

@@ -44,6 +44,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define ASSIMP_INTERNAL_BUILD
 
+#ifdef ASSIMP_BUILD_DLL_EXPORT
+#	if _MSC_VER >= 1400
+#		pragma message( "AssimpBuild: Building Windows DLL" )
+#	endif
+#endif
+
 // *******************************************************************
 // Print detailled memory allocation statistics? In this case we'll
 // need to overload all C++ memory management functions. It is assumed
@@ -56,6 +62,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	void *operator new[] (size_t);     
 	void operator delete[] (void *);
 
+#	if _MSC_VER >= 1400
+#		pragma message( "AssimpBuild: Memory tracking enabled" )
+#	endif
+
+#endif
+
+#if _MSC_VER >= 1400
+#	ifdef _DEBUG
+#		pragma message( "AssimpBuild: Debug build" )
+#	else
+#		pragma message( "AssimpBuild: Release build" )
+#	endif
 #endif
 
 // *******************************************************************

BIN
doc/ImporterNotes.rtf


+ 9 - 0
doc/datastructure.xml

@@ -11,6 +11,15 @@
     <childnode />
     <childnode />
   </node>
+
+  <cameras>
+    <camera up="0,1,0" lookat="0,0,1" fov="45"/>
+  </cameras>
+
+  <lights>
+    <light diffuse="black" type="spot" phi="5" theta="15"/>
+  </lights>
+  
   <meshes>
     <mesh id="0">
       <meshheader type="MatID, Vertexcount, Facecount, a.s.o." />

+ 0 - 22
include/BoostWorkaround/boost/foreach.hpp

@@ -56,28 +56,6 @@ auto_any<typename T::const_iterator> end(T const& t)
     return t.end();
 }
 
-
-// const_iterator
-template<typename T>
-bool done(auto_any_base const& cur, auto_any_base const& end, T const&)
-{
-    typedef typename T::const_iterator iter_type;
-    return auto_any_cast<iter_type>(cur) == auto_any_cast<iter_type>(end);
-}
-
-template<typename T>
-void next(auto_any_base const& cur, T const&)
-{
-   ++auto_any_cast<typename T::const_iterator>(cur);
-}
-
-template<typename T>
-typename T::const_reference deref(auto_any_base const& cur, T const&)
-{
-    return *auto_any_cast<typename T::const_iterator>(cur);
-}
-
-
 // iterator
 template<typename T>
 bool done(auto_any_base const& cur, auto_any_base const& end, T&)

+ 5 - 0
include/aiAnim.h

@@ -74,6 +74,9 @@ struct aiVectorKey
 	bool operator < (const aiVectorKey& o) const
 		{return mTime < o.mTime;}
 
+	bool operator > (const aiVectorKey& o) const
+		{return mTime > o.mTime;}
+
 
 #endif
 };
@@ -103,6 +106,8 @@ struct aiQuatKey
 	bool operator < (const aiQuatKey& o) const
 		{return mTime < o.mTime;}
 
+	bool operator > (const aiQuatKey& o) const
+		{return mTime < o.mTime;}
 
 
 #endif

+ 1 - 1
include/assimp.hpp

@@ -74,7 +74,7 @@ namespace Assimp
 
 struct aiScene;
 struct aiFileIO;
-extern "C" const aiScene* aiImportFileEx( const char*, unsigned int, aiFileIO*);
+extern "C" ASSIMP_API const aiScene* aiImportFileEx( const char*, unsigned int, aiFileIO*);
 
 namespace Assimp
 {

+ 0 - 4
workspaces/vc8/assimp.vcproj

@@ -2178,10 +2178,6 @@
 				RelativePath="..\..\doc\dox.h"
 				>
 			</File>
-			<File
-				RelativePath="..\..\doc\ImporterNotes.rtf"
-				>
-			</File>
 			<File
 				RelativePath="..\..\doc\Preamble.txt"
 				>