public: merge calc bone quaternion and position into single function

Expect that only adj and output quaternion can be NULL.
This commit is contained in:
Alibek Omarov 2025-02-11 18:49:25 +03:00
parent eb09af0b08
commit 39659644bf
5 changed files with 64 additions and 162 deletions

View file

@ -382,8 +382,7 @@ static void Mod_StudioCalcRotations( int boneused[], int numbones, const byte *p
for( j = numbones - 1; j >= 0; j-- ) for( j = numbones - 1; j >= 0; j-- )
{ {
i = boneused[j]; i = boneused[j];
R_StudioCalcBoneQuaternion( frame, s, &pbone[i], &panim[i], adj, q[i] ); R_StudioCalcBones( frame, s, &pbone[i], &panim[i], adj, pos[i], q[i] );
R_StudioCalcBonePosition( frame, s, &pbone[i], &panim[i], adj, pos[i] );
} }
if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f; if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
@ -724,7 +723,7 @@ void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs, qboolean i
{ {
for( k = 0; k < pseqdesc->numframes; k++ ) for( k = 0; k < pseqdesc->numframes; k++ )
{ {
R_StudioCalcBonePosition( k, 0, &pbones[j], panim, NULL, pos ); R_StudioCalcBones( k, 0, &pbones[i], panim, NULL, pos, NULL );
Mod_StudioBoundVertex( vert_mins, vert_maxs, &bone_count, pos ); Mod_StudioBoundVertex( vert_mins, vert_maxs, &bone_count, pos );
} }
} }

View file

@ -453,174 +453,83 @@ int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p )
return sides; return sides;
} }
/* void R_StudioCalcBones( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec3_t pos, vec4_t q )
==================== {
StudioCalcBoneQuaternion float v1[6], v2[6];
int i, max;
==================== max = q != NULL ? 6 : 3;
*/
void R_StudioCalcBoneQuaternion( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec4_t q )
{
vec3_t angles1;
vec3_t angles2;
int j, k;
for( j = 0; j < 3; j++ ) for( ; i < max; i++ )
{ {
if( !panim || panim->offset[j+3] == 0 ) mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[i] );
int j = frame;
float fadj = 0.0f;
if( pbone->bonecontroller[i] >= 0 && adj != NULL )
fadj = adj[pbone->bonecontroller[i]];
if( panim->offset[i] == 0 )
{ {
angles2[j] = angles1[j] = pbone->value[j+3]; // default; v1[i] = v2[i] = pbone->value[i] + fadj;
continue;
} }
else
{
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
k = frame;
// debug
if( panimvalue->num.total < panimvalue->num.valid ) if( panimvalue->num.total < panimvalue->num.valid )
k = 0; j = 0;
// find span of values that includes the frame we want while( panimvalue->num.total <= j )
while( panimvalue->num.total <= k )
{ {
k -= panimvalue->num.total; j -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1; panimvalue += panimvalue->num.valid + 1;
// debug
if( panimvalue->num.total < panimvalue->num.valid ) if( panimvalue->num.total < panimvalue->num.valid )
k = 0; j = 0;
} }
// bah, missing blend! if( panimvalue->num.valid > j )
if( panimvalue->num.valid > k )
{ {
angles1[j] = panimvalue[k+1].value; v1[i] = panimvalue[j + 1].value;
if( panimvalue->num.valid > k + 1 ) if( panimvalue->num.valid > j + 1 )
{ v2[i] = panimvalue[j + 2].value;
angles2[j] = panimvalue[k+2].value; else if( panimvalue->num.total > j + 1 )
v2[i] = v1[i];
else
v2[i] = panimvalue[panimvalue->num.valid + 2].value;
} }
else else
{ {
if( panimvalue->num.total > k + 1 ) v1[i] = panimvalue[panimvalue->num.valid].value;
angles2[j] = angles1[j];
else angles2[j] = panimvalue[panimvalue->num.valid+2].value; if( panimvalue->num.total > j + 1 )
} v2[i] = v1[i];
}
else else
v2[i] = panimvalue[panimvalue->num.valid + 2].value;
}
v1[i] = pbone->value[i] + v1[i] * pbone->scale[i] + fadj;
v2[i] = pbone->value[i] + v2[i] * pbone->scale[i] + fadj;
}
if( !VectorCompare( v1, v2 ))
VectorLerp( v1, s, v2, pos );
else
VectorCopy( v1, pos );
if( q != NULL )
{ {
angles1[j] = panimvalue[panimvalue->num.valid].value; if( !VectorCompare( &v1[3], &v2[3] ))
if( panimvalue->num.total > k + 1 )
angles2[j] = angles1[j];
else angles2[j] = panimvalue[panimvalue->num.valid+2].value;
}
angles1[j] = pbone->value[j+3] + angles1[j] * pbone->scale[j+3];
angles2[j] = pbone->value[j+3] + angles2[j] * pbone->scale[j+3];
}
if( pbone->bonecontroller[j+3] != -1 && adj != NULL )
{
angles1[j] += adj[pbone->bonecontroller[j+3]];
angles2[j] += adj[pbone->bonecontroller[j+3]];
}
}
if( !VectorCompare( angles1, angles2 ))
{ {
vec4_t q1, q2; vec4_t q1, q2;
AngleQuaternion( angles1, q1, true ); AngleQuaternion( &v1[3], q1, true );
AngleQuaternion( angles2, q2, true ); AngleQuaternion( &v2[3], q2, true );
QuaternionSlerp( q1, q2, s, q ); QuaternionSlerp( q1, q2, s, q );
} }
else else
{ {
AngleQuaternion( angles1, q, true ); AngleQuaternion( &v1[3], q, true );
} }
} }
/*
====================
StudioCalcBonePosition
====================
*/
void R_StudioCalcBonePosition( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec3_t pos )
{
vec3_t origin1;
vec3_t origin2;
int j, k;
for( j = 0; j < 3; j++ )
{
if( !panim || panim->offset[j] == 0 )
{
origin2[j] = origin1[j] = pbone->value[j]; // default;
}
else
{
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
k = frame;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
// find span of values that includes the frame we want
while( panimvalue->num.total <= k )
{
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
}
// bah, missing blend!
if( panimvalue->num.valid > k )
{
origin1[j] = panimvalue[k+1].value;
if( panimvalue->num.valid > k + 1 )
{
origin2[j] = panimvalue[k+2].value;
}
else
{
if( panimvalue->num.total > k + 1 )
origin2[j] = origin1[j];
else origin2[j] = panimvalue[panimvalue->num.valid+2].value;
}
}
else
{
origin1[j] = panimvalue[panimvalue->num.valid].value;
if( panimvalue->num.total > k + 1 )
origin2[j] = origin1[j];
else origin2[j] = panimvalue[panimvalue->num.valid+2].value;
}
origin1[j] = pbone->value[j] + origin1[j] * pbone->scale[j];
origin2[j] = pbone->value[j] + origin2[j] * pbone->scale[j];
}
if( pbone->bonecontroller[j] != -1 && adj != NULL )
{
origin1[j] += adj[pbone->bonecontroller[j]];
origin2[j] += adj[pbone->bonecontroller[j]];
}
}
if( !VectorCompare( origin1, origin2 ))
{
VectorLerp( origin1, s, origin2, pos );
}
else
{
VectorCopy( origin1, pos );
}
} }

View file

@ -168,8 +168,8 @@ void VectorsAngles( const vec3_t forward, const vec3_t right, const vec3_t up, v
void PlaneIntersect( const mplane_t *plane, const vec3_t p0, const vec3_t p1, vec3_t out ); void PlaneIntersect( const mplane_t *plane, const vec3_t p0, const vec3_t p1, vec3_t out );
qboolean SphereIntersect( const vec3_t vSphereCenter, float fSphereRadiusSquared, const vec3_t vLinePt, const vec3_t vLineDir ); qboolean SphereIntersect( const vec3_t vSphereCenter, float fSphereRadiusSquared, const vec3_t vLinePt, const vec3_t vLineDir );
void QuaternionSlerp( const vec4_t p, const vec4_t q, float t, vec4_t qt ); void QuaternionSlerp( const vec4_t p, const vec4_t q, float t, vec4_t qt );
void R_StudioCalcBoneQuaternion( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec4_t q );
void R_StudioCalcBonePosition( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const vec3_t adj, vec3_t pos ); void R_StudioCalcBones( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec3_t pos, vec4_t q );
int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p ); int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p );
#define BOX_ON_PLANE_SIDE( emins, emaxs, p ) \ #define BOX_ON_PLANE_SIDE( emins, emaxs, p ) \
((( p )->type < 3 ) ? \ ((( p )->type < 3 ) ? \

View file

@ -816,10 +816,7 @@ static void R_StudioCalcRotations( cl_entity_t *e, float pos[][3], vec4_t *q, ms
R_StudioCalcBoneAdj( dadt, adj, e->curstate.controller, e->latched.prevcontroller, e->mouth.mouthopen ); R_StudioCalcBoneAdj( dadt, adj, e->curstate.controller, e->latched.prevcontroller, e->mouth.mouthopen );
for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ ) for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ )
{ R_StudioCalcBones( frame, s, pbone, panim, adj, q[i], pos[i] );
R_StudioCalcBoneQuaternion( frame, s, pbone, panim, adj, q[i] );
R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] );
}
if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f; if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
if( pseqdesc->motiontype & STUDIO_Y ) pos[pseqdesc->motionbone][1] = 0.0f; if( pseqdesc->motiontype & STUDIO_Y ) pos[pseqdesc->motionbone][1] = 0.0f;

View file

@ -835,10 +835,7 @@ static void R_StudioCalcRotations( cl_entity_t *e, float pos[][3], vec4_t *q, ms
R_StudioCalcBoneAdj( dadt, adj, e->curstate.controller, e->latched.prevcontroller, e->mouth.mouthopen ); R_StudioCalcBoneAdj( dadt, adj, e->curstate.controller, e->latched.prevcontroller, e->mouth.mouthopen );
for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ ) for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ )
{ R_StudioCalcBones( frame, s, pbone, panim, adj, q[i], pos[i] );
R_StudioCalcBoneQuaternion( frame, s, pbone, panim, adj, q[i] );
R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] );
}
if( pseqdesc->motiontype & STUDIO_X ) if( pseqdesc->motiontype & STUDIO_X )
pos[pseqdesc->motionbone][0] = 0.0f; pos[pseqdesc->motionbone][0] = 0.0f;