Fix loading and rendering IQMs with no joints

This commit is contained in:
Zack Middleton 2013-03-18 14:13:09 -05:00
parent ecd50f01c2
commit bf962c516d
2 changed files with 182 additions and 148 deletions

View file

@ -334,6 +334,12 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
}
}
if( header->num_poses != header->num_joints ) {
return qfalse;
}
if ( header->num_joints )
{
// check and swap joints
if( IQM_CheckRange( header, header->ofs_joints,
header->num_joints, sizeof(iqmJoint_t) ) ) {
@ -365,9 +371,6 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
}
// 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;
@ -397,6 +400,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
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];
color4ub_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
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,6 +971,13 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
float nrmMat[9];
int vtx = i + surf->first_vertex;
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++ )
@ -976,6 +992,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
}
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

View file

@ -334,6 +334,12 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
}
}
if( header->num_poses != header->num_joints ) {
return qfalse;
}
if ( header->num_joints )
{
// check and swap joints
if( IQM_CheckRange( header, header->ofs_joints,
header->num_joints, sizeof(iqmJoint_t) ) ) {
@ -365,9 +371,6 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
}
// 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;
@ -397,6 +400,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
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
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,6 +971,13 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
float nrmMat[9];
int vtx = i + surf->first_vertex;
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++ )
@ -976,6 +992,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
}
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