2
0
mirror of https://github.com/rehlds/rehlds.git synced 2025-03-13 14:00:26 +03:00

Theoretically better unlag based on bose position restoring

This commit is contained in:
Alibek Omarov 2018-06-07 18:52:30 +03:00
parent 65c6ce593b
commit 61d4844826
5 changed files with 153 additions and 2 deletions

View File

@ -627,7 +627,11 @@ hull_t *R_StudioHull(model_t *pModel, float frame, int sequence, const vec_t *an
pstudiohdr = (studiohdr_t *)Mod_Extradata(pModel);
vec_t angles2[3] = { -angles[0], angles[1], angles[2] };
#ifdef REHLDS_FIXES
SV_StudioSetupUnlagBones( pModel, frame, sequence, angles2, origin, pcontroller, pblending, -1, pEdict );
#else
g_pSvBlendingAPI->SV_StudioSetupBones(pModel, frame, sequence, angles2, origin, pcontroller, pblending, -1, pEdict);
#endif
mstudiobbox_t *pbbox = (mstudiobbox_t *)((char *)pstudiohdr + pstudiohdr->hitboxindex);
for (int i = 0; i < pstudiohdr->numhitboxes; i++)
@ -874,6 +878,17 @@ void EXT_FUNC AnimationAutomove(const edict_t *pEdict, float flTime)
void EXT_FUNC GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles)
{
pstudiohdr = (studiohdr_t *)Mod_Extradata(g_psv.models[pEdict->v.modelindex]);
#ifdef REHLDS_FIXES
SV_StudioSetupUnlagBones( g_psv.models[pEdict->v.modelindex],
pEdict->v.frame,
pEdict->v.sequence,
pEdict->v.angles,
pEdict->v.origin,
pEdict->v.controller,
pEdict->v.blending,
iBone,
pEdict );
#else
g_pSvBlendingAPI->SV_StudioSetupBones(
g_psv.models[pEdict->v.modelindex],
pEdict->v.frame,
@ -885,6 +900,7 @@ void EXT_FUNC GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigi
iBone,
pEdict
);
#endif
if (rgflOrigin)
{
@ -907,6 +923,20 @@ void EXT_FUNC GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflO
pattachment = (mstudioattachment_t *)((char *)pstudiohdr + pstudiohdr->attachmentindex);
pattachment += iAttachment;
#ifdef REHLDS_FIXES
SV_StudioSetupUnlagBones(
g_psv.models[pEdict->v.modelindex],
pEdict->v.frame,
pEdict->v.sequence,
angles,
pEdict->v.origin,
pEdict->v.controller,
pEdict->v.blending,
pattachment->bone,
pEdict
);
#else
g_pSvBlendingAPI->SV_StudioSetupBones(
g_psv.models[pEdict->v.modelindex],
pEdict->v.frame,
@ -918,6 +948,7 @@ void EXT_FUNC GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflO
pattachment->bone,
pEdict
);
#endif
if (rgflOrigin)
VectorTransform(pattachment->org, bonetransform[pattachment->bone], rgflOrigin);

View File

@ -53,6 +53,7 @@ const int MAX_NAME = 32;
#include "pm_defs.h"
#include "inst_baseline.h"
#include "net_ws.h"
#include "studio_rehlds.h"
const int DEFAULT_SOUND_PACKET_VOLUME = 255;
const float DEFAULT_SOUND_PACKET_ATTENUATION = 1.0f;
@ -175,6 +176,16 @@ struct rehlds_server_t {
#endif
};
#ifdef REHLDS_FIXES
// a1batross: "bone position"-based unlag
typedef struct client_bone_state_s
{
bonetransform_t bonetransform;
float rotationmatrix[3][4];
qboolean valid;
} client_bone_state_t;
#endif // REHLDS_FIXES
typedef struct client_frame_s
{
double senttime;
@ -182,6 +193,9 @@ typedef struct client_frame_s
clientdata_t clientdata;
weapon_data_t weapondata[64];
packet_entities_t entities;
#ifdef REHLDS_FIXES // a1batross: "bone position"-based unlag
client_bone_state_t bonestate;
#endif // REHLDS_FIXES
} client_frame_t;
typedef struct client_s

View File

@ -7717,6 +7717,9 @@ void SV_Init(void)
Cvar_RegisterVariable(&sv_instancedbaseline);
Cvar_RegisterVariable(&sv_contact);
Cvar_RegisterVariable(&sv_unlag);
#ifdef REHLDS_FIXES
Cvar_RegisterVariable(&sv_bone_unlag);
#endif
Cvar_RegisterVariable(&sv_maxunlag);
Cvar_RegisterVariable(&sv_unlagpush);
Cvar_RegisterVariable(&sv_unlagsamples);

View File

@ -59,6 +59,9 @@ cvar_t sv_footsteps = { "mp_footsteps", "1", FCVAR_SERVER, 0.0f, NULL };
cvar_t sv_rollspeed = { "sv_rollspeed", "0.0", 0, 0.0f, NULL };
cvar_t sv_rollangle = { "sv_rollangle", "0.0", 0, 0.0f, NULL };
cvar_t sv_unlag = { "sv_unlag", "1", 0, 0.0f, NULL };
#ifdef REHLDS_FIXES
cvar_t sv_bone_unlag = { "sv_bone_unlag", "0", 0, 0.0f, NULL };
#endif // REHLDS_FIXES
cvar_t sv_maxunlag = { "sv_maxunlag", "0.5", 0, 0.0f, NULL };
cvar_t sv_unlagpush = { "sv_unlagpush", "0.0", 0, 0.0f, NULL };
cvar_t sv_unlagsamples = { "sv_unlagsamples", "1", 0, 0.0f, NULL };
@ -1008,6 +1011,10 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
gGlobalVariables.frametime = frametime;
gEntityInterface.pfnPlayerPostThink(sv_player);
gEntityInterface.pfnCmdEnd(sv_player);
#ifdef REHLDS_FIXES
SV_SaveBoneState( host_client, sv_player );
#endif
if (!host_client->fakeclient)
SV_RestoreMove(host_client);
@ -1320,7 +1327,7 @@ void SV_SetupMove(client_t *_host_client)
frame = nextFrame;
frac = 0.0;
}
for (i = 0; i < nextFrame->entities.num_entities; i++)
{
state = &nextFrame->entities.entities[i];
@ -1342,6 +1349,25 @@ void SV_SetupMove(client_t *_host_client)
}
pnextstate = SV_FindEntInPack(state->number, &frame->entities);
#ifdef REHLDS_FIXES
if( nextFrame->bonestate.valid )
{
if( frame->bonestate.valid )
{
// TODO: interpolate
pos->bonestate = nextFrame->bonestate;
}
else
{
pos->bonestate = nextFrame->bonestate;
}
}
else
{
pos->bonestate.valid = false;
}
#endif // REHLDS_FIXES
if (pnextstate)
{
@ -1409,7 +1435,11 @@ void SV_RestoreMove(client_t *_host_client)
Con_DPrintf("SV_RestoreMove: Tried to restore 'inactive' player %i/%s\n", i, &cli->name[4]);
continue;
}
#ifdef REHLDS_FIXES
pos->bonestate.valid = false;
#endif // REHLDS_FIXES
if (VectorCompare(pos->initial_correction_org, cli->edict->v.origin))
{
cli->edict->v.origin[0] = pos->oldorg[0];
@ -1910,3 +1940,63 @@ void SV_FullUpdate_f(void)
gEntityInterface.pfnClientCommand(sv_player);
#endif // REHLDS_FIXES
}
#ifdef REHLDS_FIXES
void SV_SaveBoneState(client_t *_host_client, const edict_t *edict)
{
int num = NUM_FOR_EDICT( edict );
client_frame_t *frame;
extern bonetransform_t bonetransform; // in r_studio.cpp
extern float rotationmatrix[3][4]; // in r_studio.cpp
if( !SV_IsPlayerIndex( num )) // just in case
return;
// get last outgoing frame
frame = &_host_client->frames[SV_UPDATE_MASK & (_host_client->netchan.outgoing_sequence)];
// set up bones
g_pSvBlendingAPI->SV_StudioSetupBones(
g_psv.models[edict->v.modelindex],
edict->v.frame, edict->v.sequence, edict->v.angles, edict->v.origin,
edict->v.controller, edict->v.blending, -1, edict
);
// copy bones
frame->bonestate.valid = true;
Q_memcpy( frame->bonestate.bonetransform, bonetransform, sizeof( bonetransform ));
Q_memcpy( frame->bonestate.rotationmatrix, rotationmatrix, sizeof( rotationmatrix ));
}
void SV_StudioSetupUnlagBones( model_t *pModel, float frame, int sequence, const vec_t *angles, const vec_t *origin, const unsigned char *pcontroller, const unsigned char *pblending, int iBone, const edict_t *edict )
{
// a1ba: carefully check everything, otherwise we may get broken bones!
if( edict && sv_bone_unlag.value ) // check is this a server or disabled
{
if( !nofind ) // unlag is enabled
{
if( edict->v.flags & FL_CLIENT )
{
int num = NUM_FOR_EDICT( edict );
if( truepositions[num].active &&
!truepositions[num].needrelink && // TODO: will this work for moving clients?
truepositions[num].bonestate.valid ) // bones are correct
{
// in r_studio.cpp
extern bonetransform_t bonetransform;
extern float rotationmatrix[3][4];
Q_memcpy( bonetransform, truepositions[num].bonestate.bonetransform, sizeof( bonetransform ));
Q_memcpy( rotationmatrix, truepositions[num].bonestate.rotationmatrix, sizeof( rotationmatrix ));
return;
}
}
}
}
// fallback to original SV_StudioSetupBones
g_pSvBlendingAPI->SV_StudioSetupBones(pModel, frame, sequence, angles, origin, pcontroller, pblending, iBone, edict);
}
#endif // REHLDS_FIXES

View File

@ -49,6 +49,9 @@ typedef struct sv_adjusted_positions_s
int deadflag;
vec3_t temp_org;
int temp_org_setflag;
#ifdef REHLDS_FIXES
client_bone_state_t bonestate;
#endif // REHLDS_FIXES
} sv_adjusted_positions_t;
typedef struct clc_func_s
@ -71,6 +74,9 @@ extern cvar_t sv_footsteps;
extern cvar_t sv_rollspeed;
extern cvar_t sv_rollangle;
extern cvar_t sv_unlag;
#ifdef REHLDS_FIXES
extern cvar_t sv_bone_unlag;
#endif
extern cvar_t sv_maxunlag;
extern cvar_t sv_unlagpush;
extern cvar_t sv_unlagsamples;
@ -117,3 +123,10 @@ qboolean SV_SetPlayer(int idnum);
void SV_ShowServerinfo_f(void);
void SV_SendEnts_f(void);
void SV_FullUpdate_f(void);
#ifdef REHLDS_FIXES
void SV_SaveBoneState( client_t *cl, const edict_t *edict );
// "bone position"-based sv_unlag
void SV_StudioSetupUnlagBones( model_t *pModel, float frame, int sequence, const vec_t *angles, const vec_t *origin, const unsigned char *pcontroller, const unsigned char *pblending, int iBone, const edict_t *edict );
#endif // REHLDS_FIXES