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:
Spoike 2009-11-15 03:20:17 +00:00
parent eae4caee99
commit 9eabcdcd56
9 changed files with 115 additions and 44 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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.

View File

@ -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)
//

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;