summaryrefslogtreecommitdiff
path: root/src/renderergl2/tr_model_iqm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderergl2/tr_model_iqm.c')
-rw-r--r--src/renderergl2/tr_model_iqm.c161
1 files changed, 89 insertions, 72 deletions
diff --git a/src/renderergl2/tr_model_iqm.c b/src/renderergl2/tr_model_iqm.c
index 41783de8..19cca777 100644
--- a/src/renderergl2/tr_model_iqm.c
+++ b/src/renderergl2/tr_model_iqm.c
@@ -334,68 +334,72 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
}
}
- // check and swap joints
- if( IQM_CheckRange( header, header->ofs_joints,
- header->num_joints, sizeof(iqmJoint_t) ) ) {
+ if( header->num_poses != header->num_joints ) {
return qfalse;
}
- joint = (iqmJoint_t *)((byte *)header + header->ofs_joints);
- joint_names = 0;
- for( i = 0; i < header->num_joints; i++, joint++ ) {
- LL( joint->name );
- LL( joint->parent );
- LL( joint->translate[0] );
- LL( joint->translate[1] );
- LL( joint->translate[2] );
- 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] );
-
- if( joint->parent < -1 ||
- joint->parent >= (int)header->num_joints ||
- joint->name >= (int)header->num_text ) {
+
+ if ( header->num_joints )
+ {
+ // check and swap joints
+ if( IQM_CheckRange( header, header->ofs_joints,
+ header->num_joints, sizeof(iqmJoint_t) ) ) {
return qfalse;
}
- joint_names += strlen( (char *)header + header->ofs_text +
- joint->name ) + 1;
- }
+ joint = (iqmJoint_t *)((byte *)header + header->ofs_joints);
+ joint_names = 0;
+ for( i = 0; i < header->num_joints; i++, joint++ ) {
+ LL( joint->name );
+ LL( joint->parent );
+ LL( joint->translate[0] );
+ LL( joint->translate[1] );
+ LL( joint->translate[2] );
+ 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] );
+
+ if( joint->parent < -1 ||
+ joint->parent >= (int)header->num_joints ||
+ joint->name >= (int)header->num_text ) {
+ return qfalse;
+ }
+ joint_names += strlen( (char *)header + header->ofs_text +
+ joint->name ) + 1;
+ }
- // check and swap poses
- if( header->num_poses != header->num_joints ) {
- return qfalse;
- }
- if( IQM_CheckRange( header, header->ofs_poses,
- header->num_poses, sizeof(iqmPose_t) ) ) {
- return qfalse;
- }
- pose = (iqmPose_t *)((byte *)header + header->ofs_poses);
- for( i = 0; i < header->num_poses; i++, pose++ ) {
- LL( pose->parent );
- LL( pose->mask );
- LL( pose->channeloffset[0] );
- LL( pose->channeloffset[1] );
- LL( pose->channeloffset[2] );
- LL( pose->channeloffset[3] );
- LL( pose->channeloffset[4] );
- LL( pose->channeloffset[5] );
- 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] );
- LL( pose->channelscale[3] );
- LL( pose->channelscale[4] );
- LL( pose->channelscale[5] );
- LL( pose->channelscale[6] );
- LL( pose->channelscale[7] );
- LL( pose->channelscale[8] );
- LL( pose->channelscale[9] );
+ // check and swap poses
+ if( IQM_CheckRange( header, header->ofs_poses,
+ header->num_poses, sizeof(iqmPose_t) ) ) {
+ return qfalse;
+ }
+ pose = (iqmPose_t *)((byte *)header + header->ofs_poses);
+ for( i = 0; i < header->num_poses; i++, pose++ ) {
+ LL( pose->parent );
+ LL( pose->mask );
+ LL( pose->channeloffset[0] );
+ LL( pose->channeloffset[1] );
+ LL( pose->channeloffset[2] );
+ LL( pose->channeloffset[3] );
+ LL( pose->channeloffset[4] );
+ LL( pose->channeloffset[5] );
+ 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] );
+ LL( pose->channelscale[3] );
+ LL( pose->channelscale[4] );
+ LL( pose->channelscale[5] );
+ LL( pose->channelscale[6] );
+ LL( pose->channelscale[7] );
+ LL( pose->channelscale[8] );
+ LL( pose->channelscale[9] );
+ }
}
if (header->ofs_bounds)
@@ -468,6 +472,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
iqmData->triangles = iqmData->jointParents + header->num_joints;
iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles);
+ if ( header->num_joints == 0 )
+ iqmData->jointMats = iqmData->poseMats = NULL;
+
// calculate joint matrices and their inverses
// joint inverses are needed only until the pose matrices are calculated
mat = iqmData->jointMats;
@@ -941,8 +948,8 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
vec2_t (*outTexCoord)[2] = &tess.texCoords[tess.numVertexes];
vec4_t *outColor = &tess.vertexColors[tess.numVertexes];
- int frame = backEnd.currentEntity->e.frame % data->num_frames;
- int oldframe = backEnd.currentEntity->e.oldframe % data->num_frames;
+ int frame = data->num_frames ? backEnd.currentEntity->e.frame % data->num_frames : 0;
+ int oldframe = data->num_frames ? backEnd.currentEntity->e.oldframe % data->num_frames : 0;
float backlerp = backEnd.currentEntity->e.backlerp;
int *tri;
@@ -952,7 +959,9 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
// compute interpolated joint matrices
- ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
+ if ( data->num_joints > 0 ) {
+ ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
+ }
// transform vertexes and fill other data
for( i = 0; i < surf->num_vertexes;
@@ -962,20 +971,28 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
float nrmMat[9];
int vtx = i + surf->first_vertex;
- // compute the vertex matrix by blending the up to
- // four blend weights
- for( k = 0; k < 12; k++ )
- vtxMat[k] = data->blendWeights[4*vtx]
- * jointMats[12*data->blendIndexes[4*vtx] + k];
- for( j = 1; j < 4; j++ ) {
- if( data->blendWeights[4*vtx + j] <= 0 )
- break;
+ if ( data->num_joints == 0 || data->blendWeights[4*vtx] <= 0 ) {
+ // no blend joint, use identity matrix.
+ for( j = 0; j < 3; j++ ) {
+ for( k = 0; k < 4; k++ )
+ vtxMat[4*j+k] = ( k == j ) ? 1 : 0;
+ }
+ } else {
+ // compute the vertex matrix by blending the up to
+ // four blend weights
+ for( k = 0; k < 12; k++ )
+ vtxMat[k] = data->blendWeights[4*vtx]
+ * jointMats[12*data->blendIndexes[4*vtx] + k];
+ for( j = 1; j < 4; j++ ) {
+ if( data->blendWeights[4*vtx + j] <= 0 )
+ break;
+ for( k = 0; k < 12; k++ )
+ vtxMat[k] += data->blendWeights[4*vtx + j]
+ * jointMats[12*data->blendIndexes[4*vtx + j] + k];
+ }
for( k = 0; k < 12; k++ )
- vtxMat[k] += data->blendWeights[4*vtx + j]
- * jointMats[12*data->blendIndexes[4*vtx + j] + k];
+ vtxMat[k] *= 1.0f / 255.0f;
}
- for( k = 0; k < 12; k++ )
- vtxMat[k] *= 1.0f / 255.0f;
// compute the normal matrix as transpose of the adjoint
// of the vertex matrix