rt: improve prev frame bone matrix tracking for studio models

Still has some artifacts, but is generally rather close. Will look at
this again when caching studio model BLASes, as we'd be able to look at
them without extra animations.
This commit is contained in:
Ivan Avdeev 2023-05-15 09:27:35 -07:00 committed by Ivan Avdeev
parent 091c61a45f
commit e54913f8af
4 changed files with 26 additions and 22 deletions

View File

@ -58,8 +58,8 @@ prev_state_t* prevStateInArrayBounds( int frame_storage_id, int entity_id )
return &g_prev.prev_states[frame_storage_id][clamped_entity_id];
}
#define PREV_FRAME() prevStateInArrayBounds( g_prev.previous_frame_id, entity_id )
#define CURRENT_FRAME() prevStateInArrayBounds( g_prev.current_frame_id, entity_id )
#define PREV_FRAME(entity_id) prevStateInArrayBounds( g_prev.previous_frame_id, (entity_id) )
#define CURRENT_FRAME(entity_id) prevStateInArrayBounds( g_prev.current_frame_id, (entity_id) )
void R_PrevFrame_StartFrame( void )
{
@ -70,7 +70,7 @@ void R_PrevFrame_StartFrame( void )
void R_PrevFrame_SaveCurrentBoneTransforms( int entity_id, matrix3x4* bones_transforms, const matrix4x4 rotationmatrix_inv )
{
prev_state_t *current_frame = CURRENT_FRAME();
prev_state_t *current_frame = CURRENT_FRAME(entity_id);
if (current_frame->bones_frame_updated == g_prev.frame_index)
return; // already updated for this entity
@ -78,16 +78,12 @@ void R_PrevFrame_SaveCurrentBoneTransforms( int entity_id, matrix3x4* bones_tran
current_frame->bones_frame_updated = g_prev.frame_index;
for( int i = 0; i < MAXSTUDIOBONES; i++ )
{
// FIXME I don't see how this can work. It has only a single copy of bones transforms, but they are not global, they're per-model
// Better way to handle this would be to avoid messing with bones_transforms at all, and just cache post-transformed vertices
Matrix3x4_ConcatTransforms( current_frame->bones_worldtransform[i], bones_transforms[i], rotationmatrix_inv );
}
Matrix3x4_ConcatTransforms( current_frame->bones_worldtransform[i], rotationmatrix_inv, bones_transforms[i] );
}
void R_PrevFrame_SaveCurrentState( int entity_id, matrix4x4 model_transform )
{
prev_state_t* current_frame = CURRENT_FRAME();
prev_state_t* current_frame = CURRENT_FRAME(entity_id);
if (current_frame->frame_updated == g_prev.frame_index)
return; // already updated for this entity
@ -99,29 +95,29 @@ void R_PrevFrame_SaveCurrentState( int entity_id, matrix4x4 model_transform )
matrix3x4* R_PrevFrame_BoneTransforms( int entity_id )
{
prev_state_t* prev_frame = PREV_FRAME();
prev_state_t* prev_frame = PREV_FRAME(entity_id);
// fallback to current frame if previous is outdated
if (prev_frame->bones_frame_updated != g_prev.frame_index - 1)
return CURRENT_FRAME()->bones_worldtransform;
return CURRENT_FRAME(entity_id)->bones_worldtransform;
return prev_frame->bones_worldtransform;
}
void R_PrevFrame_ModelTransform( int entity_id, matrix4x4 model_matrix )
{
prev_state_t* prev_frame = PREV_FRAME();
prev_state_t* prev_frame = PREV_FRAME(entity_id);
// fallback to current frame if previous is outdated
if (prev_frame->frame_updated != g_prev.frame_index - 1)
prev_frame = CURRENT_FRAME();
prev_frame = CURRENT_FRAME(entity_id);
Matrix4x4_Copy(model_matrix, prev_frame->model_transform);
}
float R_PrevFrame_Time( int entity_id )
{
prev_state_t* prev_frame = PREV_FRAME();
prev_state_t* prev_frame = PREV_FRAME(entity_id);
// fallback to current frame if previous is outdated
if (prev_frame->frame_updated != g_prev.frame_index - 1)

View File

@ -3,8 +3,8 @@
#include "vk_common.h"
void R_PrevFrame_StartFrame(void);
void R_PrevFrame_SaveCurrentBoneTransforms( int entity_id, matrix3x4* bones_transforms, const matrix4x4 rotationmatrix_inv );
void R_PrevFrame_SaveCurrentBoneTransforms(int entity_id, matrix3x4* bones_transforms, const matrix4x4 rotationmatrix_inv);
void R_PrevFrame_SaveCurrentState(int entity_id, matrix4x4 model_transform);
matrix3x4* R_PrevFrame_BoneTransforms(int entity_id);
void R_PrevFrame_ModelTransform( int entity_id, matrix4x4 model_matrix );
void R_PrevFrame_ModelTransform(int entity_id, matrix4x4 model_matrix);
float R_PrevFrame_Time(int entity_id);

View File

@ -134,7 +134,7 @@ qboolean VK_RenderModelInit( vk_render_model_t* model );
void VK_RenderModelDestroy( vk_render_model_t* model );
void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model );
void VK_RenderModelDynamicBegin( vk_render_type_e render_type, const vec4_t color, const matrix4x4 transform, const char *debug_name_fmt, ... );
void VK_RenderModelDynamicBegin( vk_render_type_e render_type, const vec4_t color, const matrix3x4 transform, const char *debug_name_fmt, ... );
void VK_RenderModelDynamicAddGeometry( const vk_render_geometry_t *geom );
void VK_RenderModelDynamicCommit( void );

View File

@ -874,7 +874,7 @@ void R_StudioMergeBones( cl_entity_t *e, model_t *m_pSubModel )
Matrix3x4_FromOriginQuat( bonematrix, q[i], pos[i] );
if( pbones[i].parent == -1 )
{
Matrix3x4_Copy( g_studio.bonestransform[i], bonematrix );
Matrix3x4_ConcatTransforms( g_studio.bonestransform[i], g_studio.rotationmatrix, bonematrix );
Matrix3x4_Copy( g_studio.lighttransform[i], g_studio.bonestransform[i] );
// apply client-side effects to the transformation matrix
@ -1032,7 +1032,7 @@ void R_StudioSetupBones( cl_entity_t *e )
if( pbones[i].parent == -1 )
{
Matrix3x4_Copy( g_studio.bonestransform[i], bonematrix );
Matrix3x4_ConcatTransforms( g_studio.bonestransform[i], g_studio.rotationmatrix, bonematrix );
Matrix3x4_Copy( g_studio.lighttransform[i], g_studio.bonestransform[i] );
// apply client-side effects to the transformation matrix
@ -2178,7 +2178,11 @@ static void R_StudioDrawPoints( void )
for( i = 0; i < m_pSubModel->numverts; i++ )
{
R_StudioComputeSkinMatrix( &pvertweight[i], g_studio.worldtransform, skinMat );
Matrix3x4_VectorTransform( skinMat, pstudioverts[i], g_studio.verts[i] );
vec3_t v;
Matrix3x4_VectorTransform( skinMat, pstudioverts[i], v);
Matrix3x4_VectorTransform( rotationmatrix_inv, v, g_studio.verts[i] );
R_LightStrength( pvertbone[i], pstudioverts[i], g_studio.lightpos[i] );
}
@ -2193,7 +2197,10 @@ static void R_StudioDrawPoints( void )
for( i = 0; i < m_pSubModel->numnorms; i++ )
{
R_StudioComputeSkinMatrix( &pnormweight[i], g_studio.worldtransform, skinMat );
Matrix3x4_VectorRotate( skinMat, pstudionorms[i], g_studio.norms[i] );
vec3_t v;
Matrix3x4_VectorRotate( skinMat, pstudionorms[i], v);
Matrix3x4_VectorRotate( rotationmatrix_inv, v, g_studio.norms[i] );
}
}
else
@ -2206,8 +2213,9 @@ static void R_StudioDrawPoints( void )
vec3_t v;
Matrix3x4_VectorTransform( g_studio.bonestransform[pvertbone[i]], pstudioverts[i], v);
Matrix3x4_VectorTransform( rotationmatrix_inv, v, g_studio.verts[i] );
Matrix3x4_VectorTransform( prev_bones_transforms[pvertbone[i]], pstudioverts[i], g_studio.prev_verts[i] );
R_LightStrength( pvertbone[i], pstudioverts[i], g_studio.lightpos[i] );
Matrix3x4_VectorTransform( prev_bones_transforms[pvertbone[i]], pstudioverts[i], g_studio.prev_verts[i] );
}
}