From 9eabcdcd5601d9227e68af68e96ceca78ad481b0 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 15 Nov 2009 03:20:17 +0000 Subject: [PATCH] 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 --- engine/common/com_phys_ode.c | 16 ++++++++----- engine/common/common.c | 46 +++++++++++++++++++++++++++++++++--- engine/common/common.h | 1 + engine/common/q1bsp.c | 3 --- engine/gl/gl_model.c | 28 +++++++++++++++------- engine/server/server.h | 2 +- engine/server/sv_ents.c | 38 +++++++++++++++++++---------- engine/server/sv_main.c | 5 +++- engine/server/sv_phys.c | 20 +++++++++------- 9 files changed, 115 insertions(+), 44 deletions(-) diff --git a/engine/common/com_phys_ode.c b/engine/common/com_phys_ode.c index edc95d5a..8cbd3f0d 100644 --- a/engine/common/com_phys_ode.c +++ b/engine/common/com_phys_ode.c @@ -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) diff --git a/engine/common/common.c b/engine/common/common.c index 8d0b63e9..25223a04 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -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) diff --git a/engine/common/common.h b/engine/common/common.h index 744bda81..038a50b8 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -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); diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 5dec47fb..440097bf 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.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. diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 01670ecf..85e1eb6b 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -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 ; inumsurfaces ; i++) + { + Surf_BuildSurfaceDisplayList (mod, mod->surfaces + i); + } + */ + // // set up the submodels (FIXME: this is confusing) // diff --git a/engine/server/server.h b/engine/server/server.h index a32de821..2f553398 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -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; diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 34af88d3..285e4fa5 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -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<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<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; diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 203e08a7..9d5c5f98 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -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); diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 3b533548..d93af124 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -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;