Lots of misc changes in an attempt to reduce ODE jitter, and make it work a little better.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3456 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
eae4caee99
commit
9eabcdcd56
9 changed files with 115 additions and 44 deletions
|
@ -30,8 +30,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#ifdef USEODE
|
||||
|
||||
#pragma message("fixme: pitch values are probably inverted")
|
||||
|
||||
//============================================================================
|
||||
// physics engine support
|
||||
//============================================================================
|
||||
|
@ -48,6 +46,8 @@ cvar_t physics_ode_worldquickstep_iterations = CVARDP4(0, "physics_ode_worldquic
|
|||
cvar_t physics_ode_contact_mu = CVARDP4(0, "physics_ode_contact_mu", "1", "contact solver mu parameter - friction pyramid approximation 1 (see ODE User Guide)");
|
||||
cvar_t physics_ode_contact_erp = CVARDP4(0, "physics_ode_contact_erp", "0.96", "contact solver erp parameter - Error Restitution Percent (see ODE User Guide)");
|
||||
cvar_t physics_ode_contact_cfm = CVARDP4(0, "physics_ode_contact_cfm", "0", "contact solver cfm parameter - Constraint Force Mixing (see ODE User Guide)");
|
||||
cvar_t physics_ode_world_damping_angle = CVARDP4(0, "physics_ode_world_damping_angle", "0", "damping");
|
||||
cvar_t physics_ode_world_damping_linear = CVARDP4(0, "physics_ode_world_damping_linear", "0", "damping");
|
||||
cvar_t physics_ode_world_erp = CVARDP4(0, "physics_ode_world_erp", "-1", "world solver erp parameter - Error Restitution Percent (see ODE User Guide); use defaults when set to -1");
|
||||
cvar_t physics_ode_world_cfm = CVARDP4(0, "physics_ode_world_cfm", "-1", "world solver cfm parameter - Constraint Force Mixing (see ODE User Guide); not touched when -1");
|
||||
cvar_t physics_ode_iterationsperframe = CVARDP4(0, "physics_ode_iterationsperframe", "4", "divisor for time step, runs multiple physics steps per frame");
|
||||
|
@ -307,7 +307,7 @@ void (ODE_API *dWorldSetContactSurfaceLayer)(dWorldID, dReal depth);
|
|||
//dReal (ODE_API *dWorldGetAutoDisableTime)(dWorldID);
|
||||
//void (ODE_API *dWorldSetAutoDisableTime)(dWorldID, dReal time);
|
||||
//int (ODE_API *dWorldGetAutoDisableFlag)(dWorldID);
|
||||
//void (ODE_API *dWorldSetAutoDisableFlag)(dWorldID, int do_auto_disable);
|
||||
void (ODE_API *dWorldSetAutoDisableFlag)(dWorldID, int do_auto_disable);
|
||||
//dReal (ODE_API *dWorldGetLinearDampingThreshold)(dWorldID w);
|
||||
//void (ODE_API *dWorldSetLinearDampingThreshold)(dWorldID w, dReal threshold);
|
||||
//dReal (ODE_API *dWorldGetAngularDampingThreshold)(dWorldID w);
|
||||
|
@ -316,7 +316,7 @@ void (ODE_API *dWorldSetContactSurfaceLayer)(dWorldID, dReal depth);
|
|||
//void (ODE_API *dWorldSetLinearDamping)(dWorldID w, dReal scale);
|
||||
//dReal (ODE_API *dWorldGetAngularDamping)(dWorldID w);
|
||||
//void (ODE_API *dWorldSetAngularDamping)(dWorldID w, dReal scale);
|
||||
//void (ODE_API *dWorldSetDamping)(dWorldID w, dReal linear_scale, dReal angular_scale);
|
||||
void (ODE_API *dWorldSetDamping)(dWorldID w, dReal linear_scale, dReal angular_scale);
|
||||
//dReal (ODE_API *dWorldGetMaxAngularSpeed)(dWorldID w);
|
||||
//void (ODE_API *dWorldSetMaxAngularSpeed)(dWorldID w, dReal max_speed);
|
||||
//dReal (ODE_API *dBodyGetAutoDisableLinearThreshold)(dBodyID);
|
||||
|
@ -772,7 +772,7 @@ static dllfunction_t odefuncs[] =
|
|||
// {"dWorldGetAutoDisableTime", (void **) &dWorldGetAutoDisableTime},
|
||||
// {"dWorldSetAutoDisableTime", (void **) &dWorldSetAutoDisableTime},
|
||||
// {"dWorldGetAutoDisableFlag", (void **) &dWorldGetAutoDisableFlag},
|
||||
// {"dWorldSetAutoDisableFlag", (void **) &dWorldSetAutoDisableFlag},
|
||||
{(void **) &dWorldSetAutoDisableFlag, "dWorldSetAutoDisableFlag"},
|
||||
// {"dWorldGetLinearDampingThreshold", (void **) &dWorldGetLinearDampingThreshold},
|
||||
// {"dWorldSetLinearDampingThreshold", (void **) &dWorldSetLinearDampingThreshold},
|
||||
// {"dWorldGetAngularDampingThreshold", (void **) &dWorldGetAngularDampingThreshold},
|
||||
|
@ -781,7 +781,7 @@ static dllfunction_t odefuncs[] =
|
|||
// {"dWorldSetLinearDamping", (void **) &dWorldSetLinearDamping},
|
||||
// {"dWorldGetAngularDamping", (void **) &dWorldGetAngularDamping},
|
||||
// {"dWorldSetAngularDamping", (void **) &dWorldSetAngularDamping},
|
||||
// {"dWorldSetDamping", (void **) &dWorldSetDamping},
|
||||
{(void **) &dWorldSetDamping, "dWorldSetDamping"},
|
||||
// {"dWorldGetMaxAngularSpeed", (void **) &dWorldGetMaxAngularSpeed},
|
||||
// {"dWorldSetMaxAngularSpeed", (void **) &dWorldSetMaxAngularSpeed},
|
||||
// {"dBodyGetAutoDisableLinearThreshold", (void **) &dBodyGetAutoDisableLinearThreshold},
|
||||
|
@ -1185,6 +1185,8 @@ void World_Physics_Init(void)
|
|||
Cvar_Register(&physics_ode_contact_mu, "ODE Physics Library");
|
||||
Cvar_Register(&physics_ode_contact_erp, "ODE Physics Library");
|
||||
Cvar_Register(&physics_ode_contact_cfm, "ODE Physics Library");
|
||||
Cvar_Register(&physics_ode_world_damping_angle, "ODE Physics Library");
|
||||
Cvar_Register(&physics_ode_world_damping_linear, "ODE Physics Library");
|
||||
Cvar_Register(&physics_ode_world_erp, "ODE Physics Library");
|
||||
Cvar_Register(&physics_ode_world_cfm, "ODE Physics Library");
|
||||
Cvar_Register(&physics_ode_iterationsperframe, "ODE Physics Library");
|
||||
|
@ -1251,6 +1253,8 @@ static void World_Physics_EnableODE(world_t *world)
|
|||
dWorldSetERP(world->ode.ode_world, physics_ode_world_erp.value);
|
||||
if(physics_ode_world_cfm.value >= 0)
|
||||
dWorldSetCFM(world->ode.ode_world, physics_ode_world_cfm.value);
|
||||
dWorldSetDamping(world->ode.ode_world, physics_ode_world_damping_linear.value, physics_ode_world_damping_angle.value);
|
||||
// dWorldSetAutoDisableFlag (world->ode.ode_world, true);
|
||||
}
|
||||
|
||||
void World_Physics_Start(world_t *world)
|
||||
|
|
|
@ -780,7 +780,41 @@ coorddata MSG_ToCoord(float f, int bytes) //return value should be treated as (c
|
|||
switch(bytes)
|
||||
{
|
||||
case 2:
|
||||
r.b2 = LittleShort((short)(f*8));
|
||||
r.b4 = 0;
|
||||
if (f >= 0)
|
||||
r.b2 = LittleShort((short)(f*8+0.5f));
|
||||
else
|
||||
r.b2 = LittleShort((short)(f*8-0.5f));
|
||||
break;
|
||||
case 4:
|
||||
r.f = LittleFloat(f);
|
||||
break;
|
||||
default:
|
||||
Sys_Error("MSG_ToCoord: not a sane coordsize");
|
||||
r.b4 = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
coorddata MSG_ToAngle(float f, int bytes) //return value is NOT byteswapped.
|
||||
{
|
||||
coorddata r;
|
||||
switch(bytes)
|
||||
{
|
||||
case 1:
|
||||
r.b4 = 0;
|
||||
if (f >= 0)
|
||||
r.b[0] = (int)(f*(256.0f/360.0f) + 0.5f) & 255;
|
||||
else
|
||||
r.b[0] = (int)(f*(256.0f/360.0f) - 0.5f) & 255;
|
||||
break;
|
||||
case 2:
|
||||
r.b4 = 0;
|
||||
if (f >= 0)
|
||||
r.b2 = LittleShort((int)(f*(65536.0f/360.0f) + 0.5f) & 65535);
|
||||
else
|
||||
r.b2 = LittleShort((int)(f*(65536.0f/360.0f) - 0.5f) & 65535);
|
||||
break;
|
||||
case 4:
|
||||
r.f = LittleFloat(f);
|
||||
|
@ -801,11 +835,17 @@ void MSG_WriteCoord (sizebuf_t *sb, float f)
|
|||
|
||||
void MSG_WriteAngle16 (sizebuf_t *sb, float f)
|
||||
{
|
||||
MSG_WriteShort (sb, (int)(f*65536/360) & 65535);
|
||||
if (f >= 0)
|
||||
MSG_WriteShort (sb, (int)(f*(65536.0f/360.0f) + 0.5f) & 65535);
|
||||
else
|
||||
MSG_WriteShort (sb, (int)(f*(65536.0f/360.0f) - 0.5f) & 65535);
|
||||
}
|
||||
void MSG_WriteAngle8 (sizebuf_t *sb, float f)
|
||||
{
|
||||
MSG_WriteByte (sb, (int)(f*256/360) & 255);
|
||||
if (f >= 0)
|
||||
MSG_WriteByte (sb, (int)(f*(256.0f/360.0f) + 0.5f) & 255);
|
||||
else
|
||||
MSG_WriteByte (sb, (int)(f*(256.0f/360.0f) - 0.5f) & 255);
|
||||
}
|
||||
|
||||
void MSG_WriteAngle (sizebuf_t *sb, float f)
|
||||
|
|
|
@ -131,6 +131,7 @@ extern int sizeofcoord;
|
|||
extern int sizeofangle;
|
||||
float MSG_FromCoord(coorddata c, int bytes);
|
||||
coorddata MSG_ToCoord(float f, int bytes);
|
||||
coorddata MSG_ToAngle(float f, int bytes);
|
||||
|
||||
void MSG_WriteChar (sizebuf_t *sb, int c);
|
||||
void MSG_WriteByte (sizebuf_t *sb, int c);
|
||||
|
|
|
@ -377,9 +377,6 @@ typedef struct {
|
|||
|
||||
} fragmentdecal_t;
|
||||
|
||||
#define FloatInterpolate(a, bness, b, c) (c) = (a)*(1-bness) + (b)*bness
|
||||
#define VectorInterpolate(a, bness, b, c) FloatInterpolate((a)[0], bness, (b)[0], (c)[0]),FloatInterpolate((a)[1], bness, (b)[1], (c)[1]),FloatInterpolate((a)[2], bness, (b)[2], (c)[2])
|
||||
|
||||
//#define SHOWCLIPS
|
||||
//#define FRAGMENTASTRIANGLES //works, but produces more fragments.
|
||||
|
||||
|
|
|
@ -2801,6 +2801,11 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
|
|||
unsigned int chksum;
|
||||
int start;
|
||||
qboolean noerrors;
|
||||
#if (defined(ODE_STATIC) || defined(ODE_DYNAMIC))
|
||||
qboolean ode = true;
|
||||
#else
|
||||
#define ode true
|
||||
#endif
|
||||
|
||||
start = Hunk_LowMark();
|
||||
|
||||
|
@ -2875,13 +2880,14 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
|
|||
crouchhullfile = NULL;
|
||||
|
||||
// load into heap
|
||||
#ifndef CLIENTONLY
|
||||
if (!isDedicated)
|
||||
#endif
|
||||
if (!isDedicated || ode)
|
||||
{
|
||||
noerrors = noerrors && RMod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
|
||||
noerrors = noerrors && RMod_LoadEdges (&header->lumps[LUMP_EDGES]);
|
||||
noerrors = noerrors && RMod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
|
||||
}
|
||||
if (!isDedicated)
|
||||
{
|
||||
noerrors = noerrors && RMod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
|
||||
if (noerrors)
|
||||
RMod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
|
||||
|
@ -2890,14 +2896,13 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
|
|||
if (noerrors)
|
||||
RMod_LoadCrouchHull();
|
||||
noerrors = noerrors && RMod_LoadPlanes (&header->lumps[LUMP_PLANES]);
|
||||
#ifndef CLIENTONLY
|
||||
if (!isDedicated)
|
||||
#endif
|
||||
if (!isDedicated || ode)
|
||||
{
|
||||
noerrors = noerrors && RMod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
|
||||
noerrors = noerrors && RMod_LoadFaces (&header->lumps[LUMP_FACES]);
|
||||
noerrors = noerrors && RMod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
|
||||
}
|
||||
}
|
||||
if (!isDedicated)
|
||||
noerrors = noerrors && RMod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
|
||||
if (noerrors)
|
||||
RMod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
|
||||
noerrors = noerrors && RMod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
|
||||
|
@ -2941,6 +2946,13 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
|
|||
|
||||
mod->numframes = 2; // regular and alternate animation
|
||||
|
||||
/*FIXME: move mesh_t and lightmap allocation out of r_surf
|
||||
for (i=0 ; i<mod->numsurfaces ; i++)
|
||||
{
|
||||
Surf_BuildSurfaceDisplayList (mod, mod->surfaces + i);
|
||||
}
|
||||
*/
|
||||
|
||||
//
|
||||
// set up the submodels (FIXME: this is confusing)
|
||||
//
|
||||
|
|
|
@ -893,7 +893,7 @@ typedef enum multicast_e
|
|||
|
||||
//============================================================================
|
||||
|
||||
extern cvar_t sv_mintic, sv_maxtic;
|
||||
extern cvar_t sv_mintic, sv_maxtic, sv_limittics;
|
||||
extern cvar_t sv_maxspeed;
|
||||
extern cvar_t sv_antilag;
|
||||
extern cvar_t sv_antilag_frac;
|
||||
|
|
|
@ -428,7 +428,8 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
|
|||
int bits;
|
||||
int i;
|
||||
int fromeffects;
|
||||
float miss;
|
||||
coorddata coordd[3];
|
||||
coorddata angled[3];
|
||||
|
||||
static entity_state_t defaultbaseline;
|
||||
if (from == &((edict_t*)NULL)->baseline)
|
||||
|
@ -441,8 +442,8 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
|
|||
{
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
miss = (short)(to->origin[i]*8) - (short)(from->origin[i]*8);
|
||||
if (miss)
|
||||
coordd[i] = MSG_ToCoord(to->origin[i], sizeofcoord);
|
||||
if (MSG_ToCoord(from->origin[i], sizeofcoord).b4 != coordd[i].b4)
|
||||
bits |= U_ORIGIN1<<i;
|
||||
else
|
||||
to->origin[i] = from->origin[i];
|
||||
|
@ -452,19 +453,29 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
|
|||
{
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
coordd[i] = MSG_ToCoord(to->origin[i], sizeofcoord);
|
||||
if (to->origin[i] != from->origin[i])
|
||||
bits |= U_ORIGIN1<<i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( to->angles[0] != from->angles[0] )
|
||||
angled[0] = MSG_ToAngle(to->angles[0], sizeofangle);
|
||||
if (MSG_ToAngle(from->angles[0], sizeofcoord).b4 != angled[0].b4)
|
||||
bits |= U_ANGLE1;
|
||||
else
|
||||
to->angles[0] = from->angles[0];
|
||||
|
||||
if ( to->angles[1] != from->angles[1] )
|
||||
angled[1] = MSG_ToAngle(to->angles[1], sizeofangle);
|
||||
if (MSG_ToAngle(from->angles[1], sizeofcoord).b4 != angled[1].b4)
|
||||
bits |= U_ANGLE2;
|
||||
else
|
||||
to->angles[1] = from->angles[1];
|
||||
|
||||
if ( to->angles[2] != from->angles[2] )
|
||||
angled[2] = MSG_ToAngle(to->angles[2], sizeofangle);
|
||||
if (MSG_ToAngle(from->angles[2], sizeofcoord).b4 != angled[2].b4)
|
||||
bits |= U_ANGLE3;
|
||||
else
|
||||
to->angles[2] = from->angles[2];
|
||||
|
||||
if ( to->colormap != from->colormap )
|
||||
bits |= U_COLORMAP;
|
||||
|
@ -599,17 +610,17 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
|
|||
if (bits & U_EFFECTS)
|
||||
MSG_WriteByte (msg, to->effects&0x00ff);
|
||||
if (bits & U_ORIGIN1)
|
||||
MSG_WriteCoord (msg, to->origin[0]);
|
||||
SZ_Write(msg, &coordd[0], sizeofcoord);
|
||||
if (bits & U_ANGLE1)
|
||||
MSG_WriteAngle(msg, to->angles[0]);
|
||||
SZ_Write(msg, &angled[0], sizeofangle);
|
||||
if (bits & U_ORIGIN2)
|
||||
MSG_WriteCoord (msg, to->origin[1]);
|
||||
SZ_Write(msg, &coordd[1], sizeofcoord);
|
||||
if (bits & U_ANGLE2)
|
||||
MSG_WriteAngle(msg, to->angles[1]);
|
||||
SZ_Write(msg, &angled[1], sizeofangle);
|
||||
if (bits & U_ORIGIN3)
|
||||
MSG_WriteCoord (msg, to->origin[2]);
|
||||
SZ_Write(msg, &coordd[2], sizeofcoord);
|
||||
if (bits & U_ANGLE3)
|
||||
MSG_WriteAngle(msg, to->angles[2]);
|
||||
SZ_Write(msg, &angled[2], sizeofangle);
|
||||
|
||||
#ifdef U_SCALE
|
||||
if (evenmorebits & U_SCALE)
|
||||
|
@ -1417,7 +1428,7 @@ SV_WritePlayersToClient
|
|||
void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *clent, qbyte *pvs, sizebuf_t *msg)
|
||||
{
|
||||
qboolean isbot;
|
||||
int i, j;
|
||||
int j;
|
||||
client_t *cl;
|
||||
edict_t *ent, *vent;
|
||||
int pflags;
|
||||
|
@ -1524,6 +1535,7 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
|
|||
vec3_t vel;
|
||||
float lerp;
|
||||
float a1, a2;
|
||||
int i;
|
||||
extern vec3_t player_mins, player_maxs;
|
||||
clstate_t clst;
|
||||
extern float olddemotime, nextdemotime;
|
||||
|
|
|
@ -93,7 +93,9 @@ cvar_t sv_mintic = SCVAR("sv_mintic","0.03");
|
|||
#else
|
||||
cvar_t sv_mintic = SCVAR("sv_mintic","0"); //client builds can think as often as they want.
|
||||
#endif
|
||||
cvar_t sv_maxtic = SCVAR("sv_maxtic","0.1");
|
||||
cvar_t sv_maxtic = SCVAR("sv_maxtic","0.1");//never run a tick slower than this
|
||||
cvar_t sv_limittics = SCVAR("sv_limittics","3");//
|
||||
|
||||
cvar_t sv_nailhack = SCVAR("sv_nailhack","0");
|
||||
|
||||
|
||||
|
@ -3525,6 +3527,7 @@ void SV_InitLocal (void)
|
|||
|
||||
Cvar_Register (&sv_mintic, cvargroup_servercontrol);
|
||||
Cvar_Register (&sv_maxtic, cvargroup_servercontrol);
|
||||
Cvar_Register (&sv_limittics, cvargroup_servercontrol);
|
||||
|
||||
Cvar_Register (&fraglimit, cvargroup_serverinfo);
|
||||
Cvar_Register (&timelimit, cvargroup_serverinfo);
|
||||
|
|
|
@ -1981,6 +1981,7 @@ qboolean SV_Physics (void)
|
|||
qboolean retouch;
|
||||
edict_t *ent;
|
||||
qboolean moved = false;
|
||||
int maxtics;
|
||||
|
||||
|
||||
if (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM && svs.gametype != GT_HALFLIFE) //make tics multiples of sv_maxtic (defaults to 0.1)
|
||||
|
@ -2075,6 +2076,8 @@ qboolean SV_Physics (void)
|
|||
}
|
||||
}
|
||||
|
||||
maxtics = sv_limittics.ival;
|
||||
|
||||
// don't bother running a frame if sys_ticrate seconds haven't passed
|
||||
while (1)
|
||||
{
|
||||
|
@ -2086,18 +2089,17 @@ qboolean SV_Physics (void)
|
|||
}
|
||||
if (host_frametime <= 0 || host_frametime < sv_mintic.value)
|
||||
break;
|
||||
if (host_frametime > ((/*sv_captic.value<=*/0)?1:sv_maxtic.value*5))
|
||||
if (host_frametime > sv_maxtic.value)
|
||||
{
|
||||
//cap the distance to run physics
|
||||
if (--maxtics == 0)
|
||||
{
|
||||
//timewarp, as we're running too slowly
|
||||
sv.world.physicstime = sv.time;
|
||||
break;
|
||||
}
|
||||
host_frametime = sv_maxtic.value;
|
||||
sv.world.physicstime = sv.time;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (host_frametime > sv_maxtic.value)
|
||||
host_frametime = sv_maxtic.value;
|
||||
sv.world.physicstime += host_frametime;
|
||||
}
|
||||
sv.world.physicstime += host_frametime;
|
||||
|
||||
moved = true;
|
||||
|
||||
|
|
Loading…
Reference in a new issue