// update the csqc's server timestamps, critical for proper sync
CSQC_UpdateNetworkTimes(cl.mtime[0], cl.mtime[1]);
+#ifdef USEODE
if (cl.mtime[0] > cl.mtime[1])
World_Physics_Frame(&cl.world, cl.mtime[0] - cl.mtime[1], cl.movevars_gravity);
+#endif
// only lerp entities that also get an update in this frame, when lerp excess is used
if(cl_lerpexcess.value > 0)
World_UnlinkEdict(ed);
memset(ed->fields.fp, 0, prog->entityfields * sizeof(prvm_vec_t));
VM_RemoveEdictSkeleton(prog, ed);
+#ifdef USEODE
World_Physics_RemoveFromEntity(&cl.world, ed);
World_Physics_RemoveJointFromEntity(&cl.world, ed);
+#endif
}
static void CLVM_count_edicts(prvm_prog_t *prog)
#this checks USEODE when compiling so it needs the ODE flags as well
+cl_parse.o: cl_parse.c
+ $(CHECKLEVEL2)
+ $(DO_CC) $(CFLAGS_ODE)
+
+cs_progs.o: cs_progs.c
+ $(CHECKLEVEL2)
+ $(DO_CC) $(CFLAGS_ODE)
+
+sv_main.o: sv_main.c
+ $(CHECKLEVEL2)
+ $(DO_CC) $(CFLAGS_ODE)
+
+sv_phys.o: sv_phys.c
+ $(CHECKLEVEL2)
+ $(DO_CC) $(CFLAGS_ODE)
+
prvm_cmds.o: prvm_cmds.c
$(CHECKLEVEL2)
$(DO_CC) $(CFLAGS_ODE)
#define ODEFUNC_FORCE 3
#define ODEFUNC_TORQUE 4
+#ifdef USEODE
typedef struct edict_odefunc_s
{
int type;
vec3_t v2;
struct edict_odefunc_s *next;
}edict_odefunc_t;
+#endif
typedef struct edict_engineprivate_s
{
frameblend_t frameblend[MAX_FRAMEBLENDS];
skeleton_t skeleton;
+#ifdef USEODE
// physics parameters
qbool ode_physics;
void *ode_body;
vec3_t ode_joint_velocity; // second joint axis
vec3_t ode_joint_movedir; // parameters
void *ode_massbuf;
+#endif
}
edict_engineprivate_t;
// physics builtins
//
+#ifdef USEODE
#define VM_physics_ApplyCmd(ed,f) if (!ed->priv.server->ode_body) VM_physics_newstackfunction(prog, ed, f); else World_Physics_ApplyCmd(ed, f)
static edict_odefunc_t *VM_physics_newstackfunction(prvm_prog_t *prog, prvm_edict_t *ed, edict_odefunc_t *f)
}
return newfunc;
}
+#endif
// void(entity e, float physics_enabled) physics_enable = #;
void VM_physics_enable(prvm_prog_t *prog)
{
+#ifdef USEODE
prvm_edict_t *ed;
edict_odefunc_t f;
-
+#endif
VM_SAFEPARMCOUNT(2, VM_physics_enable);
+#ifdef USEODE
ed = PRVM_G_EDICT(OFS_PARM0);
if (!ed)
{
}
f.type = PRVM_G_FLOAT(OFS_PARM1) == 0 ? ODEFUNC_DISABLE : ODEFUNC_ENABLE;
VM_physics_ApplyCmd(ed, &f);
+#endif
}
// void(entity e, vector force, vector relative_ofs) physics_addforce = #;
void VM_physics_addforce(prvm_prog_t *prog)
{
+#ifdef USEODE
prvm_edict_t *ed;
edict_odefunc_t f;
-
+#endif
VM_SAFEPARMCOUNT(3, VM_physics_addforce);
+#ifdef USEODE
ed = PRVM_G_EDICT(OFS_PARM0);
if (!ed)
{
VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f.v1);
VectorCopy(PRVM_G_VECTOR(OFS_PARM2), f.v2);
VM_physics_ApplyCmd(ed, &f);
+#endif
}
// void(entity e, vector torque) physics_addtorque = #;
void VM_physics_addtorque(prvm_prog_t *prog)
{
+#ifdef USEODE
prvm_edict_t *ed;
edict_odefunc_t f;
-
+#endif
VM_SAFEPARMCOUNT(2, VM_physics_addtorque);
+#ifdef USEODE
ed = PRVM_G_EDICT(OFS_PARM0);
if (!ed)
{
f.type = ODEFUNC_TORQUE;
VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f.v1);
VM_physics_ApplyCmd(ed, &f);
+#endif
}
extern cvar_t prvm_coverage;
PRVM_serveredictfloat(ed, solid) = 0;
VM_RemoveEdictSkeleton(prog, ed);
+#ifdef USEODE
World_Physics_RemoveFromEntity(&sv.world, ed);
World_Physics_RemoveJointFromEntity(&sv.world, ed);
-
+#endif
// make sure csqc networking is aware of the removed entity
e = PRVM_NUM_FOR_EDICT(ed);
sv.csqcentityversion[e] = 0;
PRVM_serverglobalfloat(frametime) = sv.frametime;
prog->ExecuteProgram(prog, PRVM_serverfunction(StartFrame), "QC function StartFrame is missing");
+#ifdef USEODE
// run physics engine
World_Physics_Frame(&sv.world, sv.frametime, sv_gravity.value);
+#endif
//
// treat each object in turn
*/
+#ifdef USEODE
static void World_Physics_Init(void);
+#endif
void World_Init(void)
{
Collision_Init();
+#ifdef USEODE
World_Physics_Init();
+#endif
}
+#ifdef USEODE
static void World_Physics_Shutdown(void);
+#endif
void World_Shutdown(void)
{
+#ifdef USEODE
World_Physics_Shutdown();
+#endif
}
+#ifdef USEODE
static void World_Physics_Start(world_t *world);
+#endif
void World_Start(world_t *world)
{
+#ifdef USEODE
World_Physics_Start(world);
+#endif
}
+#ifdef USEODE
static void World_Physics_End(world_t *world);
+#endif
void World_End(world_t *world)
{
+#ifdef USEODE
World_Physics_End(world);
+#endif
}
//============================================================================
// {"dGeomTriMeshDataUpdate", (void **) &dGeomTriMeshDataUpdate},
{NULL, NULL}
};
-
// Handle for ODE DLL
dllhandle_t ode_dll = NULL;
#endif
-#endif
static void World_Physics_Init(void)
{
-#ifdef USEODE
#ifndef LINK_TO_LIBODE
const char* dllnames [] =
{
}
#endif
}
-#endif
}
-
static void World_Physics_Shutdown(void)
{
-#ifdef USEODE
#ifndef LINK_TO_LIBODE
if (ode_dll)
#endif
ode_dll = NULL;
#endif
}
-#endif
}
-#ifdef USEODE
static void World_Physics_UpdateODE(world_t *world)
{
dWorldID odeworld;
World_Physics_UpdateODE(world);
}
-#endif
static void World_Physics_Start(world_t *world)
{
-#ifdef USEODE
if (world->physics.ode)
return;
World_Physics_EnableODE(world);
-#endif
}
static void World_Physics_End(world_t *world)
{
-#ifdef USEODE
if (world->physics.ode)
{
dWorldDestroy((dWorldID)world->physics.ode_world);
dJointGroupDestroy((dJointGroupID)world->physics.ode_contactgroup);
world->physics.ode = false;
}
-#endif
}
void World_Physics_RemoveJointFromEntity(world_t *world, prvm_edict_t *ed)
{
ed->priv.server->ode_joint_type = 0;
-#ifdef USEODE
if(ed->priv.server->ode_joint)
dJointDestroy((dJointID)ed->priv.server->ode_joint);
ed->priv.server->ode_joint = NULL;
-#endif
}
void World_Physics_RemoveFromEntity(world_t *world, prvm_edict_t *ed)
// entity is not physics controlled, free any physics data
ed->priv.server->ode_physics = false;
-#ifdef USEODE
if (ed->priv.server->ode_geom)
dGeomDestroy((dGeomID)ed->priv.server->ode_geom);
ed->priv.server->ode_geom = NULL;
dBodyDestroy((dBodyID)ed->priv.server->ode_body);
}
ed->priv.server->ode_body = NULL;
-#endif
if (ed->priv.server->ode_vertex3f)
Mem_Free(ed->priv.server->ode_vertex3f);
ed->priv.server->ode_vertex3f = NULL;
void World_Physics_ApplyCmd(prvm_edict_t *ed, edict_odefunc_t *f)
{
-#ifdef USEODE
dBodyID body = (dBodyID)ed->priv.server->ode_body;
switch(f->type)
default:
break;
}
-#endif
}
-#ifdef USEODE
static void World_Physics_Frame_BodyToEntity(world_t *world, prvm_edict_t *ed)
{
prvm_prog_t *prog = world->prog;
dJointAttach(c, b1, b2);
}
}
-#endif
void World_Physics_Frame(world_t *world, double frametime, double gravity)
{
-#ifdef USEODE
prvm_prog_t *prog = world->prog;
double tdelta, tdelta2, tdelta3, simulationtime, collisiontime;
}
}
}
-#endif
}
+#endif