mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2025-02-20 19:12:15 +00:00
Fix loading and rendering IQMs with no joints
This commit is contained in:
parent
ecd50f01c2
commit
bf962c516d
2 changed files with 182 additions and 148 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue