r696 - trunk

lordhavoc at icculus.org lordhavoc at icculus.org
Sat Apr 8 22:53:10 EDT 2006


Author: lordhavoc
Date: 2006-04-08 22:53:10 -0400 (Sat, 08 Apr 2006)
New Revision: 696

Modified:
   trunk/model.c
   trunk/model.h
   trunk/r_main.c
Log:
changed skeletal animation blending code to use the matrix palette
method (not yet hardware accelerated), this eliminates the weights array


Modified: trunk/model.c
===================================================================
--- trunk/model.c	2006-04-08 21:50:07 UTC (rev 695)
+++ trunk/model.c	2006-04-09 02:53:10 UTC (rev 696)
@@ -343,7 +343,6 @@
 			Model_MD5_Weight *md5weights = NULL, *md5weight = NULL;
 			NUint32 *md5weightrange = NULL;
 			NUint32 i, j;
-			Model_Weight *weight;
 			matrix4x4_t *matrix;
 
 			ExpectKeyword("{", "after 'mesh'");
@@ -498,7 +497,6 @@
 				}
 			}
 			memset(mesh->data_vertex3f, 0, mesh->num_vertices * sizeof(float[3]));
-			mesh->num_weights = 0;
 			for (i = 0;i < mesh->num_vertices;i++)
 			{
 				Ndouble sum = 0;
@@ -524,7 +522,6 @@
 						mesh->data_weightvalue4f[i*4+k] = md5weight->vertex[3];
 					}
 					sum += md5weight->vertex[3];
-					mesh->num_weights++;
 				}
 				if (fabs(sum - 1) > 0.001)
 					Console_Printf("vertex #%i (weights %i-%i) does not sum to 1! (sum = %f)\n", i, md5weightrange[i*2+0], md5weightrange[i*2+0]+md5weightrange[i*2+1], sum);
@@ -551,12 +548,10 @@
 			mesh->max_collisionbrushes = mesh->num_collisionbrushes;
 			mesh->data_collisionbrushes = Collision_Brush_AllocBrushesForTriangleMesh(r->memzone, mesh->max_triangles);
 			Collision_Brush_UpdateTriangleMeshBrushes(mesh->data_collisionbrushes, mesh->num_triangles, mesh->data_element3i, mesh->data_vertex3f);
-			// regenerate the weights from the static mesh and influences,
-			// because we need weights with svector/tvector/normal information
-			mesh->weights = Mem_Alloc(r->memzone, mesh->num_weights * sizeof(Model_Weight));
-			weight = mesh->weights;
+			// calculate culling shapes
 			for (i = 0;i < mesh->num_vertices;i++)
 			{
+				NUint32 k;
 				if (!i && !meshnum)
 				{
 					VectorCopy(mesh->data_vertex3f, model->basecullmins);
@@ -585,30 +580,15 @@
 					mesh->basecullmaxs[1] = Max(mesh->basecullmaxs[1], mesh->data_vertex3f[i * 3 + 1]);
 					mesh->basecullmaxs[2] = Max(mesh->basecullmaxs[2], mesh->data_vertex3f[i * 3 + 2]);
 				}
-				for (j = 0, md5weight = md5weights + md5weightrange[i*2+0];j < md5weightrange[i*2+1];j++, md5weight++)
+				for (k = 0;k < 4 && mesh->data_weightvalue4f[i*4+k] > 0;k++)
 				{
-					float r;
-					// copy properties from the md5weight struct
-					weight->vertexindex = i;
-					weight->transformindex = md5weight->jointnum;
-					weight->vertex[0] = md5weight->vertex[0];
-					weight->vertex[1] = md5weight->vertex[1];
-					weight->vertex[2] = md5weight->vertex[2];
-					weight->vertex[3] = md5weight->vertex[3];
-					// calculate weights for the tangent space vectors
-					matrix = &model->data_transforminfo[weight->transformindex].basematrix;
-					weight->svector[0] = (mesh->data_svector3f[i*3+0] * matrix->m[0][0] + mesh->data_svector3f[i*3+1] * matrix->m[1][0] + mesh->data_svector3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3];
-					weight->svector[1] = (mesh->data_svector3f[i*3+0] * matrix->m[0][1] + mesh->data_svector3f[i*3+1] * matrix->m[1][1] + mesh->data_svector3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3];
-					weight->svector[2] = (mesh->data_svector3f[i*3+0] * matrix->m[0][2] + mesh->data_svector3f[i*3+1] * matrix->m[1][2] + mesh->data_svector3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3];
-					weight->tvector[0] = (mesh->data_tvector3f[i*3+0] * matrix->m[0][0] + mesh->data_tvector3f[i*3+1] * matrix->m[1][0] + mesh->data_tvector3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3];
-					weight->tvector[1] = (mesh->data_tvector3f[i*3+0] * matrix->m[0][1] + mesh->data_tvector3f[i*3+1] * matrix->m[1][1] + mesh->data_tvector3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3];
-					weight->tvector[2] = (mesh->data_tvector3f[i*3+0] * matrix->m[0][2] + mesh->data_tvector3f[i*3+1] * matrix->m[1][2] + mesh->data_tvector3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3];
-					weight->normal[0] = (mesh->data_normal3f[i*3+0] * matrix->m[0][0] + mesh->data_normal3f[i*3+1] * matrix->m[1][0] + mesh->data_normal3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3];
-					weight->normal[1] = (mesh->data_normal3f[i*3+0] * matrix->m[0][1] + mesh->data_normal3f[i*3+1] * matrix->m[1][1] + mesh->data_normal3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3];
-					weight->normal[2] = (mesh->data_normal3f[i*3+0] * matrix->m[0][2] + mesh->data_normal3f[i*3+1] * matrix->m[1][2] + mesh->data_normal3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3];
-					r = VectorLength(weight->vertex) / weight->vertex[3];
-					model->data_transforminfo[weight->transformindex].radius = Max(model->data_transforminfo[weight->transformindex].radius, r);
-					weight++;
+					NUint32 index = mesh->data_weightindex4i[i*4+k];
+					Nvec3 v1, v;
+					Nvec r;
+					VectorCopy(mesh->data_vertex3f + i * 3, v1);
+					Matrix4x4_Transform(&model->data_transforminfo[index].baseinversematrix, v1, v);
+					r = VectorLength(v);
+					model->data_transforminfo[index].radius = Max(model->data_transforminfo[index].radius, r);
 				}
 			}
 			Mem_Free(&md5weights);
@@ -640,11 +620,29 @@
 //////////////////////////////////////////////////////////////////////////////
 
 // this function decodes weights to produce a renderable or collidable mesh
-void Model_GetVertices(Model_Mesh *mesh, const matrix4x4_t *transforms, float *outvertex3f, float *outsvector3f, float *outtvector3f, float *outnormal3f, float *outplane4f)
+void Model_GetVertices(NUint32 resourceindex, NUint32 meshindex, const matrix4x4_t *transforms, float *outvertex3f, float *outsvector3f, float *outtvector3f, float *outnormal3f, float *outplane4f)
 {
+	Model *model;
+	Model_Mesh *mesh;
+	const float *v;
+	const float *sv;
+	const float *tv;
+	const float *n;
+#if 1
+	NUint32 j, k, index;
+	const matrix4x4_t *matrix;
+	matrix4x4_t relativematrix[256]; // FIXME!!
+#else
 	NUint32 j, index;
 	Model_Weight *weight;
 	const matrix4x4_t *matrix;
+#endif
+	model = Resource_GetData(resourceindex);
+	if (!model)
+		return; // no model
+	if (meshindex >= model->num_meshes)
+		return; // invalid mesh index
+	mesh = model->data_meshes + meshindex;
 	if (!transforms)
 	{
 		if (outvertex3f)
@@ -669,79 +667,52 @@
 		memset(outtvector3f, 0, mesh->num_vertices * sizeof(float[3]));
 	if (outnormal3f)
 		memset(outnormal3f, 0, mesh->num_vertices * sizeof(float[3]));
-	// TODO: SSE assembly support
-	if (outvertex3f && outsvector3f && outtvector3f && outnormal3f)
+	v = mesh->data_vertex3f;
+	sv = mesh->data_svector3f;
+	tv = mesh->data_tvector3f;
+	n = mesh->data_normal3f;
+	for (j = 0;j < model->num_transforms;j++)
+		Matrix4x4_Concat(relativematrix + j, transforms + j, &model->data_transforminfo[j].baseinversematrix);
+	for (j = 0, index = 0;j < mesh->num_vertices;j++, index += 3)
 	{
-		// fastpath for all properties at once
-		for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++)
+		float value;
+		for (k = 0;k < 4 && (value = mesh->data_weightvalue4f[j*4+k]);k++)
 		{
-			matrix = transforms + weight->transformindex;
-			index = weight->vertexindex*3;
-			outvertex3f[index+0] += DotProduct4(weight->vertex, matrix->m[0]);
-			outvertex3f[index+1] += DotProduct4(weight->vertex, matrix->m[1]);
-			outvertex3f[index+2] += DotProduct4(weight->vertex, matrix->m[2]);
-			outsvector3f[index+0] += DotProduct(weight->svector, matrix->m[0]);
-			outsvector3f[index+1] += DotProduct(weight->svector, matrix->m[1]);
-			outsvector3f[index+2] += DotProduct(weight->svector, matrix->m[2]);
-			outtvector3f[index+0] += DotProduct(weight->tvector, matrix->m[0]);
-			outtvector3f[index+1] += DotProduct(weight->tvector, matrix->m[1]);
-			outtvector3f[index+2] += DotProduct(weight->tvector, matrix->m[2]);
-			outnormal3f[index+0] += DotProduct(weight->normal, matrix->m[0]);
-			outnormal3f[index+1] += DotProduct(weight->normal, matrix->m[1]);
-			outnormal3f[index+2] += DotProduct(weight->normal, matrix->m[2]);
+			matrix = relativematrix + mesh->data_weightindex4i[j*4+k];
+			if (outvertex3f)
+			{
+				outvertex3f[index+0] += value * (DotProduct(v + index, matrix->m[0]) + matrix->m[0][3]);
+				outvertex3f[index+1] += value * (DotProduct(v + index, matrix->m[1]) + matrix->m[1][3]);
+				outvertex3f[index+2] += value * (DotProduct(v + index, matrix->m[2]) + matrix->m[2][3]);
+			}
+			if (outsvector3f)
+			{
+				outsvector3f[index+0] += value * DotProduct(sv + index, matrix->m[0]);
+				outsvector3f[index+1] += value * DotProduct(sv + index, matrix->m[1]);
+				outsvector3f[index+2] += value * DotProduct(sv + index, matrix->m[2]);
+			}
+			if (outtvector3f)
+			{
+				outtvector3f[index+0] += value * DotProduct(tv + index, matrix->m[0]);
+				outtvector3f[index+1] += value * DotProduct(tv + index, matrix->m[1]);
+				outtvector3f[index+2] += value * DotProduct(tv + index, matrix->m[2]);
+			}
+			if (outnormal3f)
+			{
+				outnormal3f[index+0] += value * DotProduct(n + index, matrix->m[0]);
+				outnormal3f[index+1] += value * DotProduct(n + index, matrix->m[1]);
+				outnormal3f[index+2] += value * DotProduct(n + index, matrix->m[2]);
+			}
 		}
-		if (outplane4f)
-			Model_BuildTrianglePlanes(outvertex3f, mesh->num_triangles, mesh->data_element3i, outplane4f);
-		return;
+		if (outsvector3f)
+			VectorNormalize(outsvector3f + index);
+		if (outtvector3f)
+			VectorNormalize(outtvector3f + index);
+		if (outnormal3f)
+			VectorNormalize(outnormal3f + index);
 	}
-	// partial request, handle each in turn (usually only vertex)
-	// FIXME: would it be worth saving separate weights for vertex?
-	if (outvertex3f)
-	{
-		for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++)
-		{
-			matrix = transforms + weight->transformindex;
-			index = weight->vertexindex*3;
-			outvertex3f[index+0] += DotProduct4(weight->vertex, matrix->m[0]);
-			outvertex3f[index+1] += DotProduct4(weight->vertex, matrix->m[1]);
-			outvertex3f[index+2] += DotProduct4(weight->vertex, matrix->m[2]);
-		}
-		if (outplane4f)
-			Model_BuildTrianglePlanes(outvertex3f, mesh->num_triangles, mesh->data_element3i, outplane4f);
-	}
-	if (outsvector3f)
-	{
-		for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++)
-		{
-			matrix = transforms + weight->transformindex;
-			index = weight->vertexindex*3;
-			outsvector3f[index+0] += DotProduct(weight->svector, matrix->m[0]);
-			outsvector3f[index+1] += DotProduct(weight->svector, matrix->m[1]);
-			outsvector3f[index+2] += DotProduct(weight->svector, matrix->m[2]);
-		}
-	}
-	if (outtvector3f)
-	{
-		for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++)
-		{
-			matrix = transforms + weight->transformindex;
-			index = weight->vertexindex*3;
-			outtvector3f[index+0] += DotProduct(weight->tvector, matrix->m[0]);
-			outtvector3f[index+1] += DotProduct(weight->tvector, matrix->m[1]);
-			outtvector3f[index+2] += DotProduct(weight->tvector, matrix->m[2]);
-		}
-	}
-	if (outnormal3f)
-	{
-		for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++)
-		{
-			matrix = transforms + weight->transformindex;
-			index = weight->vertexindex*3;
-			outnormal3f[index+0] += DotProduct(weight->normal, matrix->m[0]);
-			outnormal3f[index+1] += DotProduct(weight->normal, matrix->m[1]);
-			outnormal3f[index+2] += DotProduct(weight->normal, matrix->m[2]);
-		}
-	}
+	if (outvertex3f && outplane4f)
+		Model_BuildTrianglePlanes(outvertex3f, mesh->num_triangles, mesh->data_element3i, outplane4f);
 }
 
 void Model_GetCullBox(NUint32 modelresource, const matrix4x4_t *transforms, Nvec3 cullmins, Nvec3 cullmaxs)
@@ -818,7 +789,7 @@
 		// by vertex number to make this faster (no intermediate buffer involved)
 		NUint32 i;
 		float *v, *vertex3f = Mem_Alloc(Global_Zone, mesh->num_vertices * sizeof(float[3]));
-		Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL);
+		Model_GetVertices(modelresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL);
 		VectorCopy(vertex3f, cullmins);
 		VectorCopy(vertex3f, cullmaxs);
 		for (i = 0, v = vertex3f;i < mesh->num_vertices;i++, v += 3)

Modified: trunk/model.h
===================================================================
--- trunk/model.h	2006-04-08 21:50:07 UTC (rev 695)
+++ trunk/model.h	2006-04-09 02:53:10 UTC (rev 696)
@@ -18,27 +18,6 @@
 }
 Model_TransformInfo;
 
-typedef struct Model_Weight
-{
-	// this struct is intended to be easy for SSE 4 component math ops
-	// x y z and influence, x y z are prescaled by influence, so this is a
-	// simple DotProduct4 with the matrix.
-	float vertex[4];
-	// x y z of vector along S texcoord (tangent space)
-	float svector[3];
-	// number of vertex this weight influences
-	NUint32 vertexindex;
-	// x y z of vector along T texcoord (tangent space)
-	float tvector[3];
-	// number of transform this weight is relative to
-	NUint32 transformindex;
-	// x y z of vector along normal (tangent space)
-	float normal[3];
-	// unused space to pad this to 64 bytes
-	float pad;
-}
-Model_Weight;
-
 typedef struct Model_Mesh
 {
 	char *materialname;
@@ -83,14 +62,6 @@
 	// blending influence values of up to 4 transforms per vertex
 	float *data_weightvalue4f;
 
-#if 1
-	// number of skeletal transforms to blend onto the vertex array
-	// (always >= numvertices)
-	NUint32 num_weights;
-	// skeletal transform weights
-	Model_Weight *weights;
-#endif
-
 	Nvec3 basecullmins;
 	Nvec3 basecullmaxs;
 
@@ -104,7 +75,6 @@
 }
 Model_Mesh;
 
-
 typedef struct Model
 {
 	NUint32 num_meshes;
@@ -125,7 +95,7 @@
 
 // this function decodes skeletal vertex information to your supplied arrays
 // NOTE: outplane4f requires outvertex3f
-void Model_GetVertices(Model_Mesh *mesh, const matrix4x4_t *transforms, float *outvertex3f, float *outsvector3f, float *outtvector3f, float *outnormal3f, float *outplane4f);
+void Model_GetVertices(NUint32 resourceindex, NUint32 meshindex, const matrix4x4_t *transforms, float *outvertex3f, float *outsvector3f, float *outtvector3f, float *outnormal3f, float *outplane4f);
 void Model_GetCullBox(NUint32 modelresource, const matrix4x4_t *transforms, Nvec3 cullmins, Nvec3 cullmaxs);
 void Model_GetMeshCullBox(NUint32 modelresource, NUint32 meshindex, const matrix4x4_t *transforms, Nvec3 cullmins, Nvec3 cullmaxs);
 NSint32 Model_GetTransformNumberForName(NUint32 modelresource, const char *name);

Modified: trunk/r_main.c
===================================================================
--- trunk/r_main.c	2006-04-08 21:50:07 UTC (rev 695)
+++ trunk/r_main.c	2006-04-09 02:53:10 UTC (rev 696)
@@ -1934,7 +1934,7 @@
 		if (transforms)
 		{
 			vertex3f = R.varray_vertex3f;
-			Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL);
+			Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL);
 		}
 		else
 			vertex3f = mesh->data_vertex3f;
@@ -1948,7 +1948,7 @@
 		if (transforms)
 		{
 			vertex3f = R.varray_vertex3f;
-			Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL);
+			Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL);
 		}
 		else
 			vertex3f = mesh->data_vertex3f;
@@ -1962,7 +1962,7 @@
 		if (transforms)
 		{
 			vertex3f = R.varray_vertex3f;
-			Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL);
+			Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL);
 		}
 		else
 			vertex3f = mesh->data_vertex3f;
@@ -2013,7 +2013,7 @@
 		if (transforms)
 		{
 			vertex3f = R.varray_vertex3f;
-			Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL);
+			Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL);
 		}
 		else
 			vertex3f = mesh->data_vertex3f;
@@ -2037,7 +2037,7 @@
 		{
 			vertex3f = R.varray_vertex3f;
 			plane4f = R.varray_plane4f;
-			Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, plane4f);
+			Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, plane4f);
 		}
 		else
 		{
@@ -2105,7 +2105,7 @@
 			svector3f = R.varray_svector3f;
 			tvector3f = R.varray_tvector3f;
 			normal3f = R.varray_normal3f;
-			Model_GetVertices(mesh, transforms, vertex3f, svector3f, tvector3f, normal3f, NULL);
+			Model_GetVertices(materialresource, meshindex, transforms, vertex3f, svector3f, tvector3f, normal3f, NULL);
 		}
 		else
 		{
@@ -2201,7 +2201,7 @@
 		if (transforms)
 		{
 			vertex3f = R.varray_vertex3f;
-			Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL);
+			Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL);
 		}
 		else
 			vertex3f = mesh->data_vertex3f;
@@ -2224,7 +2224,7 @@
 		if (transforms)
 		{
 			vertex3f = R.varray_vertex3f;
-			Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL);
+			Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL);
 		}
 		else
 			vertex3f = mesh->data_vertex3f;
@@ -2239,7 +2239,7 @@
 		if (transforms)
 		{
 			vertex3f = R.varray_vertex3f;
-			Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL);
+			Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL);
 		}
 		else
 			vertex3f = mesh->data_vertex3f;




More information about the neither-commits mailing list