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