summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZack Middleton <zturtleman@gmail.com>2013-03-08 13:47:16 -0600
committerTim Angus <tim@ngus.net>2013-03-19 16:41:18 +0000
commitffa02b557a039421a3348cf6cc7712f704197ca5 (patch)
treeaa8c3b1538c81ab673d70e5f1502152ab5005927 /src
parent583527fd62c1f982c2557bba9d083b44f96c2bcb (diff)
Fix origin returned by IQM's LerpTag
It use to return pose joint's offset from base at the lerped frame, now it returns the joint's origin at the lerped frame. Patch by Axel Isouard and Zack Middleton.
Diffstat (limited to 'src')
-rw-r--r--src/renderergl1/tr_local.h1
-rw-r--r--src/renderergl1/tr_model_iqm.c55
-rw-r--r--src/renderergl2/tr_local.h1
-rw-r--r--src/renderergl2/tr_model_iqm.c55
4 files changed, 82 insertions, 30 deletions
diff --git a/src/renderergl1/tr_local.h b/src/renderergl1/tr_local.h
index f54400eb..40e78500 100644
--- a/src/renderergl1/tr_local.h
+++ b/src/renderergl1/tr_local.h
@@ -650,6 +650,7 @@ typedef struct {
int *triangles;
int *jointParents;
+ float *jointMats;
float *poseMats;
float *bounds;
char *names;
diff --git a/src/renderergl1/tr_model_iqm.c b/src/renderergl1/tr_model_iqm.c
index 720e4a23..b7d474be 100644
--- a/src/renderergl1/tr_model_iqm.c
+++ b/src/renderergl1/tr_model_iqm.c
@@ -52,6 +52,11 @@ static void Matrix34Multiply( float *a, float *b, float *out ) {
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
}
+static void Matrix34Multiply_OnlySetOrigin( float *a, float *b, float *out ) {
+ out[ 3] = a[0] * b[3] + a[1] * b[7] + a[ 2] * b[11] + a[ 3];
+ out[ 7] = a[4] * b[3] + a[5] * b[7] + a[ 6] * b[11] + a[ 7];
+ out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
+}
static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) {
float unLerp = 1.0f - lerp;
@@ -133,8 +138,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
unsigned short *framedata;
char *str;
int i, j;
- float jointMats[IQM_MAX_JOINTS * 2 * 12];
- float *mat;
+ float jointInvMats[IQM_MAX_JOINTS * 12];
+ float *mat, *matInv;
size_t size, joint_names;
iqmData_t *iqmData;
srfIQModel_t *surface;
@@ -419,7 +424,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
// allocate the model and copy the data
size = sizeof(iqmData_t);
size += header->num_meshes * sizeof( srfIQModel_t );
- size += header->num_joints * header->num_frames * 12 * sizeof( float );
+ size += header->num_joints * header->num_frames * 12 * sizeof( float ); // joint mats
+ size += header->num_joints * header->num_frames * 12 * sizeof( float ); // pose mats
if(header->ofs_bounds)
size += header->num_frames * 6 * sizeof(float); // model bounds
size += header->num_vertexes * 3 * sizeof(float); // positions
@@ -444,7 +450,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
iqmData->num_surfaces = header->num_meshes;
iqmData->num_joints = header->num_joints;
iqmData->surfaces = (srfIQModel_t *)(iqmData + 1);
- iqmData->poseMats = (float *) (iqmData->surfaces + iqmData->num_surfaces);
+ iqmData->jointMats = (float *) (iqmData->surfaces + iqmData->num_surfaces);
+ iqmData->poseMats = iqmData->jointMats + 12 * header->num_joints * header->num_frames;
if(header->ofs_bounds)
{
iqmData->bounds = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
@@ -463,8 +470,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles);
// calculate joint matrices and their inverses
- // they are needed only until the pose matrices are calculated
- mat = jointMats;
+ // joint inverses are needed only until the pose matrices are calculated
+ mat = iqmData->jointMats;
+ matInv = jointInvMats;
joint = (iqmJoint_t *)((byte *)header + header->ofs_joints);
for( i = 0; i < header->num_joints; i++, joint++ ) {
float baseFrame[12], invBaseFrame[12];
@@ -474,17 +482,17 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
if ( joint->parent >= 0 )
{
- Matrix34Multiply( jointMats + 2 * 12 * joint->parent, baseFrame, mat );
- mat += 12;
- Matrix34Multiply( invBaseFrame, jointMats + 2 * 12 * joint->parent + 12, mat );
+ Matrix34Multiply( iqmData->jointMats + 12 * joint->parent, baseFrame, mat );
mat += 12;
+ Matrix34Multiply( invBaseFrame, jointInvMats + 12 * joint->parent, matInv );
+ matInv += 12;
}
else
{
Com_Memcpy( mat, baseFrame, sizeof(baseFrame) );
mat += 12;
- Com_Memcpy( mat, invBaseFrame, sizeof(invBaseFrame) );
- mat += 12;
+ Com_Memcpy( matInv, invBaseFrame, sizeof(invBaseFrame) );
+ matInv += 12;
}
}
@@ -536,13 +544,13 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
JointToMatrix( rotate, scale, translate, mat1 );
if( pose->parent >= 0 ) {
- Matrix34Multiply( jointMats + 12 * 2 * pose->parent,
+ Matrix34Multiply( iqmData->jointMats + 12 * pose->parent,
mat1, mat2 );
} else {
Com_Memcpy( mat2, mat1, sizeof(mat1) );
}
- Matrix34Multiply( mat2, jointMats + 12 * (2 * j + 1), mat );
+ Matrix34Multiply( mat2, jointInvMats + 12 * j, mat );
mat += 12;
}
}
@@ -862,7 +870,7 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) {
}
-static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
+static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
float backlerp, float *mat ) {
float *mat1, *mat2;
int *joint = data->jointParents;
@@ -898,6 +906,23 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
}
}
+static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
+ float backlerp, float *mat ) {
+ float *mat1;
+ int i;
+
+ ComputePoseMats( data, frame, oldframe, backlerp, mat );
+
+ for( i = 0; i < data->num_joints; i++ ) {
+ float outmat[12];
+ mat1 = mat + 12 * i;
+
+ Com_Memcpy(outmat, mat1, sizeof(outmat));
+
+ Matrix34Multiply_OnlySetOrigin( outmat, data->jointMats + 12 * i, mat1 );
+ }
+}
+
/*
=================
@@ -928,7 +953,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
// compute interpolated joint matrices
- ComputeJointMats( data, frame, oldframe, backlerp, jointMats );
+ ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
// transform vertexes and fill other data
for( i = 0; i < surf->num_vertexes;
diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h
index 6c0bf165..7efb26e9 100644
--- a/src/renderergl2/tr_local.h
+++ b/src/renderergl2/tr_local.h
@@ -1251,6 +1251,7 @@ typedef struct {
int *triangles;
int *jointParents;
+ float *jointMats;
float *poseMats;
float *bounds;
char *names;
diff --git a/src/renderergl2/tr_model_iqm.c b/src/renderergl2/tr_model_iqm.c
index 2797f59c..2d21f6de 100644
--- a/src/renderergl2/tr_model_iqm.c
+++ b/src/renderergl2/tr_model_iqm.c
@@ -51,6 +51,11 @@ static void Matrix34Multiply( float *a, float *b, float *out ) {
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
}
+static void Matrix34Multiply_OnlySetOrigin( float *a, float *b, float *out ) {
+ out[ 3] = a[0] * b[3] + a[1] * b[7] + a[ 2] * b[11] + a[ 3];
+ out[ 7] = a[4] * b[3] + a[5] * b[7] + a[ 6] * b[11] + a[ 7];
+ out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
+}
static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) {
float unLerp = 1.0f - lerp;
@@ -132,8 +137,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
unsigned short *framedata;
char *str;
int i, j;
- float jointMats[IQM_MAX_JOINTS * 2 * 12];
- float *mat;
+ float jointInvMats[IQM_MAX_JOINTS * 12];
+ float *mat, *matInv;
size_t size, joint_names;
iqmData_t *iqmData;
srfIQModel_t *surface;
@@ -418,7 +423,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
// allocate the model and copy the data
size = sizeof(iqmData_t);
size += header->num_meshes * sizeof( srfIQModel_t );
- size += header->num_joints * header->num_frames * 12 * sizeof( float );
+ size += header->num_joints * header->num_frames * 12 * sizeof( float ); // joint mats
+ size += header->num_joints * header->num_frames * 12 * sizeof( float ); // pose mats
if(header->ofs_bounds)
size += header->num_frames * 6 * sizeof(float); // model bounds
size += header->num_vertexes * 3 * sizeof(float); // positions
@@ -443,7 +449,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
iqmData->num_surfaces = header->num_meshes;
iqmData->num_joints = header->num_joints;
iqmData->surfaces = (srfIQModel_t *)(iqmData + 1);
- iqmData->poseMats = (float *) (iqmData->surfaces + iqmData->num_surfaces);
+ iqmData->jointMats = (float *) (iqmData->surfaces + iqmData->num_surfaces);
+ iqmData->poseMats = iqmData->jointMats + 12 * header->num_joints * header->num_frames;
if(header->ofs_bounds)
{
iqmData->bounds = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
@@ -462,8 +469,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles);
// calculate joint matrices and their inverses
- // they are needed only until the pose matrices are calculated
- mat = jointMats;
+ // joint inverses are needed only until the pose matrices are calculated
+ mat = iqmData->jointMats;
+ matInv = jointInvMats;
joint = (iqmJoint_t *)((byte *)header + header->ofs_joints);
for( i = 0; i < header->num_joints; i++, joint++ ) {
float baseFrame[12], invBaseFrame[12];
@@ -473,17 +481,17 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
if ( joint->parent >= 0 )
{
- Matrix34Multiply( jointMats + 2 * 12 * joint->parent, baseFrame, mat );
- mat += 12;
- Matrix34Multiply( invBaseFrame, jointMats + 2 * 12 * joint->parent + 12, mat );
+ Matrix34Multiply( iqmData->jointMats + 12 * joint->parent, baseFrame, mat );
mat += 12;
+ Matrix34Multiply( invBaseFrame, jointInvMats + 12 * joint->parent, matInv );
+ matInv += 12;
}
else
{
Com_Memcpy( mat, baseFrame, sizeof(baseFrame) );
mat += 12;
- Com_Memcpy( mat, invBaseFrame, sizeof(invBaseFrame) );
- mat += 12;
+ Com_Memcpy( matInv, invBaseFrame, sizeof(invBaseFrame) );
+ matInv += 12;
}
}
@@ -535,13 +543,13 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
JointToMatrix( rotate, scale, translate, mat1 );
if( pose->parent >= 0 ) {
- Matrix34Multiply( jointMats + 12 * 2 * pose->parent,
+ Matrix34Multiply( iqmData->jointMats + 12 * pose->parent,
mat1, mat2 );
} else {
Com_Memcpy( mat2, mat1, sizeof(mat1) );
}
- Matrix34Multiply( mat2, jointMats + 12 * (2 * j + 1), mat );
+ Matrix34Multiply( mat2, jointInvMats + 12 * j, mat );
mat += 12;
}
}
@@ -861,7 +869,7 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) {
}
-static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
+static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
float backlerp, float *mat ) {
float *mat1, *mat2;
int *joint = data->jointParents;
@@ -897,6 +905,23 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
}
}
+static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
+ float backlerp, float *mat ) {
+ float *mat1;
+ int i;
+
+ ComputePoseMats( data, frame, oldframe, backlerp, mat );
+
+ for( i = 0; i < data->num_joints; i++ ) {
+ float outmat[12];
+ mat1 = mat + 12 * i;
+
+ Com_Memcpy(outmat, mat1, sizeof(outmat));
+
+ Matrix34Multiply_OnlySetOrigin( outmat, data->jointMats + 12 * i, mat1 );
+ }
+}
+
/*
=================
@@ -927,7 +952,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
// compute interpolated joint matrices
- ComputeJointMats( data, frame, oldframe, backlerp, jointMats );
+ ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
// transform vertexes and fill other data
for( i = 0; i < surf->num_vertexes;