瀏覽代碼

# fix undefined behaviour in WriteDumb.cpp that would make our dumps include some padding bytes

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@955 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
aramis_acg 14 年之前
父節點
當前提交
9491b0c044
共有 2 個文件被更改,包括 115 次插入84 次删除
  1. 3 3
      tools/assimp_cmd/CompareDump.cpp
  2. 112 81
      tools/assimp_cmd/WriteDumb.cpp

+ 3 - 3
tools/assimp_cmd/CompareDump.cpp

@@ -642,9 +642,9 @@ void CompareOnTheFlyNodeAnim(comparer_context& comp)	{
 	comp.cmp<uint32_t>("mPreState");
 	comp.cmp<uint32_t>("mPostState");
 
-	comp.cmp_bounds<aiVector3D>("mPositionKeys");
-	comp.cmp_bounds<aiVector3D>("mRotationKeys");
-	comp.cmp_bounds<aiVector3D>("mScalingKeys");
+	comp.cmp_bounds<aiVectorKey>("mPositionKeys");
+	comp.cmp_bounds<aiQuatKey>("mRotationKeys");
+	comp.cmp_bounds<aiVectorKey>("mScalingKeys");
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////

+ 112 - 81
tools/assimp_cmd/WriteDumb.cpp

@@ -105,9 +105,15 @@ inline uint32_t WriteMagic(uint32_t magic)
 	return ftell(out)-4;
 }
 
+// use template specializations rather than regular overloading to be able to 
+// explicitly select the right 'overload' to leave no doubts on what is called,
+// retaining the possibility of letting the compiler select.
+template <typename T> uint32_t Write(const T&) {};
+
 // -----------------------------------------------------------------------------------
 // Serialize an aiString
-inline uint32_t WriteAiString(const aiString& s)
+template <>
+inline uint32_t Write<aiString>(const aiString& s)
 {
 	const uint32_t s2 = (uint32_t)s.length;
 	fwrite(&s,4,1,out);
@@ -117,7 +123,8 @@ inline uint32_t WriteAiString(const aiString& s)
 
 // -----------------------------------------------------------------------------------
 // Serialize an unsigned int as uint32_t
-inline uint32_t WriteInteger(unsigned int w)
+template <>
+inline uint32_t Write<unsigned int>(const unsigned int& w)
 {
 	const uint32_t t = (uint32_t)w;
 	fwrite(&t,4,1,out);
@@ -126,16 +133,17 @@ inline uint32_t WriteInteger(unsigned int w)
 
 // -----------------------------------------------------------------------------------
 // Serialize an unsigned int as uint16_t
-inline uint32_t WriteShort(unsigned int w)
+template <>
+inline uint32_t Write<uint16_t>(const uint16_t& w)
 {
-	const uint16_t t = (uint16_t)w;
-	fwrite(&t,2,1,out);
+	fwrite(&w,2,1,out);
 	return 2;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize a float
-inline uint32_t WriteFloat(float f)
+template <>
+inline uint32_t Write<float>(const float& f)
 {
 	fwrite(&f,4,1,out);
 	return 4;
@@ -143,7 +151,8 @@ inline uint32_t WriteFloat(float f)
 
 // -----------------------------------------------------------------------------------
 // Serialize a double
-inline uint32_t WriteDouble(double f)
+template <>
+inline uint32_t Write<double>(const double& f)
 {
 	fwrite(&f,8,1,out);
 	return 8;
@@ -151,7 +160,8 @@ inline uint32_t WriteDouble(double f)
 
 // -----------------------------------------------------------------------------------
 // Serialize a vec3
-inline uint32_t WriteVec3(const aiVector3D& v)
+template <>
+inline uint32_t Write<aiVector3D>(const aiVector3D& v)
 {
 	fwrite(&v,12,1,out);
 	return 12;
@@ -159,16 +169,35 @@ inline uint32_t WriteVec3(const aiVector3D& v)
 
 // -----------------------------------------------------------------------------------
 // Serialize a mat4x4
-inline uint32_t WriteMat4x4(const aiMatrix4x4& m)
+template <>
+inline uint32_t Write<aiMatrix4x4>(const aiMatrix4x4& m)
 {
 	for (unsigned int i = 0; i < 4;++i) {
 		for (unsigned int i2 = 0; i2 < 4;++i2) {
-			WriteFloat(m[i][i2]);
+			Write<float>(m[i][i2]);
 		}
 	}
 	return 64;
 }
 
+// -----------------------------------------------------------------------------------
+// Serialize an aiVectorKey
+template <>
+inline uint32_t Write<aiVectorKey>(const aiVectorKey& v)
+{
+	const uint32_t t = Write<double>(v.mTime);
+	return t + Write<aiVector3D>(v.mValue);
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize an aiQuatKey
+template <>
+inline uint32_t Write<aiQuatKey>(const aiQuatKey& v)
+{
+	const uint32_t t = Write<double>(v.mTime);
+	return t + Write<aiQuaternion>(v.mValue);
+}
+
 // -----------------------------------------------------------------------------------
 // Write the min/max values of an array of Ts to the file
 template <typename T>
@@ -176,11 +205,13 @@ inline uint32_t WriteBounds(const T* in, unsigned int size)
 {
 	T minc,maxc;
 	Assimp::ArrayBounds(in,size,minc,maxc);
-	fwrite(&minc,sizeof(T),1,out);
-	fwrite(&maxc,sizeof(T),1,out);
-	return sizeof(T)*2;
+
+	const uint32_t t = Write<T>(minc);
+	return t + Write<T>(maxc);
 }
 
+
+
 // -----------------------------------------------------------------------------------
 void ChangeInteger(uint32_t ofs,uint32_t n)
 {
@@ -194,13 +225,13 @@ void ChangeInteger(uint32_t ofs,uint32_t n)
 uint32_t WriteBinaryNode(const aiNode* node)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODE);
-	len += WriteAiString(node->mName);
-	len += WriteMat4x4(node->mTransformation);
-	len += WriteInteger(node->mNumChildren);
-	len += WriteInteger(node->mNumMeshes);
+	len += Write<aiString>(node->mName);
+	len += Write<aiMatrix4x4>(node->mTransformation);
+	len += Write<unsigned int>(node->mNumChildren);
+	len += Write<unsigned int>(node->mNumMeshes);
 
 	for (unsigned int i = 0; i < node->mNumMeshes;++i) {
-		len += WriteInteger(node->mMeshes[i]);
+		len += Write<unsigned int>(node->mMeshes[i]);
 	}
 
 	for (unsigned int i = 0; i < node->mNumChildren;++i) {
@@ -216,8 +247,8 @@ uint32_t WriteBinaryTexture(const aiTexture* tex)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AITEXTURE);
 
-	len += WriteInteger(tex->mWidth);
-	len += WriteInteger(tex->mHeight);
+	len += Write<unsigned int>(tex->mWidth);
+	len += Write<unsigned int>(tex->mHeight);
 	len += fwrite(tex->achFormatHint,1,4,out);
 
 	if(!shortened) {
@@ -238,9 +269,9 @@ uint32_t WriteBinaryBone(const aiBone* b)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIBONE);
 
-	len += WriteAiString(b->mName);
-	len += WriteInteger(b->mNumWeights);
-	len += WriteMat4x4(b->mOffsetMatrix);
+	len += Write<aiString>(b->mName);
+	len += Write<unsigned int>(b->mNumWeights);
+	len += Write<aiMatrix4x4>(b->mOffsetMatrix);
 
 	// for the moment we write dumb min/max values for the bones, too.
 	// maybe I'll add a better, hash-like solution later
@@ -258,11 +289,11 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMESH);
 
-	len += WriteInteger(mesh->mPrimitiveTypes);
-	len += WriteInteger(mesh->mNumVertices);
-	len += WriteInteger(mesh->mNumFaces);
-	len += WriteInteger(mesh->mNumBones);
-	len += WriteInteger(mesh->mMaterialIndex);
+	len += Write<unsigned int>(mesh->mPrimitiveTypes);
+	len += Write<unsigned int>(mesh->mNumVertices);
+	len += Write<unsigned int>(mesh->mNumFaces);
+	len += Write<unsigned int>(mesh->mNumBones);
+	len += Write<unsigned int>(mesh->mMaterialIndex);
 
 	// first of all, write bits for all existent vertex components
 	unsigned int c = 0;
@@ -287,7 +318,7 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
 		}
 		c |= ASSBIN_MESH_HAS_COLOR(n);
 	}
-	len += WriteInteger(c);
+	len += Write<unsigned int>(c);
 
 	aiVector3D minVec, maxVec;
 	if (mesh->mVertices) {
@@ -326,7 +357,7 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
 			break;
 
 		// write number of UV components
-		len += WriteInteger(mesh->mNumUVComponents[n]);
+		len += Write<unsigned int>(mesh->mNumUVComponents[n]);
 
 		if (shortened) {
 			len += WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices);
@@ -349,7 +380,7 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
 				hash = SuperFastHash((const char*)&f.mNumIndices,sizeof(unsigned int),hash);
 				hash = SuperFastHash((const char*) f.mIndices,f.mNumIndices*sizeof(unsigned int),hash);
 			}
-			len += WriteInteger(hash);
+			len += Write<unsigned int>(hash);
 		}
 	}
 	else // else write as usual
@@ -363,12 +394,12 @@ uint32_t WriteBinaryMesh(const aiMesh* mesh)
 				return -1;
 			}
 
-			len += WriteShort(f.mNumIndices);
+			len += Write<uint16_t>(f.mNumIndices);
 			for (unsigned int a = 0; a < f.mNumIndices;++a) {
 				if (mesh->mNumVertices < (1u<<16)) {
-					len += WriteShort(f.mIndices[a]);
+					len += Write<uint16_t>(f.mIndices[a]);
 				}
-				else len += WriteInteger(f.mIndices[a]);
+				else len += Write<unsigned int>(f.mIndices[a]);
 			}
 		}
 	}
@@ -390,12 +421,12 @@ uint32_t WriteBinaryMaterialProperty(const aiMaterialProperty* prop)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIALPROPERTY);
 
-	len += WriteAiString(prop->mKey);
-	len += WriteInteger(prop->mSemantic);
-	len += WriteInteger(prop->mIndex);
+	len += Write<aiString>(prop->mKey);
+	len += Write<unsigned int>(prop->mSemantic);
+	len += Write<unsigned int>(prop->mIndex);
 
-	len += WriteInteger(prop->mDataLength);
-	len += WriteInteger((unsigned int)prop->mType);
+	len += Write<unsigned int>(prop->mDataLength);
+	len += Write<unsigned int>((unsigned int)prop->mType);
 	len += fwrite(prop->mData,1,prop->mDataLength,out);
 
 	ChangeInteger(old,len);
@@ -407,7 +438,7 @@ uint32_t WriteBinaryMaterial(const aiMaterial* mat)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIAL);
 
-	len += WriteInteger(mat->mNumProperties);
+	len += Write<unsigned int>(mat->mNumProperties);
 	for (unsigned int i = 0; i < mat->mNumProperties;++i) {
 		len += WriteBinaryMaterialProperty(mat->mProperties[i])+8;
 	}
@@ -421,12 +452,12 @@ uint32_t WriteBinaryNodeAnim(const aiNodeAnim* nd)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODEANIM);
 
-	len += WriteAiString(nd->mNodeName);
-	len += WriteInteger(nd->mNumPositionKeys);
-	len += WriteInteger(nd->mNumRotationKeys);
-	len += WriteInteger(nd->mNumScalingKeys);
-	len += WriteInteger(nd->mPreState);
-	len += WriteInteger(nd->mPostState);
+	len += Write<aiString>(nd->mNodeName);
+	len += Write<unsigned int>(nd->mNumPositionKeys);
+	len += Write<unsigned int>(nd->mNumRotationKeys);
+	len += Write<unsigned int>(nd->mNumScalingKeys);
+	len += Write<unsigned int>(nd->mPreState);
+	len += Write<unsigned int>(nd->mPostState);
 
 	if (nd->mPositionKeys) {
 		if (shortened) {
@@ -460,10 +491,10 @@ uint32_t WriteBinaryAnim(const aiAnimation* anim)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIANIMATION);
 
-	len += WriteAiString (anim->mName);
-	len += WriteDouble (anim->mDuration);
-	len += WriteDouble (anim->mTicksPerSecond);
-	len += WriteInteger(anim->mNumChannels);
+	len += Write<aiString> (anim->mName);
+	len += Write<double> (anim->mDuration);
+	len += Write<double> (anim->mTicksPerSecond);
+	len += Write<unsigned int>(anim->mNumChannels);
 
 	for (unsigned int a = 0; a < anim->mNumChannels;++a) {
 		const aiNodeAnim* nd = anim->mChannels[a];
@@ -479,22 +510,22 @@ uint32_t WriteBinaryLight(const aiLight* l)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AILIGHT);
 
-	len += WriteAiString(l->mName);
-	len += WriteInteger(l->mType);
+	len += Write<aiString>(l->mName);
+	len += Write<unsigned int>(l->mType);
 
 	if (l->mType != aiLightSource_DIRECTIONAL) { 
-		len += WriteFloat(l->mAttenuationConstant);
-		len += WriteFloat(l->mAttenuationLinear);
-		len += WriteFloat(l->mAttenuationQuadratic);
+		len += Write<float>(l->mAttenuationConstant);
+		len += Write<float>(l->mAttenuationLinear);
+		len += Write<float>(l->mAttenuationQuadratic);
 	}
 
-	len += WriteVec3((const aiVector3D&)l->mColorDiffuse);
-	len += WriteVec3((const aiVector3D&)l->mColorSpecular);
-	len += WriteVec3((const aiVector3D&)l->mColorAmbient);
+	len += Write<aiVector3D>((const aiVector3D&)l->mColorDiffuse);
+	len += Write<aiVector3D>((const aiVector3D&)l->mColorSpecular);
+	len += Write<aiVector3D>((const aiVector3D&)l->mColorAmbient);
 
 	if (l->mType == aiLightSource_SPOT) {
-		len += WriteFloat(l->mAngleInnerCone);
-		len += WriteFloat(l->mAngleOuterCone);
+		len += Write<float>(l->mAngleInnerCone);
+		len += Write<float>(l->mAngleOuterCone);
 	}
 
 	ChangeInteger(old,len);
@@ -506,14 +537,14 @@ uint32_t WriteBinaryCamera(const aiCamera* cam)
 {
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AICAMERA);
 
-	len += WriteAiString(cam->mName);
-	len += WriteVec3(cam->mPosition);
-	len += WriteVec3(cam->mLookAt);
-	len += WriteVec3(cam->mUp);
-	len += WriteFloat(cam->mHorizontalFOV);
-	len += WriteFloat(cam->mClipPlaneNear);
-	len += WriteFloat(cam->mClipPlaneFar);
-	len += WriteFloat(cam->mAspect);
+	len += Write<aiString>(cam->mName);
+	len += Write<aiVector3D>(cam->mPosition);
+	len += Write<aiVector3D>(cam->mLookAt);
+	len += Write<aiVector3D>(cam->mUp);
+	len += Write<float>(cam->mHorizontalFOV);
+	len += Write<float>(cam->mClipPlaneNear);
+	len += Write<float>(cam->mClipPlaneFar);
+	len += Write<float>(cam->mAspect);
 
 	ChangeInteger(old,len);
 	return len;
@@ -525,13 +556,13 @@ uint32_t WriteBinaryScene(const aiScene* scene)
 	uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AISCENE);
 
 	// basic scene information
-	len += WriteInteger(scene->mFlags);
-	len += WriteInteger(scene->mNumMeshes);
-	len += WriteInteger(scene->mNumMaterials);
-	len += WriteInteger(scene->mNumAnimations);
-	len += WriteInteger(scene->mNumTextures);
-	len += WriteInteger(scene->mNumLights);
-	len += WriteInteger(scene->mNumCameras);
+	len += Write<unsigned int>(scene->mFlags);
+	len += Write<unsigned int>(scene->mNumMeshes);
+	len += Write<unsigned int>(scene->mNumMaterials);
+	len += Write<unsigned int>(scene->mNumAnimations);
+	len += Write<unsigned int>(scene->mNumTextures);
+	len += Write<unsigned int>(scene->mNumLights);
+	len += Write<unsigned int>(scene->mNumCameras);
 	
 	// write node graph
 	len += WriteBinaryNode(scene->mRootNode)+8;
@@ -592,12 +623,12 @@ void WriteBinaryDump(const aiScene* scene, FILE* _out, const char* src, const ch
 	fprintf(out,"ASSIMP.binary-dump.%s",asctime(p));
 	// == 44 bytes
 
-	WriteInteger(ASSBIN_VERSION_MAJOR);
-	WriteInteger(ASSBIN_VERSION_MINOR);
-	WriteInteger(aiGetVersionRevision());
-	WriteInteger(aiGetCompileFlags());
-	WriteShort(shortened);
-	WriteShort(compressed);
+	Write<unsigned int>(ASSBIN_VERSION_MAJOR);
+	Write<unsigned int>(ASSBIN_VERSION_MINOR);
+	Write<unsigned int>(aiGetVersionRevision());
+	Write<unsigned int>(aiGetCompileFlags());
+	Write<uint16_t>(shortened);
+	Write<uint16_t>(compressed);
 	// ==  20 bytes
 
 	char buff[256];