diff options
Diffstat (limited to 'src/renderer')
-rw-r--r-- | src/renderer/tr_model_iqm.c | 107 |
1 files changed, 65 insertions, 42 deletions
diff --git a/src/renderer/tr_model_iqm.c b/src/renderer/tr_model_iqm.c index ea2a903d..76f8c14c 100644 --- a/src/renderer/tr_model_iqm.c +++ b/src/renderer/tr_model_iqm.c @@ -67,20 +67,17 @@ static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) { mat[10] = a[10] * unLerp + b[10] * lerp; mat[11] = a[11] * unLerp + b[11] * lerp; } -static void JointToMatrix( vec3_t rot, vec3_t scale, vec3_t trans, +static void JointToMatrix( vec4_t rot, vec3_t scale, vec3_t trans, float *mat ) { - float rotLen = DotProduct(rot, rot); - float rotW = -SQRTFAST(1.0f - rotLen); - float xx = 2.0f * rot[0] * rot[0]; float yy = 2.0f * rot[1] * rot[1]; float zz = 2.0f * rot[2] * rot[2]; float xy = 2.0f * rot[0] * rot[1]; float xz = 2.0f * rot[0] * rot[2]; float yz = 2.0f * rot[1] * rot[2]; - float wx = 2.0f * rotW * rot[0]; - float wy = 2.0f * rotW * rot[1]; - float wz = 2.0f * rotW * rot[2]; + float wx = 2.0f * rot[3] * rot[0]; + float wy = 2.0f * rot[3] * rot[1]; + float wz = 2.0f * rot[3] * rot[2]; mat[ 0] = scale[0] * (1.0f - (yy + zz)); mat[ 1] = scale[0] * (xy - wz); @@ -95,20 +92,17 @@ static void JointToMatrix( vec3_t rot, vec3_t scale, vec3_t trans, mat[10] = scale[2] * (1.0f - (xx + yy)); mat[11] = trans[2]; } -static void JointToMatrixInverse( vec3_t rot, vec3_t scale, vec3_t trans, +static void JointToMatrixInverse( vec4_t rot, vec3_t scale, vec3_t trans, float *mat ) { - float rotLen = DotProduct(rot, rot); - float rotW = -SQRTFAST(1.0f - rotLen); - float xx = 2.0f * rot[0] * rot[0]; float yy = 2.0f * rot[1] * rot[1]; float zz = 2.0f * rot[2] * rot[2]; float xy = 2.0f * rot[0] * rot[1]; float xz = 2.0f * rot[0] * rot[2]; float yz = 2.0f * rot[1] * rot[2]; - float wx = 2.0f * rotW * rot[0]; - float wy = 2.0f * rotW * rot[1]; - float wz = 2.0f * rotW * rot[2]; + float wx = 2.0f * rot[3] * rot[0]; + float wy = 2.0f * rot[3] * rot[1]; + float wz = 2.0f * rot[3] * rot[2]; mat[ 0] = scale[0] * (1.0f - (yy + zz)); mat[ 1] = scale[0] * (xy + wz); @@ -159,6 +153,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na LL( header->version ); if( header->version != IQM_VERSION ) { + ri.Printf(PRINT_WARNING, "R_LoadIQM: %s is a unsupported IQM version (%d), only version %d is supported.\n", + mod_name, header->version, IQM_VERSION); return qfalse; } @@ -355,6 +351,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na LL( joint->rotate[0] ); LL( joint->rotate[1] ); LL( joint->rotate[2] ); + LL( joint->rotate[3] ); LL( joint->scale[0] ); LL( joint->scale[1] ); LL( joint->scale[2] ); @@ -390,6 +387,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na LL( pose->channeloffset[6] ); LL( pose->channeloffset[7] ); LL( pose->channeloffset[8] ); + LL( pose->channeloffset[9] ); LL( pose->channelscale[0] ); LL( pose->channelscale[1] ); LL( pose->channelscale[2] ); @@ -399,25 +397,29 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na LL( pose->channelscale[6] ); LL( pose->channelscale[7] ); LL( pose->channelscale[8] ); + LL( pose->channelscale[9] ); } - // check and swap model bounds - if(IQM_CheckRange(header, header->ofs_bounds, - header->num_frames, sizeof(*bounds))) - { - return qfalse; - } - bounds = (iqmBounds_t *) ((byte *) header + header->ofs_bounds); - for(i = 0; i < header->num_poses; i++) + if (header->ofs_bounds) { - LL(bounds->bbmin[0]); - LL(bounds->bbmin[1]); - LL(bounds->bbmin[2]); - LL(bounds->bbmax[0]); - LL(bounds->bbmax[1]); - LL(bounds->bbmax[2]); - - bounds++; + // check and swap model bounds + if(IQM_CheckRange(header, header->ofs_bounds, + header->num_frames, sizeof(*bounds))) + { + return qfalse; + } + bounds = (iqmBounds_t *) ((byte *) header + header->ofs_bounds); + for(i = 0; i < header->num_frames; i++) + { + LL(bounds->bbmin[0]); + LL(bounds->bbmin[1]); + LL(bounds->bbmin[2]); + LL(bounds->bbmax[0]); + LL(bounds->bbmax[1]); + LL(bounds->bbmax[2]); + + bounds++; + } } // allocate the model and copy the data @@ -509,7 +511,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na for( i = 0; i < header->num_frames; i++ ) { pose = (iqmPose_t *)((byte *)header + header->ofs_poses); for( j = 0; j < header->num_poses; j++, pose++ ) { - vec3_t translate, rotate, scale; + vec3_t translate; + vec4_t rotate; + vec3_t scale; float mat1[12], mat2[12]; translate[0] = pose->channeloffset[0]; @@ -521,6 +525,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na translate[2] = pose->channeloffset[2]; if( pose->mask & 0x004) translate[2] += *framedata++ * pose->channelscale[2]; + rotate[0] = pose->channeloffset[3]; if( pose->mask & 0x008) rotate[0] += *framedata++ * pose->channelscale[3]; @@ -530,15 +535,19 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na rotate[2] = pose->channeloffset[5]; if( pose->mask & 0x020) rotate[2] += *framedata++ * pose->channelscale[5]; - scale[0] = pose->channeloffset[6]; + rotate[3] = pose->channeloffset[6]; if( pose->mask & 0x040) - scale[0] += *framedata++ * pose->channelscale[6]; - scale[1] = pose->channeloffset[7]; + rotate[3] += *framedata++ * pose->channelscale[6]; + + scale[0] = pose->channeloffset[7]; if( pose->mask & 0x080) - scale[1] += *framedata++ * pose->channelscale[7]; - scale[2] = pose->channeloffset[8]; + scale[0] += *framedata++ * pose->channelscale[7]; + scale[1] = pose->channeloffset[8]; if( pose->mask & 0x100) - scale[2] += *framedata++ * pose->channelscale[8]; + scale[1] += *framedata++ * pose->channelscale[8]; + scale[2] = pose->channeloffset[9]; + if( pose->mask & 0x200) + scale[2] += *framedata++ * pose->channelscale[9]; // construct transformation matrix JointToMatrix( rotate, scale, translate, mat1 ); @@ -563,6 +572,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na for( i = 0; i < header->num_meshes; i++, mesh++, surface++ ) { surface->surfaceType = SF_IQM; Q_strncpyz(surface->name, str + mesh->name, sizeof (surface->name)); + Q_strlwr(surface->name); // lowercase the surface name so skin compares are faster surface->shader = R_FindShader( str + mesh->material, LIGHTMAP_NONE, qtrue ); if( surface->shader->defaultShader ) surface->shader = tr.defaultShader; @@ -677,6 +687,11 @@ static int R_CullIQM( iqmData_t *data, trRefEntity_t *ent ) { vec_t *oldBounds, *newBounds; int i; + if (!data->bounds) { + tr.pc.c_box_cull_md3_clip++; + return CULL_CLIP; + } + // compute bounds pointers oldBounds = data->bounds + 6*ent->e.oldframe; newBounds = data->bounds + 6*ent->e.frame; @@ -712,6 +727,7 @@ int R_ComputeIQMFogNum( iqmData_t *data, trRefEntity_t *ent ) { int i, j; fog_t *fog; vec_t *bounds; + const vec_t defaultBounds[6] = { -8, -8, -8, 8, 8, 8 }; vec3_t diag, center; vec3_t localOrigin; vec_t radius; @@ -721,7 +737,11 @@ int R_ComputeIQMFogNum( iqmData_t *data, trRefEntity_t *ent ) { } // FIXME: non-normalized axis issues - bounds = data->bounds + 6*ent->e.frame; + if (data->bounds) { + bounds = data->bounds + 6*ent->e.frame; + } else { + bounds = defaultBounds; + } VectorSubtract( bounds+3, bounds, diag ); VectorMA( bounds, 0.5f, diag, center ); VectorAdd( ent->e.origin, center, localOrigin ); @@ -879,7 +899,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe, mat1 = data->poseMats + 12 * data->num_joints * frame; mat2 = data->poseMats + 12 * data->num_joints * oldframe; - for( i = 0; i < 12 * data->num_joints; i++, joint++ ) { + for( i = 0; i < data->num_joints; i++, joint++ ) { if( *joint >= 0 ) { float tmpMat[12]; InterpolateMatrix( mat1 + 12*i, mat2 + 12*i, @@ -1031,8 +1051,11 @@ int R_IQMLerpTag( orientation_t *tag, iqmData_t *data, break; names += strlen( names ) + 1; } - if( joint >= data->num_joints ) + if( joint >= data->num_joints ) { + AxisClear( tag->axis ); + VectorClear( tag->origin ); return qfalse; + } ComputeJointMats( data, startFrame, endFrame, frac, jointMats ); @@ -1047,7 +1070,7 @@ int R_IQMLerpTag( orientation_t *tag, iqmData_t *data, tag->axis[0][2] = jointMats[12 * joint + 8]; tag->axis[1][2] = jointMats[12 * joint + 9]; tag->axis[2][2] = jointMats[12 * joint + 10]; - tag->origin[0] = jointMats[12 * joint + 11]; + tag->origin[2] = jointMats[12 * joint + 11]; - return qfalse; + return qtrue; } |