mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2025-02-21 11:30:56 +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
|
// check and swap joints
|
||||||
if( IQM_CheckRange( header, header->ofs_joints,
|
if( IQM_CheckRange( header, header->ofs_joints,
|
||||||
header->num_joints, sizeof(iqmJoint_t) ) ) {
|
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
|
// check and swap poses
|
||||||
if( header->num_poses != header->num_joints ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
if( IQM_CheckRange( header, header->ofs_poses,
|
if( IQM_CheckRange( header, header->ofs_poses,
|
||||||
header->num_poses, sizeof(iqmPose_t) ) ) {
|
header->num_poses, sizeof(iqmPose_t) ) ) {
|
||||||
return qfalse;
|
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[8] );
|
||||||
LL( pose->channelscale[9] );
|
LL( pose->channelscale[9] );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (header->ofs_bounds)
|
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->triangles = iqmData->jointParents + header->num_joints;
|
||||||
iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles);
|
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
|
// calculate joint matrices and their inverses
|
||||||
// joint inverses are needed only until the pose matrices are calculated
|
// joint inverses are needed only until the pose matrices are calculated
|
||||||
mat = iqmData->jointMats;
|
mat = iqmData->jointMats;
|
||||||
|
@ -941,8 +948,8 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
vec2_t (*outTexCoord)[2] = &tess.texCoords[tess.numVertexes];
|
vec2_t (*outTexCoord)[2] = &tess.texCoords[tess.numVertexes];
|
||||||
color4ub_t *outColor = &tess.vertexColors[tess.numVertexes];
|
color4ub_t *outColor = &tess.vertexColors[tess.numVertexes];
|
||||||
|
|
||||||
int frame = backEnd.currentEntity->e.frame % data->num_frames;
|
int frame = data->num_frames ? backEnd.currentEntity->e.frame % data->num_frames : 0;
|
||||||
int oldframe = backEnd.currentEntity->e.oldframe % data->num_frames;
|
int oldframe = data->num_frames ? backEnd.currentEntity->e.oldframe % data->num_frames : 0;
|
||||||
float backlerp = backEnd.currentEntity->e.backlerp;
|
float backlerp = backEnd.currentEntity->e.backlerp;
|
||||||
|
|
||||||
int *tri;
|
int *tri;
|
||||||
|
@ -952,7 +959,9 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
|
RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
|
||||||
|
|
||||||
// compute interpolated joint matrices
|
// compute interpolated joint matrices
|
||||||
|
if ( data->num_joints > 0 ) {
|
||||||
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
|
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
|
||||||
|
}
|
||||||
|
|
||||||
// transform vertexes and fill other data
|
// transform vertexes and fill other data
|
||||||
for( i = 0; i < surf->num_vertexes;
|
for( i = 0; i < surf->num_vertexes;
|
||||||
|
@ -962,6 +971,13 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
float nrmMat[9];
|
float nrmMat[9];
|
||||||
int vtx = i + surf->first_vertex;
|
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
|
// compute the vertex matrix by blending the up to
|
||||||
// four blend weights
|
// four blend weights
|
||||||
for( k = 0; k < 12; k++ )
|
for( k = 0; k < 12; k++ )
|
||||||
|
@ -976,6 +992,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
}
|
}
|
||||||
for( k = 0; k < 12; k++ )
|
for( k = 0; k < 12; k++ )
|
||||||
vtxMat[k] *= 1.0f / 255.0f;
|
vtxMat[k] *= 1.0f / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// compute the normal matrix as transpose of the adjoint
|
// compute the normal matrix as transpose of the adjoint
|
||||||
// of the vertex matrix
|
// 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
|
// check and swap joints
|
||||||
if( IQM_CheckRange( header, header->ofs_joints,
|
if( IQM_CheckRange( header, header->ofs_joints,
|
||||||
header->num_joints, sizeof(iqmJoint_t) ) ) {
|
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
|
// check and swap poses
|
||||||
if( header->num_poses != header->num_joints ) {
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
if( IQM_CheckRange( header, header->ofs_poses,
|
if( IQM_CheckRange( header, header->ofs_poses,
|
||||||
header->num_poses, sizeof(iqmPose_t) ) ) {
|
header->num_poses, sizeof(iqmPose_t) ) ) {
|
||||||
return qfalse;
|
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[8] );
|
||||||
LL( pose->channelscale[9] );
|
LL( pose->channelscale[9] );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (header->ofs_bounds)
|
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->triangles = iqmData->jointParents + header->num_joints;
|
||||||
iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles);
|
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
|
// calculate joint matrices and their inverses
|
||||||
// joint inverses are needed only until the pose matrices are calculated
|
// joint inverses are needed only until the pose matrices are calculated
|
||||||
mat = iqmData->jointMats;
|
mat = iqmData->jointMats;
|
||||||
|
@ -941,8 +948,8 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
vec2_t (*outTexCoord)[2] = &tess.texCoords[tess.numVertexes];
|
vec2_t (*outTexCoord)[2] = &tess.texCoords[tess.numVertexes];
|
||||||
vec4_t *outColor = &tess.vertexColors[tess.numVertexes];
|
vec4_t *outColor = &tess.vertexColors[tess.numVertexes];
|
||||||
|
|
||||||
int frame = backEnd.currentEntity->e.frame % data->num_frames;
|
int frame = data->num_frames ? backEnd.currentEntity->e.frame % data->num_frames : 0;
|
||||||
int oldframe = backEnd.currentEntity->e.oldframe % data->num_frames;
|
int oldframe = data->num_frames ? backEnd.currentEntity->e.oldframe % data->num_frames : 0;
|
||||||
float backlerp = backEnd.currentEntity->e.backlerp;
|
float backlerp = backEnd.currentEntity->e.backlerp;
|
||||||
|
|
||||||
int *tri;
|
int *tri;
|
||||||
|
@ -952,7 +959,9 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
|
RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );
|
||||||
|
|
||||||
// compute interpolated joint matrices
|
// compute interpolated joint matrices
|
||||||
|
if ( data->num_joints > 0 ) {
|
||||||
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
|
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
|
||||||
|
}
|
||||||
|
|
||||||
// transform vertexes and fill other data
|
// transform vertexes and fill other data
|
||||||
for( i = 0; i < surf->num_vertexes;
|
for( i = 0; i < surf->num_vertexes;
|
||||||
|
@ -962,6 +971,13 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
float nrmMat[9];
|
float nrmMat[9];
|
||||||
int vtx = i + surf->first_vertex;
|
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
|
// compute the vertex matrix by blending the up to
|
||||||
// four blend weights
|
// four blend weights
|
||||||
for( k = 0; k < 12; k++ )
|
for( k = 0; k < 12; k++ )
|
||||||
|
@ -976,6 +992,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
}
|
}
|
||||||
for( k = 0; k < 12; k++ )
|
for( k = 0; k < 12; k++ )
|
||||||
vtxMat[k] *= 1.0f / 255.0f;
|
vtxMat[k] *= 1.0f / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// compute the normal matrix as transpose of the adjoint
|
// compute the normal matrix as transpose of the adjoint
|
||||||
// of the vertex matrix
|
// of the vertex matrix
|
||||||
|
|
Loading…
Reference in a new issue