05 Apr 2010
This commit is contained in:
parent
9f0fb3da32
commit
432fa48d5d
|
@ -207,7 +207,6 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
// copy state to progs
|
||||
ent->v.modelindex = state->modelindex;
|
||||
ent->v.weaponmodel = state->weaponmodel;
|
||||
ent->v.frame = state->frame;
|
||||
ent->v.sequence = state->sequence;
|
||||
ent->v.gaitsequence = state->gaitsequence;
|
||||
ent->v.body = state->body;
|
||||
|
@ -215,7 +214,7 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
ent->v.effects = state->effects;
|
||||
ent->v.velocity = state->velocity;
|
||||
ent->v.basevelocity = state->basevelocity;
|
||||
ent->v.oldorigin = ent->v.origin;
|
||||
ent->v.oldorigin = ent->v.origin; // previous origin holds
|
||||
ent->v.mins = state->mins;
|
||||
ent->v.maxs = state->maxs;
|
||||
ent->v.framerate = state->framerate;
|
||||
|
@ -231,7 +230,6 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
ent->v.movetype = state->movetype;
|
||||
ent->v.flags = state->flags;
|
||||
ent->v.ideal_pitch = state->idealpitch;
|
||||
ent->v.oldangles = ent->v.angles; // just a delta between frames
|
||||
ent->v.animtime = state->animtime;
|
||||
|
||||
if( state->groundent != -1 )
|
||||
|
@ -245,99 +243,36 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
switch( ent->v.movetype )
|
||||
{
|
||||
case MOVETYPE_NONE:
|
||||
case MOVETYPE_STEP:
|
||||
// monster's steps will be interpolated on render-side
|
||||
ent->v.origin = state->origin;
|
||||
ent->v.angles = state->angles;
|
||||
break;
|
||||
default:
|
||||
ent->v.angles = LerpAngle( prev->angles, state->angles, m_fLerp );
|
||||
ent->v.origin = LerpPoint( prev->origin, state->origin, m_fLerp );
|
||||
ent->v.basevelocity = LerpPoint( prev->basevelocity, state->basevelocity, m_fLerp );
|
||||
break;
|
||||
}
|
||||
|
||||
// lerping some fields
|
||||
for( i = 0; i < 3; i++ )
|
||||
// interpolate scale, renderamount etc
|
||||
ent->v.scale = LerpPoint( prev->scale, state->scale, m_fLerp );
|
||||
ent->v.rendercolor = LerpPoint( prev->rendercolor, state->rendercolor, m_fLerp );
|
||||
ent->v.renderamt = LerpPoint( prev->renderamt, state->renderamt, m_fLerp );
|
||||
|
||||
// auto-animation uses v.frame for hold ending frame
|
||||
if(!( ent->v.effects & EF_ANIMATE ))
|
||||
{
|
||||
ent->v.angles[i] = LerpAngle( prev->angles[i], state->angles[i], m_fLerp );
|
||||
ent->v.rendercolor[i] = LerpPoint( prev->rendercolor[i], state->rendercolor[i], m_fLerp );
|
||||
}
|
||||
|
||||
if( ent->v.movetype == MOVETYPE_STEP )
|
||||
{
|
||||
float f = 0;
|
||||
float d;
|
||||
|
||||
// don't do it if the goalstarttime hasn't updated in a while.
|
||||
|
||||
// NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit
|
||||
// was increased to 1.0 s., which is 2x the max lag we are accounting for.
|
||||
|
||||
if(( gpGlobals->time < state->animtime + 1.0f ) && ( state->animtime != prev->animtime ))
|
||||
if( ent->v.animtime )
|
||||
{
|
||||
f = (gpGlobals->time - state->animtime) / (state->animtime - prev->animtime);
|
||||
//ALERT( at_console, "%4.2f %.2f %.2f\n", f, state->animtime, gpGlobals->time );
|
||||
}
|
||||
|
||||
if(!( ent->v.flags & EF_NOINTERP ))
|
||||
{
|
||||
// ugly hack to interpolate angle, position.
|
||||
// current is reached 0.1 seconds after being set
|
||||
f = f - 1.0;
|
||||
// use normal studio lerping
|
||||
ent->v.frame = state->frame;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = 0;
|
||||
// sprite frames will be interpolated in other place
|
||||
ent->v.frame = Q_rint( state->frame );
|
||||
}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
ent->v.origin[i] += (ent->v.origin[i] - prev->origin[i]) * f;
|
||||
}
|
||||
|
||||
// NOTE: Because multiplayer lag can be relatively large, we don't want to cap
|
||||
// f at 1.5 anymore.
|
||||
//if( f > -1.0 && f < 1.5 ) {}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
float ang1, ang2;
|
||||
|
||||
ang1 = ent->v.angles[i];
|
||||
ang2 = prev->angles[i];
|
||||
|
||||
d = ang1 - ang2;
|
||||
if( d > 180 )
|
||||
{
|
||||
d -= 360;
|
||||
}
|
||||
else if( d < -180 )
|
||||
{
|
||||
d += 360;
|
||||
}
|
||||
ent->v.angles[i] += d * f;
|
||||
}
|
||||
//ALERT( at_console, "%.3f \n", f );
|
||||
}
|
||||
|
||||
// interpolate scale, renderamount etc
|
||||
ent->v.renderamt = LerpPoint( prev->renderamt, state->renderamt, m_fLerp );
|
||||
ent->v.scale = LerpPoint( prev->scale, state->scale, m_fLerp );
|
||||
|
||||
if(!( ent->v.effects & EF_ANIMATE )) // auto-animation uses v.frame for hold ending frame
|
||||
{
|
||||
float frame = state->frame;
|
||||
float prevframe = prev->frame;
|
||||
float lerpTime = (frame - prevframe);
|
||||
|
||||
if( ent->v.animtime )
|
||||
{
|
||||
if(!( ent->v.effects & EF_NOINTERP ))
|
||||
{
|
||||
// adjust lerping values if animation restarted
|
||||
if( lerpTime < 0 ) prevframe = 1.001;
|
||||
ent->v.frame = LerpPoint( prevframe, frame, m_fLerp );
|
||||
}
|
||||
else ent->v.frame = state->frame; // use normal studio lerping
|
||||
}
|
||||
else ent->v.frame = Q_rint( state->frame ); // sprite frames will be interpolated in other place
|
||||
}
|
||||
|
||||
switch( state->ed_type )
|
||||
|
@ -390,26 +325,27 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
if( state->owner != -1 )
|
||||
ent->v.owner = GetEntityByIndex( state->owner );
|
||||
else ent->v.owner = NULL;
|
||||
|
||||
// add server beam now
|
||||
g_pViewRenderBeams->AddServerBeam( ent );
|
||||
break;
|
||||
default:
|
||||
ent->v.movedir = Vector( 0, 0, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
// add env_beam to drawing list
|
||||
if( state->ed_type == ED_BEAM )
|
||||
g_pViewRenderBeams->AddServerBeam( ent );
|
||||
|
||||
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
|
||||
{
|
||||
ent->v.blending[i] = LerpByte( prev->blending[i], state->blending[i], m_fLerp );
|
||||
}
|
||||
|
||||
for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ )
|
||||
{
|
||||
if( abs( prev->controller[i] - state->controller[i] ) > 128 )
|
||||
ent->v.controller[i] = state->controller[i];
|
||||
else ent->v.controller[i] = LerpByte( prev->controller[i], state->controller[i], m_fLerp );
|
||||
}
|
||||
|
||||
// g-cont. moved here because we may needs apply null scale to skyportal
|
||||
if( ent->v.scale == 0.0f ) ent->v.scale = 1.0f;
|
||||
ent->v.pContainingEntity = ent;
|
||||
|
|
|
@ -153,4 +153,13 @@ void HUD_StudioFxTransform( edict_t *ent, float transform[4][4] )
|
|||
transform[2][1] *= scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int HUD_StudioDoInterp( edict_t *e )
|
||||
{
|
||||
if( r_studio_lerping->integer )
|
||||
{
|
||||
return (e->v.flags & EF_NOINTERP) ? false : true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -44,6 +44,7 @@ extern void HUD_CreateEntities( void );
|
|||
extern int HUD_AddVisibleEntity( edict_t *pEnt, int ed_type );
|
||||
extern void HUD_StudioEvent( const dstudioevent_t *event, edict_t *entity );
|
||||
extern void HUD_StudioFxTransform( edict_t *ent, float transform[4][4] );
|
||||
extern int HUD_StudioDoInterp( edict_t *e );
|
||||
extern void HUD_ParseTempEntity( void );
|
||||
extern void V_CalcRefdef( ref_params_t *parms );
|
||||
extern void V_StartPitchDrift( void );
|
||||
|
@ -126,6 +127,17 @@ inline float LerpAngle( float a2, float a1, float frac )
|
|||
return a2 + frac * (a1 - a2);
|
||||
}
|
||||
|
||||
inline Vector LerpAngle( Vector a2, Vector a1, float frac )
|
||||
{
|
||||
Vector a3;
|
||||
|
||||
a3.x = LerpAngle( a2.x, a1.x, frac );
|
||||
a3.y = LerpAngle( a2.y, a1.y, frac );
|
||||
a3.z = LerpAngle( a2.z, a1.z, frac );
|
||||
|
||||
return a3;
|
||||
}
|
||||
|
||||
inline float LerpView( float org1, float org2, float ofs1, float ofs2, float frac )
|
||||
{
|
||||
return org1 + ofs1 + frac * (org2 + ofs2 - (org1 + ofs1));
|
||||
|
@ -211,6 +223,7 @@ extern int g_iAlive; // indicates alive local client or not
|
|||
// input.cpp
|
||||
extern cvar_t *v_centerspeed;
|
||||
extern cvar_t *v_centermove;
|
||||
extern cvar_t *r_studio_lerping;
|
||||
extern cvar_t *cl_forwardspeed;
|
||||
extern cvar_t *cl_particlelod;
|
||||
extern cvar_t *cl_particles;
|
||||
|
|
|
@ -56,6 +56,7 @@ cvar_t *cl_bobup;
|
|||
cvar_t *cl_waterdist;
|
||||
cvar_t *cl_chasedist;
|
||||
|
||||
cvar_t *r_studio_lerping;
|
||||
cvar_t *v_iyaw_cycle;
|
||||
cvar_t *v_iroll_cycle;
|
||||
cvar_t *v_ipitch_cycle;
|
||||
|
@ -131,6 +132,7 @@ void V_Init( void )
|
|||
scr_ofsx = g_engfuncs.pfnRegisterVariable( "scr_ofsx", "0", 0, "screen offset by X" );
|
||||
scr_ofsy = g_engfuncs.pfnRegisterVariable( "scr_ofsy", "0", 0, "screen offset by Y" );
|
||||
scr_ofsz = g_engfuncs.pfnRegisterVariable( "scr_ofsz", "0", 0, "screen offset by Z" );
|
||||
r_studio_lerping = g_engfuncs.pfnRegisterVariable( "r_studio_lerping", "1", FCVAR_ARCHIVE, "enables studio model animation lerping" ); // get copy of engine cvar
|
||||
|
||||
cl_vsmoothing = g_engfuncs.pfnRegisterVariable( "cl_vsmoothing", "0.05", 0, "enables lepring in multiplayer" );
|
||||
cl_stairsmooth = g_engfuncs.pfnRegisterVariable( "cl_vstairsmooth", "100", FCVAR_ARCHIVE, "how fast your view moves upward/downward when running up/down stairs" );
|
||||
|
|
|
@ -29,7 +29,6 @@ typedef struct entvars_s
|
|||
vec3_t movedir;
|
||||
|
||||
vec3_t angles; // ENG [all], NET [all]
|
||||
vec3_t oldangles; // ENG [all], NET [all]
|
||||
vec3_t avelocity; // angular velocity (degrees per second)
|
||||
vec3_t punchangle; // NET [player], auto-decaying view angle adjustment
|
||||
vec3_t viewangles; // NET [player], viewing angle (old name was v_angle)
|
||||
|
|
|
@ -148,7 +148,7 @@ byte CL_GetMouthOpen( int entityIndex )
|
|||
return ed->pvClientData->mouth.open;
|
||||
}
|
||||
|
||||
studioframe_t *CL_GetStudioFrame( int entityIndex )
|
||||
lerpframe_t *CL_GetLerpFrame( int entityIndex )
|
||||
{
|
||||
edict_t *pEnt = CL_GetEdictByIndex( entityIndex );
|
||||
|
||||
|
@ -793,7 +793,7 @@ void CL_InitWorld( void )
|
|||
}
|
||||
|
||||
// clear viewmodel prevstate
|
||||
Mem_Set( &clgame.viewent.pvClientData->frame, 0, sizeof( studioframe_t ));
|
||||
Mem_Set( &clgame.viewent.pvClientData->frame, 0, sizeof( lerpframe_t ));
|
||||
}
|
||||
|
||||
void CL_InitEdicts( void )
|
||||
|
|
|
@ -39,7 +39,7 @@ int CL_AddTempEntity( TEMPENTITY *pTemp, shader_t customShader )
|
|||
if( type == mod_studio || type == mod_sprite )
|
||||
{
|
||||
// alloc engine data to holds lerping values for studiomdls and sprites
|
||||
pTemp->pvEngineData = Mem_Alloc( cls.mempool, sizeof( studioframe_t ));
|
||||
pTemp->pvEngineData = Mem_Alloc( cls.mempool, sizeof( lerpframe_t ));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -173,7 +173,7 @@ struct cl_priv_s
|
|||
|
||||
entity_state_t current;
|
||||
entity_state_t prev; // will always be valid, but might just be a copy of current
|
||||
studioframe_t frame; // holds the studio values for right lerping
|
||||
lerpframe_t frame; // holds the studio values for right lerping
|
||||
|
||||
// studiomodels attachments
|
||||
vec3_t origin[MAXSTUDIOATTACHMENTS];
|
||||
|
|
|
@ -224,7 +224,7 @@ bool CL_GetAttachment( int entityIndex, int number, vec3_t origin, vec3_t angles
|
|||
bool CL_SetAttachment( int entityIndex, int number, vec3_t origin, vec3_t angles );
|
||||
void CL_StudioEvent( dstudioevent_t *event, edict_t *ent );
|
||||
bool CL_GetComment( const char *demoname, char *comment );
|
||||
studioframe_t *CL_GetStudioFrame( int entityIndex );
|
||||
lerpframe_t *CL_GetLerpFrame( int entityIndex );
|
||||
edict_t *CL_GetEdictByIndex( int index );
|
||||
edict_t *CL_GetLocalPlayer( void );
|
||||
int CL_GetMaxClients( void );
|
||||
|
|
|
@ -174,7 +174,7 @@ bool Host_InitRender( void )
|
|||
ri.GetAttachment = CL_GetAttachment;
|
||||
ri.SetAttachment = CL_SetAttachment;
|
||||
ri.GetClientEdict = CL_GetEdictByIndex;
|
||||
ri.GetStudioFrame = CL_GetStudioFrame;
|
||||
ri.GetLerpFrame = CL_GetLerpFrame;
|
||||
ri.GetMouthOpen = CL_GetMouthOpen;
|
||||
ri.GetLocalPlayer = CL_GetLocalPlayer;
|
||||
ri.GetMaxClients = CL_GetMaxClients;
|
||||
|
|
|
@ -60,37 +60,48 @@ typedef struct
|
|||
vec3_t normal;
|
||||
} fragment_t;
|
||||
|
||||
// hold values that needs for right studio lerping
|
||||
typedef struct
|
||||
{
|
||||
float frame;
|
||||
float animtime;
|
||||
int sequence;
|
||||
float sequencetime;
|
||||
float animtime; // curstate.animtime
|
||||
int sequence; // curstate.sequence
|
||||
float frame; // curstate.frame
|
||||
vec3_t origin; // curstate.origin
|
||||
vec3_t angles; // curstate.angles
|
||||
byte blending[16]; // curstate.blending
|
||||
byte controller[16]; // curstate.controller
|
||||
} currentvars_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float animtime; // latched.prevanimtime
|
||||
float sequencetime; // latechd.prevsequencetime
|
||||
byte seqblending[16]; // blending between sequence when it's changed
|
||||
vec3_t origin; // latched.prevorigin
|
||||
vec3_t angles; // latched.prevangles
|
||||
int sequence; // latched.prevsequence
|
||||
float frame; // latched.prevframe
|
||||
byte controller[16]; // latched.prevcontroller
|
||||
byte blending[16]; // latched.prevblending
|
||||
} latchedvars_t;
|
||||
|
||||
// hold values that needs for right studio and sprite lerping
|
||||
typedef struct
|
||||
{
|
||||
currentvars_t curstate;
|
||||
latchedvars_t latched;
|
||||
|
||||
// CLIENT SPECIFIC
|
||||
vec3_t gaitorigin; // client oldorigin used to calc velocity
|
||||
float gaitframe; // client->frame + yaw
|
||||
float gaityaw; // local value
|
||||
vec3_t gaitorigin; // client oldorigin used to calc velocity
|
||||
float gaitframe; // client->frame + yaw
|
||||
float gaityaw; // local value
|
||||
|
||||
// EF_ANIMATE stuff
|
||||
int m_fSequenceLoops; // sequence is looped
|
||||
int m_fSequenceFinished; // sequence is finished
|
||||
float m_flFrameRate; // looped sequence framerate
|
||||
float m_flGroundSpeed; // looped sequence ground speed (movement)
|
||||
float m_flLastEventCheck; // last time when event is checked
|
||||
|
||||
float curanimtime; // HACKHACK current animtime
|
||||
float curframe; // HACKHACK current frame
|
||||
|
||||
int cursequence; // HACKHACK current sequence
|
||||
byte curblending[16]; // HACKHACK current blending
|
||||
byte curcontroller[16]; // HACKHACL current blending
|
||||
|
||||
byte blending[16]; // previous blending values
|
||||
byte controller[16]; // previous controller values
|
||||
byte seqblending[16]; // blending between sequence when it's changed
|
||||
} studioframe_t;
|
||||
int m_fSequenceLoops; // sequence is looped
|
||||
int m_fSequenceFinished;// sequence is finished
|
||||
float m_flFrameRate; // looped sequence framerate
|
||||
float m_flGroundSpeed; // looped sequence ground speed (movement)
|
||||
float m_flLastEventCheck; // last time when event is checked
|
||||
} lerpframe_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -204,7 +215,7 @@ typedef struct render_imp_s
|
|||
bool (*GetAttachment)( int entityIndex, int number, vec3_t origin, vec3_t angles );
|
||||
bool (*SetAttachment)( int entityIndex, int number, vec3_t origin, vec3_t angles );
|
||||
edict_t *(*GetClientEdict)( int index );
|
||||
studioframe_t *(*GetStudioFrame)( int entityIndex );
|
||||
lerpframe_t *(*GetLerpFrame)( int entityIndex );
|
||||
byte (*GetMouthOpen)( int entityIndex );
|
||||
edict_t *(*GetLocalPlayer)( void );
|
||||
int (*GetMaxClients)( void );
|
||||
|
|
|
@ -30,7 +30,6 @@ TYPEDESCRIPTION gEntvarsDescription[] =
|
|||
DEFINE_ENTITY_FIELD( movedir, FIELD_VECTOR ),
|
||||
|
||||
DEFINE_ENTITY_FIELD( angles, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( oldangles, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( viewangles, FIELD_VECTOR ),
|
||||
|
|
|
@ -458,7 +458,6 @@ TYPEDESCRIPTION gEntvarsDescription[] =
|
|||
DEFINE_ENTITY_FIELD( movedir, FIELD_VECTOR ),
|
||||
|
||||
DEFINE_ENTITY_FIELD( angles, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( oldangles, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( viewangles, FIELD_VECTOR ),
|
||||
|
|
|
@ -215,8 +215,7 @@ typedef struct ref_entity_s
|
|||
|
||||
struct ref_model_s *model; // opaque type outside refresh
|
||||
struct ref_entity_s *parent; // link to parent entity (FOLLOW or weaponmodel)
|
||||
|
||||
studioframe_t *prev; // previous frame values for lerping
|
||||
lerpframe_t *lerp; // pointer to client entity lerpingdata (holds two frames)
|
||||
|
||||
float framerate; // custom framerate
|
||||
float frame;
|
||||
|
|
|
@ -722,7 +722,7 @@ static void R_AddSpriteModelToList( ref_entity_t *e )
|
|||
|
||||
if( R_SpriteOccluded( e )) return;
|
||||
|
||||
frame = R_GetSpriteFrame( e->model, e->prev->curframe, e->angles[YAW] );
|
||||
frame = R_GetSpriteFrame( e->model, e->lerp->curstate.frame, e->angles[YAW] );
|
||||
if( e->customShader ) shader = e->customShader;
|
||||
else shader = &r_shaders[frame->shader];
|
||||
|
||||
|
@ -2348,11 +2348,11 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
|
|||
break;
|
||||
}
|
||||
|
||||
refent->prev = ri.GetStudioFrame( refent->index ); // setup prevframe data
|
||||
refent->lerp = ri.GetLerpFrame( refent->index ); // get pointer to lerping frame data
|
||||
|
||||
if( refent->prev == NULL )
|
||||
if( refent->lerp == NULL )
|
||||
{
|
||||
MsgDev( D_ERROR, "Rejected entity %i (model %s) -- no prevframe data\n", refent->index, refent->model->name );
|
||||
MsgDev( D_ERROR, "Rejected entity %i (model %s) -- no lerpframe data\n", refent->index, refent->model->name );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2372,9 +2372,9 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
|
|||
{
|
||||
float numframes = ((msprite_t *)refent->model->extradata)->numframes;
|
||||
|
||||
refent->prev->curframe += (pRefEntity->v.framerate * RI.refdef.frametime);
|
||||
if( refent->prev->curframe > numframes && numframes > 0 )
|
||||
refent->prev->curframe = fmod( refent->prev->curframe, numframes );
|
||||
refent->lerp->curstate.frame += (pRefEntity->v.framerate * RI.refdef.frametime);
|
||||
if( refent->lerp->curstate.frame > numframes && numframes > 0 )
|
||||
refent->lerp->curstate.frame = fmod( refent->lerp->curstate.frame, numframes );
|
||||
}
|
||||
break;
|
||||
case mod_studio:
|
||||
|
@ -2385,16 +2385,10 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
|
|||
}
|
||||
else
|
||||
{
|
||||
refent->prev->frame = refent->prev->curframe; // save oldframe
|
||||
refent->prev->curframe = pRefEntity->v.frame;
|
||||
refent->lerp->latched.frame = refent->lerp->curstate.frame; // save oldframe
|
||||
refent->lerp->curstate.frame = pRefEntity->v.frame;
|
||||
}
|
||||
|
||||
if( refent->ent_type == ED_MOVER || refent->ent_type == ED_BSPBRUSH )
|
||||
{
|
||||
VectorNormalize2( pRefEntity->v.movedir, refent->movedir );
|
||||
}
|
||||
else VectorClear( refent->movedir );
|
||||
|
||||
// calculate angles
|
||||
if( refent->flags & EF_ROTATE )
|
||||
{
|
||||
|
@ -2408,6 +2402,20 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
|
|||
Matrix3x3_FromAngles( refent->angles, refent->axis );
|
||||
VectorClear( refent->origin2 );
|
||||
|
||||
if( refent->ent_type == ED_CLIENT )
|
||||
{
|
||||
refent->gaitsequence = pRefEntity->v.gaitsequence;
|
||||
refent->flags |= EF_OCCLUSIONTEST;
|
||||
refent->lightingOrigin[2] += refent->model->maxs[2] - 2; // drop shadow to floor
|
||||
}
|
||||
else refent->gaitsequence = 0;
|
||||
|
||||
if( refent->ent_type == ED_MOVER || refent->ent_type == ED_BSPBRUSH )
|
||||
{
|
||||
VectorNormalize2( pRefEntity->v.movedir, refent->movedir );
|
||||
}
|
||||
else VectorClear( refent->movedir );
|
||||
|
||||
if( refent->ent_type == ED_VIEWMODEL )
|
||||
{
|
||||
if( r_lefthand->integer == 1 )
|
||||
|
@ -2425,14 +2433,6 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
|
|||
refent->extradata = NULL;
|
||||
}
|
||||
|
||||
if( refent->ent_type == ED_CLIENT )
|
||||
{
|
||||
refent->gaitsequence = pRefEntity->v.gaitsequence;
|
||||
refent->flags |= EF_OCCLUSIONTEST;
|
||||
refent->lightingOrigin[2] += refent->model->maxs[2] - 2; // drop shadow to floor
|
||||
}
|
||||
else refent->gaitsequence = 0;
|
||||
|
||||
// because entity without models never added to scene
|
||||
if( !refent->ent_type )
|
||||
{
|
||||
|
@ -2538,7 +2538,7 @@ bool R_AddEntityToScene( edict_t *pRefEntity, int ed_type, shader_t customShader
|
|||
refent->movetype = pRefEntity->v.movetype;
|
||||
refent->framerate = pRefEntity->v.framerate;
|
||||
refent->parent = NULL;
|
||||
refent->prev = NULL;
|
||||
refent->lerp = NULL;
|
||||
|
||||
if( pRefEntity->v.rendermode == kRenderGlow && !pRefEntity->v.renderfx )
|
||||
refent->flags |= EF_OCCLUSIONTEST;
|
||||
|
@ -2637,7 +2637,7 @@ bool R_AddTeEntToScene( TEMPENTITY *pTempEntity, int ed_type, shader_t customSha
|
|||
refent->flags = EF_NOSHADOW;
|
||||
refent->gaitsequence = 0;
|
||||
refent->parent = NULL;
|
||||
refent->prev = NULL;
|
||||
refent->lerp = NULL;
|
||||
|
||||
refent->renderamt = R_ComputeFxBlend( refent );
|
||||
|
||||
|
@ -2665,11 +2665,11 @@ bool R_AddTeEntToScene( TEMPENTITY *pTempEntity, int ed_type, shader_t customSha
|
|||
break;
|
||||
}
|
||||
|
||||
refent->prev = pTempEntity->pvEngineData; // setup prevframe data
|
||||
refent->lerp = pTempEntity->pvEngineData; // setup lerpframe data
|
||||
|
||||
if( refent->prev == NULL )
|
||||
if( refent->lerp == NULL )
|
||||
{
|
||||
MsgDev( D_ERROR, "Rejected temp entity (model %s) -- no prevframe data\n", refent->model->name );
|
||||
MsgDev( D_ERROR, "Rejected temp entity (model %s) -- no lerpframe data\n", refent->model->name );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2680,8 +2680,8 @@ bool R_AddTeEntToScene( TEMPENTITY *pTempEntity, int ed_type, shader_t customSha
|
|||
|
||||
refent->rtype = RT_MODEL;
|
||||
|
||||
refent->prev->frame = refent->prev->curframe; // save oldframe
|
||||
refent->prev->curframe = pTempEntity->m_flFrame;
|
||||
refent->lerp->latched.frame = refent->lerp->curstate.frame; // save oldframe
|
||||
refent->lerp->curstate.frame = pTempEntity->m_flFrame;
|
||||
|
||||
// setup light origin
|
||||
if( refent->model ) VectorAverage( refent->model->mins, refent->model->maxs, center );
|
||||
|
|
|
@ -325,7 +325,7 @@ float R_GetSpriteFrameInterpolant( ref_entity_t *ent, mspriteframe_t **oldframe,
|
|||
int m_fDoInterp;
|
||||
|
||||
psprite = ent->model->extradata;
|
||||
frame = (int)ent->prev->curframe;
|
||||
frame = (int)ent->lerp->curstate.frame;
|
||||
lerpFrac = 1.0f;
|
||||
|
||||
// misc info
|
||||
|
@ -343,49 +343,49 @@ float R_GetSpriteFrameInterpolant( ref_entity_t *ent, mspriteframe_t **oldframe,
|
|||
{
|
||||
if( m_fDoInterp )
|
||||
{
|
||||
if( ent->prev->sequence >= psprite->numframes || psprite->frames[ent->prev->sequence].type != FRAME_SINGLE )
|
||||
if( ent->lerp->latched.sequence >= psprite->numframes || psprite->frames[ent->lerp->latched.sequence].type != FRAME_SINGLE )
|
||||
{
|
||||
// this can be happens when rendering switched between single and angled frames
|
||||
// or change model on replace delta-entity
|
||||
ent->prev->sequence = ent->prev->cursequence = frame;
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
ent->lerp->latched.sequence = ent->lerp->curstate.sequence = frame;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
lerpFrac = 1.0f;
|
||||
}
|
||||
|
||||
if( ent->prev->curanimtime < RI.refdef.time )
|
||||
if( ent->lerp->curstate.animtime < RI.refdef.time )
|
||||
{
|
||||
if( frame != ent->prev->cursequence )
|
||||
if( frame != ent->lerp->curstate.sequence )
|
||||
{
|
||||
ent->prev->sequence = ent->prev->cursequence;
|
||||
ent->prev->cursequence = frame;
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
ent->lerp->latched.sequence = ent->lerp->curstate.sequence;
|
||||
ent->lerp->curstate.sequence = frame;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
lerpFrac = 0.0f;
|
||||
}
|
||||
else lerpFrac = (RI.refdef.time - ent->prev->curanimtime) * ent->framerate;
|
||||
else lerpFrac = (RI.refdef.time - ent->lerp->curstate.animtime) * ent->framerate;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->prev->sequence = ent->prev->cursequence = frame;
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
ent->lerp->latched.sequence = ent->lerp->curstate.sequence = frame;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
lerpFrac = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->prev->sequence = ent->prev->cursequence = frame;
|
||||
ent->lerp->latched.sequence = ent->lerp->curstate.sequence = frame;
|
||||
lerpFrac = 1.0f;
|
||||
}
|
||||
|
||||
if( ent->prev->sequence >= psprite->numframes )
|
||||
if( ent->lerp->latched.sequence >= psprite->numframes )
|
||||
{
|
||||
// reset interpolation on change model
|
||||
ent->prev->sequence = ent->prev->cursequence = frame;
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
ent->lerp->latched.sequence = ent->lerp->curstate.sequence = frame;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
lerpFrac = 0.0f;
|
||||
}
|
||||
|
||||
// get the interpolated frames
|
||||
if( oldframe ) *oldframe = psprite->frames[ent->prev->sequence].frameptr;
|
||||
if( oldframe ) *oldframe = psprite->frames[ent->lerp->latched.sequence].frameptr;
|
||||
if( curframe ) *curframe = psprite->frames[frame].frameptr;
|
||||
}
|
||||
else if( psprite->frames[frame].type == FRAME_GROUP )
|
||||
|
@ -429,40 +429,40 @@ float R_GetSpriteFrameInterpolant( ref_entity_t *ent, mspriteframe_t **oldframe,
|
|||
|
||||
if( m_fDoInterp )
|
||||
{
|
||||
if( ent->prev->sequence >= psprite->numframes || psprite->frames[ent->prev->sequence].type != FRAME_ANGLED )
|
||||
if( ent->lerp->latched.sequence >= psprite->numframes || psprite->frames[ent->lerp->latched.sequence].type != FRAME_ANGLED )
|
||||
{
|
||||
// this can be happens when rendering switched between single and angled frames
|
||||
// or change model on replace delta-entity
|
||||
ent->prev->sequence = ent->prev->cursequence = frame;
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
ent->lerp->latched.sequence = ent->lerp->curstate.sequence = frame;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
lerpFrac = 1.0f;
|
||||
}
|
||||
|
||||
if( ent->prev->curanimtime < RI.refdef.time )
|
||||
if( ent->lerp->curstate.animtime < RI.refdef.time )
|
||||
{
|
||||
if( frame != ent->prev->cursequence )
|
||||
if( frame != ent->lerp->curstate.sequence )
|
||||
{
|
||||
ent->prev->sequence = ent->prev->cursequence;
|
||||
ent->prev->cursequence = frame;
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
ent->lerp->latched.sequence = ent->lerp->curstate.sequence;
|
||||
ent->lerp->curstate.sequence = frame;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
lerpFrac = 0.0f;
|
||||
}
|
||||
else lerpFrac = (RI.refdef.time - ent->prev->curanimtime) * ent->framerate;
|
||||
else lerpFrac = (RI.refdef.time - ent->lerp->curstate.animtime) * ent->framerate;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->prev->sequence = ent->prev->cursequence = frame;
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
ent->lerp->latched.sequence = ent->lerp->curstate.sequence = frame;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
lerpFrac = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->prev->sequence = ent->prev->cursequence = frame;
|
||||
ent->lerp->latched.sequence = ent->lerp->curstate.sequence = frame;
|
||||
lerpFrac = 1.0f;
|
||||
}
|
||||
|
||||
pspritegroup = (mspritegroup_t *)psprite->frames[ent->prev->sequence].frameptr;
|
||||
pspritegroup = (mspritegroup_t *)psprite->frames[ent->lerp->latched.sequence].frameptr;
|
||||
if( oldframe ) *oldframe = pspritegroup->frames[angleframe];
|
||||
|
||||
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
|
||||
|
@ -566,7 +566,7 @@ void R_DrawSpriteModel( const meshbuffer_t *mb )
|
|||
case kRenderNormal:
|
||||
case kRenderTransColor:
|
||||
case kRenderTransAlpha:
|
||||
frame = oldframe = R_GetSpriteFrame( e->model, e->prev->curframe, e->angles[YAW] );
|
||||
frame = oldframe = R_GetSpriteFrame( e->model, e->lerp->curstate.frame, e->angles[YAW] );
|
||||
break;
|
||||
case kRenderTransTexture:
|
||||
case kRenderTransAdd:
|
||||
|
|
|
@ -62,7 +62,7 @@ typedef struct studioverts_s
|
|||
|
||||
typedef struct studiovars_s
|
||||
{
|
||||
studioframe_t *prev; // duplcate e->prev for consistency
|
||||
lerpframe_t *lerp; // duplicate e->lerp pointer for consistency
|
||||
|
||||
// cached values, valid only for CURRENT frame
|
||||
char bonenames[MAXSTUDIOBONES][32];// used for attached entities
|
||||
|
@ -119,50 +119,50 @@ void R_StudioAllocTentExtradata( TEMPENTITY *in, ref_entity_t *e )
|
|||
if( !e->mempool ) e->mempool = Mem_AllocPool( va( "TempEntity Pool %i", e - r_entities ));
|
||||
if( !e->extradata ) e->extradata = (void *)Mem_Alloc( e->mempool, sizeof( studiovars_t ));
|
||||
studio = (studiovars_t *)e->extradata;
|
||||
studio->prev = e->prev;
|
||||
studio->lerp = e->lerp;
|
||||
|
||||
// any stuidio model MUST have previous data for lerping
|
||||
Com_Assert( studio->prev == NULL );
|
||||
// any stuidio model MUST have lerpframe data for lerping
|
||||
Com_Assert( studio->lerp == NULL );
|
||||
|
||||
// copy controllers
|
||||
for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ )
|
||||
{
|
||||
studio->prev->controller[i] = studio->prev->curcontroller[i];
|
||||
studio->prev->curcontroller[i] = 0x7F; // tempents doesn't have bonecontrollers
|
||||
studio->lerp->latched.controller[i] = studio->lerp->curstate.controller[i];
|
||||
studio->lerp->curstate.controller[i] = 0x7F; // tempents doesn't have bonecontrollers
|
||||
}
|
||||
|
||||
// copy blends
|
||||
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
|
||||
{
|
||||
studio->prev->blending[i] = studio->prev->curblending[i];
|
||||
studio->prev->curblending[i] = 0x7F; // tempents doesn't have blendings
|
||||
studio->lerp->latched.blending[i] = studio->lerp->curstate.blending[i];
|
||||
studio->lerp->curstate.blending[i] = 0x7F; // tempents doesn't have blendings
|
||||
}
|
||||
|
||||
// sequence has changed, hold the previous sequence info
|
||||
if( in->m_iSequence != e->prev->cursequence )
|
||||
if( in->m_iSequence != studio->lerp->curstate.sequence )
|
||||
{
|
||||
studio->prev->sequencetime = e->prev->animtime + 0.01f;
|
||||
studio->prev->sequence = e->prev->cursequence;
|
||||
studio->lerp->latched.sequencetime = e->lerp->latched.animtime + 0.01f;
|
||||
e->lerp->latched.sequence = studio->lerp->curstate.sequence;
|
||||
|
||||
// save current blendings
|
||||
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
|
||||
studio->prev->blending[i] = studio->prev->curblending[i];
|
||||
studio->lerp->latched.blending[i] = studio->lerp->curstate.blending[i];
|
||||
}
|
||||
|
||||
if( in->flags & FTENT_SPRANIMATE )
|
||||
{
|
||||
if( in->m_flFrame == -1 )
|
||||
{
|
||||
in->m_flFrame = e->prev->curframe = 0;
|
||||
e->prev->cursequence = in->m_iSequence;
|
||||
in->m_flFrame = e->lerp->curstate.frame = 0;
|
||||
studio->lerp->curstate.sequence = in->m_iSequence;
|
||||
R_StudioResetSequenceInfo( e );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !studio->prev->m_fSequenceFinished )
|
||||
if( !studio->lerp->m_fSequenceFinished )
|
||||
R_StudioFrameAdvance( e, 0 );
|
||||
|
||||
if( studio->prev->m_fSequenceFinished )
|
||||
if( studio->lerp->m_fSequenceFinished )
|
||||
{
|
||||
if( in->flags & FTENT_SPRANIMATELOOP )
|
||||
in->m_flFrame = -1;
|
||||
|
@ -171,15 +171,21 @@ void R_StudioAllocTentExtradata( TEMPENTITY *in, ref_entity_t *e )
|
|||
else
|
||||
{
|
||||
// copy current frame back to let user grab it on a client-side
|
||||
in->m_flFrame = e->prev->curframe;
|
||||
in->m_flFrame = e->lerp->curstate.frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e->prev->cursequence = in->m_iSequence;
|
||||
e->prev->animtime = e->prev->curanimtime; // must be update each frame!
|
||||
e->prev->curanimtime = in->m_flFrameMax; // HACKHACK: used m_flFrameMax as animtime
|
||||
studio->lerp->curstate.sequence = in->m_iSequence;
|
||||
e->lerp->latched.animtime = e->lerp->curstate.animtime; // must be update each frame!
|
||||
e->lerp->curstate.animtime = in->m_flFrameMax; // HACKHACK: used m_flFrameMax as animtime
|
||||
|
||||
// push position and angles
|
||||
VectorCopy( e->lerp->curstate.origin, e->lerp->latched.origin );
|
||||
VectorCopy( in->origin, e->lerp->curstate.origin );
|
||||
VectorCopy( e->lerp->curstate.angles, e->lerp->latched.angles );
|
||||
VectorCopy( in->angles, e->lerp->curstate.angles );
|
||||
}
|
||||
|
||||
if( studio->numbones != numbones )
|
||||
|
@ -221,67 +227,81 @@ void R_StudioAllocExtradata( edict_t *in, ref_entity_t *e )
|
|||
if( !e->mempool ) e->mempool = Mem_AllocPool( va( "Entity Pool %i", e - r_entities ));
|
||||
if( !e->extradata ) e->extradata = (void *)Mem_Alloc( e->mempool, sizeof( studiovars_t ));
|
||||
studio = (studiovars_t *)e->extradata;
|
||||
studio->prev = e->prev;
|
||||
studio->lerp = e->lerp;
|
||||
|
||||
// any stuidio model MUST have previous data for lerping
|
||||
Com_Assert( studio->prev == NULL );
|
||||
Com_Assert( studio->lerp == NULL );
|
||||
|
||||
// copy controllers
|
||||
for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ )
|
||||
{
|
||||
studio->prev->controller[i] = studio->prev->curcontroller[i];
|
||||
studio->prev->curcontroller[i] = in->v.controller[i];
|
||||
studio->lerp->latched.controller[i] = studio->lerp->curstate.controller[i];
|
||||
studio->lerp->curstate.controller[i] = in->v.controller[i];
|
||||
}
|
||||
|
||||
// copy blends
|
||||
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
|
||||
{
|
||||
studio->prev->blending[i] = studio->prev->curblending[i];
|
||||
studio->prev->curblending[i] = in->v.blending[i];
|
||||
studio->lerp->latched.blending[i] = studio->lerp->curstate.blending[i];
|
||||
studio->lerp->curstate.blending[i] = in->v.blending[i];
|
||||
}
|
||||
|
||||
// sequence has changed, hold the previous sequence info
|
||||
if( in->v.sequence != e->prev->cursequence )
|
||||
if( in->v.sequence != studio->lerp->curstate.sequence )
|
||||
{
|
||||
studio->prev->sequencetime = e->prev->animtime + 0.01f;
|
||||
studio->prev->sequence = e->prev->cursequence;
|
||||
studio->lerp->latched.sequencetime = e->lerp->latched.animtime + 0.01f;
|
||||
e->lerp->latched.sequence = studio->lerp->curstate.sequence;
|
||||
e->lerp->curstate.sequence = in->v.sequence;
|
||||
|
||||
// save current blendings
|
||||
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
|
||||
studio->prev->blending[i] = studio->prev->curblending[i];
|
||||
studio->lerp->latched.blending[i] = studio->lerp->curstate.blending[i];
|
||||
}
|
||||
|
||||
if( e->flags & EF_ANIMATE )
|
||||
{
|
||||
if( in->v.frame == -1 )
|
||||
{
|
||||
in->v.frame = e->prev->curframe = 0;
|
||||
e->prev->cursequence = in->v.sequence;
|
||||
in->v.frame = e->lerp->curstate.frame = 0;
|
||||
studio->lerp->curstate.sequence = in->v.sequence;
|
||||
R_StudioResetSequenceInfo( e );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !studio->prev->m_fSequenceFinished )
|
||||
if( !studio->lerp->m_fSequenceFinished )
|
||||
R_StudioFrameAdvance( e, 0 );
|
||||
|
||||
if( studio->prev->m_fSequenceFinished )
|
||||
if( studio->lerp->m_fSequenceFinished )
|
||||
{
|
||||
if( studio->prev->m_fSequenceLoops )
|
||||
if( studio->lerp->m_fSequenceLoops )
|
||||
in->v.frame = -1;
|
||||
// hold at last frame
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy current frame back to let user grab it on a client-side
|
||||
in->v.frame = e->prev->curframe;
|
||||
in->v.frame = e->lerp->curstate.frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e->prev->cursequence = in->v.sequence;
|
||||
e->prev->animtime = e->prev->curanimtime; // must be update each frame!
|
||||
e->prev->curanimtime = in->v.animtime;
|
||||
if( in->v.animtime != e->lerp->curstate.animtime )
|
||||
{
|
||||
// client got new packet, shuffle animtimes
|
||||
e->lerp->latched.animtime = e->lerp->curstate.animtime;
|
||||
e->lerp->curstate.animtime = in->v.animtime;
|
||||
}
|
||||
|
||||
if( !VectorCompare( in->v.origin, e->lerp->curstate.origin ))
|
||||
{
|
||||
// push position and angles
|
||||
VectorCopy( e->lerp->curstate.origin, e->lerp->latched.origin );
|
||||
VectorCopy( in->v.origin, e->lerp->curstate.origin );
|
||||
}
|
||||
|
||||
VectorCopy( e->lerp->curstate.angles, e->lerp->latched.angles );
|
||||
VectorCopy( in->v.angles, e->lerp->curstate.angles );
|
||||
}
|
||||
|
||||
if( studio->numbones != numbones )
|
||||
|
@ -390,7 +410,7 @@ void R_StudioModelBBox( ref_entity_t *e, vec3_t mins, vec3_t maxs )
|
|||
|
||||
hdr = ((mstudiomodel_t *)e->model->extradata)->phdr;
|
||||
if( !hdr ) return;
|
||||
R_StudioExtractBbox( hdr, e->prev->cursequence, mins, maxs );
|
||||
R_StudioExtractBbox( hdr, e->lerp->curstate.sequence, mins, maxs );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -637,10 +657,10 @@ float R_StudioSequenceDuration( dstudiohdr_t *hdr, ref_entity_t *ent )
|
|||
{
|
||||
dstudioseqdesc_t *pseqdesc;
|
||||
|
||||
if( !hdr || ent->prev->cursequence >= hdr->numseq )
|
||||
if( !hdr || ent->lerp->curstate.sequence >= hdr->numseq )
|
||||
return 0.0f;
|
||||
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->prev->cursequence;
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->lerp->curstate.sequence;
|
||||
return pseqdesc->numframes / pseqdesc->fps;
|
||||
}
|
||||
|
||||
|
@ -648,10 +668,10 @@ int R_StudioGetSequenceFlags( dstudiohdr_t *hdr, ref_entity_t *ent )
|
|||
{
|
||||
dstudioseqdesc_t *pseqdesc;
|
||||
|
||||
if( !hdr || ent->prev->cursequence >= hdr->numseq )
|
||||
if( !hdr || ent->lerp->curstate.sequence >= hdr->numseq )
|
||||
return 0;
|
||||
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + (int)ent->prev->cursequence;
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + (int)ent->lerp->curstate.sequence;
|
||||
return pseqdesc->flags;
|
||||
}
|
||||
|
||||
|
@ -659,14 +679,14 @@ void R_StuioGetSequenceInfo( dstudiohdr_t *hdr, ref_entity_t *ent, float *pflFra
|
|||
{
|
||||
dstudioseqdesc_t *pseqdesc;
|
||||
|
||||
if( !hdr || ent->prev->cursequence >= hdr->numseq )
|
||||
if( !hdr || ent->lerp->curstate.sequence >= hdr->numseq )
|
||||
{
|
||||
*pflFrameRate = 0.0;
|
||||
*pflGroundSpeed = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->prev->cursequence;
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->lerp->curstate.sequence;
|
||||
|
||||
if( pseqdesc->numframes > 1 )
|
||||
{
|
||||
|
@ -690,24 +710,26 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float flInterval )
|
|||
|
||||
if( flInterval == 0.0 )
|
||||
{
|
||||
flInterval = ( RI.refdef.time - ent->prev->curanimtime );
|
||||
flInterval = ( RI.refdef.time - ent->lerp->curstate.animtime );
|
||||
if( flInterval <= 0.001 )
|
||||
{
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
if( !ent->prev->curanimtime ) flInterval = 0.0;
|
||||
|
||||
ent->prev->curframe += flInterval * pstudio->prev->m_flFrameRate * ent->framerate;
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
if( !ent->lerp->curstate.animtime )
|
||||
flInterval = 0.0;
|
||||
|
||||
if( ent->prev->curframe < 0.0 || ent->prev->curframe >= 256.0 )
|
||||
ent->lerp->curstate.frame += flInterval * pstudio->lerp->m_flFrameRate * ent->framerate;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
|
||||
if( ent->lerp->curstate.frame < 0.0 || ent->lerp->curstate.frame >= 256.0 )
|
||||
{
|
||||
if( pstudio->prev->m_fSequenceLoops )
|
||||
ent->prev->curframe -= (int)(ent->prev->curframe / 256.0) * 256.0;
|
||||
else ent->prev->curframe = (ent->prev->curframe < 0.0) ? 0 : 255;
|
||||
pstudio->prev->m_fSequenceFinished = true;
|
||||
if( pstudio->lerp->m_fSequenceLoops )
|
||||
ent->lerp->curstate.frame -= (int)(ent->lerp->curstate.frame / 256.0) * 256.0;
|
||||
else ent->lerp->curstate.frame = (ent->lerp->curstate.frame < 0.0) ? 0 : 255;
|
||||
pstudio->lerp->m_fSequenceFinished = true;
|
||||
}
|
||||
return flInterval;
|
||||
}
|
||||
|
@ -717,18 +739,18 @@ void R_StudioResetSequenceInfo( ref_entity_t *ent )
|
|||
dstudiohdr_t *hdr;
|
||||
studiovars_t *pstudio = (studiovars_t *)ent->extradata;
|
||||
|
||||
if( !ent || !ent->prev || !ent->extradata || !ent->model || !ent->model->extradata )
|
||||
if( !ent || !ent->lerp || !ent->extradata || !ent->model || !ent->model->extradata )
|
||||
return;
|
||||
|
||||
hdr = ((mstudiomodel_t *)ent->model->extradata)->phdr;
|
||||
if( !hdr ) return;
|
||||
|
||||
R_StuioGetSequenceInfo( hdr, ent, &pstudio->prev->m_flFrameRate, &pstudio->prev->m_flGroundSpeed );
|
||||
pstudio->prev->m_fSequenceLoops = ((R_StudioGetSequenceFlags( hdr, ent ) & STUDIO_LOOPING) != 0 );
|
||||
ent->prev->animtime = ent->prev->curanimtime;
|
||||
ent->prev->curanimtime = RI.refdef.time;
|
||||
pstudio->prev->m_fSequenceFinished = false;
|
||||
pstudio->prev->m_flLastEventCheck = RI.refdef.time;
|
||||
R_StuioGetSequenceInfo( hdr, ent, &pstudio->lerp->m_flFrameRate, &pstudio->lerp->m_flGroundSpeed );
|
||||
pstudio->lerp->m_fSequenceLoops = ((R_StudioGetSequenceFlags( hdr, ent ) & STUDIO_LOOPING) != 0 );
|
||||
ent->lerp->latched.animtime = ent->lerp->curstate.animtime;
|
||||
ent->lerp->curstate.animtime = RI.refdef.time;
|
||||
pstudio->lerp->m_fSequenceFinished = false;
|
||||
pstudio->lerp->m_flLastEventCheck = RI.refdef.time;
|
||||
}
|
||||
|
||||
int R_StudioGetEvent( ref_entity_t *e, dstudioevent_t *pcurrent, float flStart, float flEnd, int index )
|
||||
|
@ -737,7 +759,7 @@ int R_StudioGetEvent( ref_entity_t *e, dstudioevent_t *pcurrent, float flStart,
|
|||
dstudioevent_t *pevent;
|
||||
int events = 0;
|
||||
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->prev->cursequence;
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->lerp->curstate.sequence;
|
||||
pevent = (dstudioevent_t *)((byte *)m_pStudioHeader + pseqdesc->eventindex);
|
||||
|
||||
if( pseqdesc->numevents == 0 || index > pseqdesc->numevents )
|
||||
|
@ -819,7 +841,7 @@ void R_StudioCalcBoneAdj( float dadt, float *adj, const byte *pcontroller1, cons
|
|||
value = bound( 0.0f, value, 1.0f );
|
||||
value = (1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end;
|
||||
}
|
||||
// Msg( "%d %d %f : %f\n", RI.currententity->curstate.controller[j], RI.currententity->prev->prevcontroller[j], value, dadt );
|
||||
// Msg( "%d %d %f : %f\n", RI.currententity->lerp->curstate.controller[j], RI.currententity->lerp->latched.controller[j], value, dadt );
|
||||
}
|
||||
|
||||
switch( pbonecontroller[j].type & STUDIO_TYPES )
|
||||
|
@ -943,7 +965,7 @@ void R_StudioCalcBonePosition( int frame, float s, dstudiobone_t *pbone, dstudio
|
|||
{
|
||||
panimvalue = (dstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
|
||||
|
||||
//if (j == 0) Msg("%d %d:%d %f\n", frame, panimvalue->num.valid, panimvalue->num.total, s );
|
||||
//if( j == 0 ) Msg( "%d %d:%d %f\n", frame, panimvalue->num.valid, panimvalue->num.total, s );
|
||||
k = frame;
|
||||
|
||||
// debug
|
||||
|
@ -1075,9 +1097,9 @@ dstudioanim_t *R_StudioGetAnim( ref_model_t *m_pRefModel, dstudioseqdesc_t *pseq
|
|||
com.snprintf( filepath, sizeof( filepath ), "%s/%s%i%i.mdl", modelpath, modelname, pseqdesc->seqgroup / 10, pseqdesc->seqgroup % 10 );
|
||||
|
||||
buf = FS_LoadFile( filepath, &filesize );
|
||||
if( !buf || !filesize ) Host_Error( "R_StudioGetAnim: can't load %s\n", modelpath );
|
||||
if( !buf || !filesize ) Host_Error( "R_StudioGetAnim: can't load %s\n", filepath );
|
||||
if( IDSEQGRPHEADER != LittleLong(*(uint *)buf ))
|
||||
Host_Error( "R_StudioGetAnim: %s is corrpted\n", modelpath );
|
||||
Host_Error( "R_StudioGetAnim: %s is corrupted\n", filepath );
|
||||
|
||||
MsgDev( D_LOAD, "R_StudioGetAnim: %s\n", filepath );
|
||||
|
||||
|
@ -1135,6 +1157,7 @@ StudioSetUpTransform
|
|||
void R_StudioSetUpTransform( ref_entity_t *e, bool trivial_accept )
|
||||
{
|
||||
vec3_t angles, origin;
|
||||
int i;
|
||||
|
||||
if( trivial_accept )
|
||||
{
|
||||
|
@ -1155,6 +1178,65 @@ void R_StudioSetUpTransform( ref_entity_t *e, bool trivial_accept )
|
|||
VectorCopy( e->origin, origin );
|
||||
VectorCopy( e->angles, angles );
|
||||
|
||||
if( e->movetype == MOVETYPE_STEP )
|
||||
{
|
||||
float d, f = 0.0f;
|
||||
|
||||
// don't do it if the goalstarttime hasn't updated in a while.
|
||||
// NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit
|
||||
// was increased to 1.0 s., which is 2x the max lag we are accounting for.
|
||||
|
||||
if(( RI.refdef.time < e->lerp->curstate.animtime + 1.0f ) && ( e->lerp->curstate.animtime != e->lerp->latched.animtime ))
|
||||
{
|
||||
f = ( RI.refdef.time - e->lerp->curstate.animtime ) / ( e->lerp->curstate.animtime - e->lerp->latched.animtime );
|
||||
//Msg( "%4.2f %.2f %.2f\n", f, e->lerp->curstate.animtime, RI.refdef.time );
|
||||
}
|
||||
else Msg( "skip f\n" );
|
||||
|
||||
if( m_fDoInterp )
|
||||
{
|
||||
// ugly hack to interpolate angle, position.
|
||||
// current is reached 0.1 seconds after being set
|
||||
f = f - 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = 0.0f;
|
||||
}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
origin[i] += ( e->lerp->curstate.origin[i] - e->lerp->latched.origin[i] ) * f;
|
||||
}
|
||||
|
||||
// NOTE: Because multiplayer lag can be relatively large, we don't want to cap f at 1.5 anymore.
|
||||
// if( f > -1.0 && f < 1.5 ) {}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
float ang1, ang2;
|
||||
|
||||
ang1 = e->angles[i];
|
||||
ang2 = e->lerp->latched.angles[i];
|
||||
|
||||
d = ang1 - ang2;
|
||||
if( d > 180 )
|
||||
{
|
||||
d -= 360;
|
||||
}
|
||||
else if( d < -180 )
|
||||
{
|
||||
d += 360;
|
||||
}
|
||||
angles[i] += d * f;
|
||||
}
|
||||
//Msg( "%.3f \n", f );
|
||||
}
|
||||
else if( e->movetype != MOVETYPE_NONE )
|
||||
{
|
||||
VectorCopy( e->angles, angles );
|
||||
}
|
||||
|
||||
if( e->ent_type == ED_CLIENT ) angles[PITCH] = 0; // don't rotate player model, only aim
|
||||
if( e->ent_type == ED_VIEWMODEL ) angles[PITCH] = -angles[PITCH]; // stupid Half-Life bug
|
||||
|
||||
|
@ -1180,12 +1262,12 @@ StudioEstimateInterpolant
|
|||
*/
|
||||
float R_StudioEstimateInterpolant( void )
|
||||
{
|
||||
float dadt = 1.0;
|
||||
float dadt = 1.0f;
|
||||
|
||||
if( m_fDoInterp && ( RI.currententity->prev->curanimtime >= RI.currententity->prev->animtime + 0.01 ))
|
||||
if( m_fDoInterp && ( RI.currententity->lerp->curstate.animtime >= RI.currententity->lerp->latched.animtime + 0.01f ))
|
||||
{
|
||||
dadt = (RI.refdef.time - RI.currententity->prev->curanimtime) / 0.1;
|
||||
if( dadt > 2.0 ) dadt = 2.0;
|
||||
dadt = ( RI.refdef.time - RI.currententity->lerp->curstate.animtime ) / 0.1f;
|
||||
if( dadt > 2.0f ) dadt = 2.0f;
|
||||
}
|
||||
return dadt;
|
||||
}
|
||||
|
@ -1222,9 +1304,9 @@ void R_StudioCalcRotations( float pos[][3], vec4_t *q, dstudioseqdesc_t *pseqdes
|
|||
pstudio = RI.currententity->extradata;
|
||||
Com_Assert( pstudio == NULL );
|
||||
|
||||
// Msg("%d %.4f %.4f %.4f %.4f %d\n", RI.currententity->curstate.sequence, m_clTime, RI.currententity->prev->curanimtime, RI.currententity->prev->curframe, f, frame );
|
||||
// Msg( "%d %.4f %.4f %.4f %.4f %d\n", RI.currententity->lerp->curstate.sequence, RI.refdef.time, RI.currententity->lerp->curstate.animtime, RI.currententity->lerp->curstate.frame, f, frame );
|
||||
// Msg( "%f %f %f\n", RI.currententity->angles[ROLL], RI.currententity->angles[PITCH], RI.currententity->angles[YAW] );
|
||||
// Msg("frame %d %d\n", frame1, frame2 );
|
||||
// Msg( "frame %d %d\n", frame1, frame2 );
|
||||
|
||||
dadt = R_StudioEstimateInterpolant();
|
||||
s = (f - frame);
|
||||
|
@ -1233,13 +1315,13 @@ void R_StudioCalcRotations( float pos[][3], vec4_t *q, dstudioseqdesc_t *pseqdes
|
|||
pbone = (dstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex);
|
||||
mouthopen = ri.GetMouthOpen( RI.currententity->index );
|
||||
|
||||
R_StudioCalcBoneAdj( dadt, adj, pstudio->prev->curcontroller, pstudio->prev->controller, mouthopen );
|
||||
R_StudioCalcBoneAdj( dadt, adj, pstudio->lerp->curstate.controller, pstudio->lerp->latched.controller, mouthopen );
|
||||
|
||||
for (i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++)
|
||||
{
|
||||
R_StudioCalcBoneQuaterion( frame, s, pbone, panim, adj, q[i] );
|
||||
R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] );
|
||||
// if( 0 && i == 0 ) Msg("%d %d %d %d\n", RI.currententity->prev->cursequence, frame, j, k );
|
||||
// if( 0 && i == 0 ) Msg( "%d %d %d %d\n", RI.currententity->lerp->curstate.sequence, frame, j, k );
|
||||
}
|
||||
|
||||
if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
|
||||
|
@ -1265,13 +1347,13 @@ float R_StudioEstimateFrame( dstudioseqdesc_t *pseqdesc )
|
|||
|
||||
if( m_fDoInterp )
|
||||
{
|
||||
if( RI.refdef.time < RI.currententity->prev->curanimtime ) dfdt = 0;
|
||||
else dfdt = (RI.refdef.time - RI.currententity->prev->curanimtime) * RI.currententity->framerate * pseqdesc->fps;
|
||||
if( RI.refdef.time < RI.currententity->lerp->curstate.animtime ) dfdt = 0;
|
||||
else dfdt = (RI.refdef.time - RI.currententity->lerp->curstate.animtime) * RI.currententity->framerate * pseqdesc->fps;
|
||||
}
|
||||
else dfdt = 0;
|
||||
|
||||
if( pseqdesc->numframes <= 1 ) f = 0;
|
||||
else f = (RI.currententity->prev->curframe * (pseqdesc->numframes - 1)) / 256.0;
|
||||
else f = (RI.currententity->lerp->curstate.frame * (pseqdesc->numframes - 1)) / 256.0;
|
||||
|
||||
f += dfdt;
|
||||
|
||||
|
@ -1321,12 +1403,12 @@ float R_StudioSetupBones( ref_entity_t *e )
|
|||
return 0.0f;
|
||||
|
||||
cl_entity = ri.GetClientEdict( e->index );
|
||||
if( e->prev->cursequence >= m_pStudioHeader->numseq ) e->prev->cursequence = 0;
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->prev->cursequence;
|
||||
if( e->lerp->curstate.sequence >= m_pStudioHeader->numseq ) e->lerp->curstate.sequence = 0;
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->lerp->curstate.sequence;
|
||||
|
||||
f = R_StudioEstimateFrame( pseqdesc );
|
||||
|
||||
// if( e->prev->frame > f ) Msg( "%f %f\n", e->prev->frame, f );
|
||||
// if( e->lerp->curstate.frame > f ) Msg( "%f %f\n", e->lerp->curstate.frame, f );
|
||||
|
||||
pstudio = RI.currententity->extradata;
|
||||
Com_Assert( pstudio == NULL );
|
||||
|
@ -1343,7 +1425,7 @@ float R_StudioSetupBones( ref_entity_t *e )
|
|||
R_StudioCalcRotations( pos2, q2, pseqdesc, panim, f );
|
||||
|
||||
dadt = R_StudioEstimateInterpolant();
|
||||
s = (pstudio->prev->curblending[0] * dadt + pstudio->prev->blending[0] * (1.0 - dadt)) / 255.0;
|
||||
s = (pstudio->lerp->curstate.blending[0] * dadt + pstudio->lerp->latched.blending[0] * (1.0 - dadt)) / 255.0;
|
||||
|
||||
R_StudioSlerpBones( q, pos, q2, pos2, s );
|
||||
|
||||
|
@ -1355,57 +1437,57 @@ float R_StudioSetupBones( ref_entity_t *e )
|
|||
panim += m_pStudioHeader->numbones;
|
||||
R_StudioCalcRotations( pos4, q4, pseqdesc, panim, f );
|
||||
|
||||
s = (pstudio->prev->curblending[0] * dadt + pstudio->prev->blending[0] * (1.0 - dadt)) / 255.0;
|
||||
s = (pstudio->lerp->curstate.blending[0] * dadt + pstudio->lerp->latched.blending[0] * (1.0 - dadt)) / 255.0;
|
||||
R_StudioSlerpBones( q3, pos3, q4, pos4, s );
|
||||
|
||||
s = (pstudio->prev->curblending[1] * dadt + pstudio->prev->blending[1] * (1.0 - dadt)) / 255.0;
|
||||
s = (pstudio->lerp->curstate.blending[1] * dadt + pstudio->lerp->latched.blending[1] * (1.0 - dadt)) / 255.0;
|
||||
R_StudioSlerpBones( q, pos, q3, pos3, s );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_fDoInterp && pstudio->prev->sequencetime && ( pstudio->prev->sequencetime + 0.2 > RI.refdef.time) && ( pstudio->prev->sequence < m_pStudioHeader->numseq ))
|
||||
if( m_fDoInterp && pstudio->lerp->latched.sequencetime && ( pstudio->lerp->latched.sequencetime + 0.2 > RI.refdef.time) && ( pstudio->lerp->latched.sequence < m_pStudioHeader->numseq ))
|
||||
{
|
||||
// blend from last sequence
|
||||
static float pos1b[MAXSTUDIOBONES][3];
|
||||
static vec4_t q1b[MAXSTUDIOBONES];
|
||||
float s;
|
||||
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + pstudio->prev->sequence;
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + pstudio->lerp->latched.sequence;
|
||||
panim = R_StudioGetAnim( RI.currentmodel, pseqdesc );
|
||||
// clip prevframe
|
||||
R_StudioCalcRotations( pos1b, q1b, pseqdesc, panim, pstudio->prev->frame );
|
||||
R_StudioCalcRotations( pos1b, q1b, pseqdesc, panim, pstudio->lerp->latched.frame );
|
||||
|
||||
if( pseqdesc->numblends > 1 )
|
||||
{
|
||||
panim += m_pStudioHeader->numbones;
|
||||
R_StudioCalcRotations( pos2, q2, pseqdesc, panim, pstudio->prev->frame );
|
||||
R_StudioCalcRotations( pos2, q2, pseqdesc, panim, pstudio->lerp->latched.frame );
|
||||
|
||||
s = (pstudio->prev->blending[0]) / 255.0;
|
||||
s = (pstudio->lerp->latched.blending[0]) / 255.0;
|
||||
R_StudioSlerpBones( q1b, pos1b, q2, pos2, s );
|
||||
|
||||
if( pseqdesc->numblends == 4 )
|
||||
{
|
||||
panim += m_pStudioHeader->numbones;
|
||||
R_StudioCalcRotations( pos3, q3, pseqdesc, panim, pstudio->prev->frame );
|
||||
R_StudioCalcRotations( pos3, q3, pseqdesc, panim, pstudio->lerp->latched.frame );
|
||||
|
||||
panim += m_pStudioHeader->numbones;
|
||||
R_StudioCalcRotations( pos4, q4, pseqdesc, panim, pstudio->prev->frame );
|
||||
R_StudioCalcRotations( pos4, q4, pseqdesc, panim, pstudio->lerp->latched.frame );
|
||||
|
||||
s = (pstudio->prev->blending[0]) / 255.0;
|
||||
s = (pstudio->lerp->latched.blending[0]) / 255.0;
|
||||
R_StudioSlerpBones( q3, pos3, q4, pos4, s );
|
||||
|
||||
s = (pstudio->prev->blending[1]) / 255.0;
|
||||
s = (pstudio->lerp->latched.blending[1]) / 255.0;
|
||||
R_StudioSlerpBones( q1b, pos1b, q3, pos3, s );
|
||||
}
|
||||
}
|
||||
|
||||
s = 1.0 - (RI.refdef.time - pstudio->prev->sequencetime) / 0.2;
|
||||
s = 1.0 - (RI.refdef.time - pstudio->lerp->latched.sequencetime) / 0.2;
|
||||
R_StudioSlerpBones( q, pos, q1b, pos1b, s );
|
||||
}
|
||||
else
|
||||
{
|
||||
// MsgDev( D_INFO, "prevframe = %4.2f\n", f );
|
||||
pstudio->prev->frame = f;
|
||||
// Msg( "prevframe = %4.2f\n", f );
|
||||
pstudio->lerp->latched.frame = f;
|
||||
}
|
||||
|
||||
pbones = (dstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex);
|
||||
|
@ -1419,7 +1501,7 @@ float R_StudioSetupBones( ref_entity_t *e )
|
|||
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->gaitsequence;
|
||||
|
||||
panim = R_StudioGetAnim( RI.currentmodel, pseqdesc );
|
||||
R_StudioCalcRotations( pos2, q2, pseqdesc, panim, pstudio->prev->gaitframe );
|
||||
R_StudioCalcRotations( pos2, q2, pseqdesc, panim, pstudio->lerp->gaitframe );
|
||||
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++ )
|
||||
{
|
||||
|
@ -1471,7 +1553,7 @@ float R_StudioMergeBones( ref_entity_t *e, ref_model_t *m_pSubModel )
|
|||
{
|
||||
int i, j;
|
||||
double f;
|
||||
int sequence = e->prev->cursequence;
|
||||
int sequence = e->lerp->curstate.sequence;
|
||||
dstudiobone_t *pbones;
|
||||
dstudioseqdesc_t *pseqdesc;
|
||||
dstudioanim_t *panim;
|
||||
|
@ -1497,7 +1579,7 @@ float R_StudioMergeBones( ref_entity_t *e, ref_model_t *m_pSubModel )
|
|||
|
||||
f = R_StudioEstimateFrame( pseqdesc );
|
||||
|
||||
// if( e->prev->frame > f ) Msg("%f %f\n", e->prev->frame, f );
|
||||
// if( e->lerp->curstate.frame > f ) Msg( "%f %f\n", e->prev->frame, f );
|
||||
|
||||
panim = R_StudioGetAnim( m_pSubModel, pseqdesc );
|
||||
R_StudioCalcRotations( pos, q, pseqdesc, panim, f );
|
||||
|
@ -1588,7 +1670,7 @@ bool R_StudioComputeBBox( vec3_t bbox[8] )
|
|||
vec3_t vectors[3];
|
||||
ref_entity_t *e = RI.currententity;
|
||||
vec3_t tmp, angles;
|
||||
int i, seq = RI.currententity->prev->cursequence;
|
||||
int i, seq = RI.currententity->lerp->curstate.sequence;
|
||||
|
||||
if(!R_ExtractBbox( seq, studio_mins, studio_maxs ))
|
||||
return false;
|
||||
|
@ -2035,8 +2117,8 @@ void R_StudioEstimateGait( ref_entity_t *e, edict_t *pplayer )
|
|||
// VectorAdd( pplayer->v.velocity, pplayer->v.prediction_error, est_velocity );
|
||||
if( m_fGaitEstimation )
|
||||
{
|
||||
VectorSubtract( e->origin, pstudio->prev->gaitorigin, est_velocity );
|
||||
VectorCopy( e->origin, pstudio->prev->gaitorigin );
|
||||
VectorSubtract( e->origin, pstudio->lerp->gaitorigin, est_velocity );
|
||||
VectorCopy( e->origin, pstudio->lerp->gaitorigin );
|
||||
|
||||
m_flGaitMovement = VectorLength( est_velocity );
|
||||
if( dt <= 0 || m_flGaitMovement / dt < 5 )
|
||||
|
@ -2054,7 +2136,7 @@ void R_StudioEstimateGait( ref_entity_t *e, edict_t *pplayer )
|
|||
|
||||
if( est_velocity[1] == 0 && est_velocity[0] == 0 )
|
||||
{
|
||||
float flYawDiff = e->angles[YAW] - pstudio->prev->gaityaw;
|
||||
float flYawDiff = e->angles[YAW] - pstudio->lerp->gaityaw;
|
||||
|
||||
flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
|
||||
if( flYawDiff > 180 ) flYawDiff -= 360;
|
||||
|
@ -2063,15 +2145,15 @@ void R_StudioEstimateGait( ref_entity_t *e, edict_t *pplayer )
|
|||
if( dt < 0.25 ) flYawDiff *= dt * 4;
|
||||
else flYawDiff *= dt;
|
||||
|
||||
pstudio->prev->gaityaw += flYawDiff;
|
||||
pstudio->prev->gaityaw = pstudio->prev->gaityaw - (int)(pstudio->prev->gaityaw / 360) * 360;
|
||||
pstudio->lerp->gaityaw += flYawDiff;
|
||||
pstudio->lerp->gaityaw = pstudio->lerp->gaityaw - (int)(pstudio->lerp->gaityaw / 360) * 360;
|
||||
m_flGaitMovement = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pstudio->prev->gaityaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
|
||||
if( pstudio->prev->gaityaw > 180 ) pstudio->prev->gaityaw = 180;
|
||||
if( pstudio->prev->gaityaw < -180 ) pstudio->prev->gaityaw = -180;
|
||||
pstudio->lerp->gaityaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
|
||||
if( pstudio->lerp->gaityaw > 180 ) pstudio->lerp->gaityaw = 180;
|
||||
if( pstudio->lerp->gaityaw < -180 ) pstudio->lerp->gaityaw = -180;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2088,54 +2170,54 @@ void R_StudioProcessGait( ref_entity_t *e, edict_t *pplayer, studiovars_t *pstud
|
|||
float dt, flYaw; // view direction relative to movement
|
||||
int iBlend;
|
||||
|
||||
if( e->prev->cursequence >= m_pStudioHeader->numseq )
|
||||
e->prev->cursequence = 0;
|
||||
if( e->lerp->curstate.sequence >= m_pStudioHeader->numseq )
|
||||
e->lerp->curstate.sequence = 0;
|
||||
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->prev->cursequence;
|
||||
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->lerp->curstate.sequence;
|
||||
R_StudioPlayerBlend( pseqdesc, &iBlend, &e->angles[PITCH] );
|
||||
|
||||
pstudio->prev->curblending[0] = iBlend;
|
||||
pstudio->prev->blending[0] = pstudio->prev->curblending[0];
|
||||
pstudio->prev->seqblending[0] = pstudio->prev->curblending[0];
|
||||
pstudio->lerp->curstate.blending[0] = iBlend;
|
||||
pstudio->lerp->latched.blending[0] = pstudio->lerp->curstate.blending[0];
|
||||
pstudio->lerp->latched.seqblending[0] = pstudio->lerp->curstate.blending[0];
|
||||
|
||||
// MsgDev( D_INFO, "%f %d\n", e->angles[PITCH], pstudio->prev->curblending[0] );
|
||||
// Msg( "%f %d\n", e->angles[PITCH], pstudio->lerp->curstate.blending[0] );
|
||||
|
||||
dt = bound( 0.0f, RI.refdef.frametime, 1.0f );
|
||||
|
||||
R_StudioEstimateGait( e, pplayer );
|
||||
|
||||
// MsgDev( D_INFO, "%f %f\n", e->angles[YAW], m_pPlayerInfo->gaityaw );
|
||||
// Msg( "%f %f\n", e->angles[YAW], pstudio->lerp->gaityaw );
|
||||
|
||||
// calc side to side turning
|
||||
flYaw = e->angles[YAW] - pstudio->prev->gaityaw;
|
||||
flYaw = e->angles[YAW] - pstudio->lerp->gaityaw;
|
||||
flYaw = flYaw - (int)(flYaw / 360) * 360;
|
||||
if( flYaw < -180 ) flYaw = flYaw + 360;
|
||||
if( flYaw > 180 ) flYaw = flYaw - 360;
|
||||
|
||||
if( flYaw > 120 )
|
||||
{
|
||||
pstudio->prev->gaityaw = pstudio->prev->gaityaw - 180;
|
||||
pstudio->lerp->gaityaw = pstudio->lerp->gaityaw - 180;
|
||||
m_flGaitMovement = -m_flGaitMovement;
|
||||
flYaw = flYaw - 180;
|
||||
}
|
||||
else if( flYaw < -120 )
|
||||
{
|
||||
pstudio->prev->gaityaw = pstudio->prev->gaityaw + 180;
|
||||
pstudio->lerp->gaityaw = pstudio->lerp->gaityaw + 180;
|
||||
m_flGaitMovement = -m_flGaitMovement;
|
||||
flYaw = flYaw + 180;
|
||||
}
|
||||
|
||||
// adjust torso
|
||||
pstudio->prev->curcontroller[0] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
|
||||
pstudio->prev->curcontroller[1] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
|
||||
pstudio->prev->curcontroller[2] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
|
||||
pstudio->prev->curcontroller[3] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
|
||||
pstudio->prev->controller[0] = pstudio->prev->curcontroller[0];
|
||||
pstudio->prev->controller[1] = pstudio->prev->curcontroller[1];
|
||||
pstudio->prev->controller[2] = pstudio->prev->curcontroller[2];
|
||||
pstudio->prev->controller[3] = pstudio->prev->curcontroller[3];
|
||||
pstudio->lerp->curstate.controller[0] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
|
||||
pstudio->lerp->curstate.controller[1] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
|
||||
pstudio->lerp->curstate.controller[2] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
|
||||
pstudio->lerp->curstate.controller[3] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
|
||||
pstudio->lerp->latched.controller[0] = pstudio->lerp->curstate.controller[0];
|
||||
pstudio->lerp->latched.controller[1] = pstudio->lerp->curstate.controller[1];
|
||||
pstudio->lerp->latched.controller[2] = pstudio->lerp->curstate.controller[2];
|
||||
pstudio->lerp->latched.controller[3] = pstudio->lerp->curstate.controller[3];
|
||||
|
||||
e->angles[YAW] = pstudio->prev->gaityaw;
|
||||
e->angles[YAW] = pstudio->lerp->gaityaw;
|
||||
if( e->angles[YAW] < -0 ) e->angles[YAW] += 360;
|
||||
|
||||
if( pplayer->v.gaitsequence >= m_pStudioHeader->numseq )
|
||||
|
@ -2146,16 +2228,16 @@ void R_StudioProcessGait( ref_entity_t *e, edict_t *pplayer, studiovars_t *pstud
|
|||
// calc gait frame
|
||||
if( pseqdesc->linearmovement[0] > 0 )
|
||||
{
|
||||
pstudio->prev->gaitframe += (m_flGaitMovement / pseqdesc->linearmovement[0]) * pseqdesc->numframes;
|
||||
pstudio->lerp->gaitframe += (m_flGaitMovement / pseqdesc->linearmovement[0]) * pseqdesc->numframes;
|
||||
}
|
||||
else
|
||||
{
|
||||
pstudio->prev->gaitframe += pseqdesc->fps * dt;
|
||||
pstudio->lerp->gaitframe += pseqdesc->fps * dt;
|
||||
}
|
||||
|
||||
// do modulo
|
||||
pstudio->prev->gaitframe = pstudio->prev->gaitframe - (int)(pstudio->prev->gaitframe / pseqdesc->numframes) * pseqdesc->numframes;
|
||||
if( pstudio->prev->gaitframe < 0 ) pstudio->prev->gaitframe += pseqdesc->numframes;
|
||||
pstudio->lerp->gaitframe = pstudio->lerp->gaitframe - (int)(pstudio->lerp->gaitframe / pseqdesc->numframes) * pseqdesc->numframes;
|
||||
if( pstudio->lerp->gaitframe < 0 ) pstudio->lerp->gaitframe += pseqdesc->numframes;
|
||||
}
|
||||
|
||||
static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
|
||||
|
@ -2173,9 +2255,9 @@ static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
|
|||
// special handle for player model
|
||||
if( e->ent_type == ED_CLIENT || e->renderfx == kRenderFxDeadPlayer )
|
||||
{
|
||||
// MsgDev( D_INFO, "DrawPlayer %d\n", pstudio->blending[0] );
|
||||
// MsgDev( D_INFO, "DrawPlayer %d %d (%d)\n", r_framecount2, m_pEntity->serialnumber, e->prev->cursequence );
|
||||
// MsgDev( D_INFO, "Player %.2f %.2f %.2f\n", m_pEntity->v.velocity[0], m_pEntity->v.velocity[1], m_pEntity->v.velocity[2] );
|
||||
// Msg( "DrawPlayer %d\n", pstudio->lerp->blending[0] );
|
||||
// Msg( "DrawPlayer %d %d (%d)\n", r_framecount2, m_pEntity->serialnumber, e->lerp->curstate.sequence );
|
||||
// Msg( "Player %.2f %.2f %.2f\n", m_pEntity->v.velocity[0], m_pEntity->v.velocity[1], m_pEntity->v.velocity[2] );
|
||||
|
||||
if( e->renderfx == kRenderFxDeadPlayer )
|
||||
{
|
||||
|
@ -2193,7 +2275,7 @@ static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
|
|||
if( m_pEntity->v.gaitsequence <= 0 )
|
||||
{
|
||||
for( i = 0; i < 4; i++ ) // clear torso controllers
|
||||
pstudio->prev->controller[i] = pstudio->prev->curcontroller[i] = 0x7F;
|
||||
pstudio->lerp->latched.controller[i] = pstudio->lerp->curstate.controller[i] = 0x7F;
|
||||
e->gaitsequence = 0; // StudioSetupBones() issuses
|
||||
|
||||
R_StudioSetUpTransform ( e, false );
|
||||
|
@ -2227,18 +2309,18 @@ static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
|
|||
if( m_pEntity && e->movetype != MOVETYPE_FOLLOW && !RI.refdef.paused && e->m_nCachedFrameCount != r_framecount2 )
|
||||
{
|
||||
float flInterval = 0.1f;
|
||||
float flStart = e->prev->curframe + (pstudio->prev->m_flLastEventCheck - e->prev->curanimtime) * pstudio->prev->m_flFrameRate * e->framerate;
|
||||
float flEnd = e->prev->curframe + flInterval * pstudio->prev->m_flFrameRate * e->framerate;
|
||||
float flStart = e->lerp->curstate.frame + (pstudio->lerp->m_flLastEventCheck - e->lerp->curstate.animtime) * pstudio->lerp->m_flFrameRate * e->framerate;
|
||||
float flEnd = e->lerp->curstate.frame + flInterval * pstudio->lerp->m_flFrameRate * e->framerate;
|
||||
int index = 0;
|
||||
dstudioevent_t event;
|
||||
|
||||
Mem_Set( &event, 0, sizeof( event ));
|
||||
R_StudioCalcAttachments( e );
|
||||
|
||||
pstudio->prev->m_flLastEventCheck = e->prev->curanimtime + flInterval;
|
||||
pstudio->prev->m_fSequenceFinished = false;
|
||||
pstudio->lerp->m_flLastEventCheck = e->lerp->curstate.animtime + flInterval;
|
||||
pstudio->lerp->m_fSequenceFinished = false;
|
||||
if( flEnd >= 256.0f || flEnd <= 0.0f )
|
||||
pstudio->prev->m_fSequenceFinished = true;
|
||||
pstudio->lerp->m_fSequenceFinished = true;
|
||||
|
||||
while(( index = R_StudioGetEvent( e, &event, flStart, flEnd, index )) != 0 )
|
||||
ri.StudioEvent( &event, m_pEntity );
|
||||
|
@ -2420,12 +2502,12 @@ bool R_CullStudioModel( ref_entity_t *e )
|
|||
{
|
||||
// cull child entities with parent volume
|
||||
R_StudioSetupRender( e->parent, e->parent->model );
|
||||
sequence = e->parent->prev->cursequence;
|
||||
sequence = e->parent->lerp->curstate.sequence;
|
||||
}
|
||||
else
|
||||
{
|
||||
R_StudioSetupRender( e, e->model );
|
||||
sequence = e->prev->cursequence;
|
||||
sequence = e->lerp->curstate.sequence;
|
||||
}
|
||||
|
||||
if(!R_ExtractBbox( sequence, studio_mins, studio_maxs ))
|
||||
|
@ -2491,12 +2573,12 @@ void R_AddStudioModelToList( ref_entity_t *e )
|
|||
{
|
||||
// cull child entities with parent volume
|
||||
R_StudioSetupRender( e->parent, e->parent->model );
|
||||
sequence = e->parent->prev->cursequence;
|
||||
sequence = e->parent->lerp->curstate.sequence;
|
||||
}
|
||||
else
|
||||
{
|
||||
R_StudioSetupRender( e, e->model );
|
||||
sequence = e->prev->cursequence;
|
||||
sequence = e->lerp->curstate.sequence;
|
||||
}
|
||||
|
||||
if(!R_ExtractBbox( sequence, studio_mins, studio_maxs )) return; // invalid sequence
|
||||
|
|
Reference in New Issue