]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - world.c
if no varfunc is left, NULL it
[xonotic/darkplaces.git] / world.c
diff --git a/world.c b/world.c
index 43fc01ed94b511761e301c7873a7b297f00bf04b..fa1ccbc7e33da9b46756bd0de88b3cece73f46a1 100644 (file)
--- a/world.c
+++ b/world.c
@@ -351,7 +351,7 @@ cvar_t physics_ode_world_damping_angular = {0, "physics_ode_world_damping_angula
 cvar_t physics_ode_world_damping_angular_threshold = {0, "physics_ode_world_damping_angular_threshold", "0.01", "world angular damping threshold (see ODE User Guide); use defaults when set to -1"};
 cvar_t physics_ode_world_gravitymod = {0, "physics_ode_world_gravitymod", "1", "multiplies gravity got from sv_gravity, this may be needed to tweak if strong damping is used"};
 cvar_t physics_ode_iterationsperframe = {0, "physics_ode_iterationsperframe", "1", "divisor for time step, runs multiple physics steps per frame"};
-cvar_t physics_ode_constantstep = {0, "physics_ode_constantstep", "1", "use constant step instead of variable step which tends to increase stability, if set to 1 uses sys_ticrate, instead uses it's own value"};
+cvar_t physics_ode_constantstep = {0, "physics_ode_constantstep", "0", "use constant step instead of variable step which tends to increase stability, if set to 1 uses sys_ticrate, instead uses it's own value"};
 cvar_t physics_ode_autodisable = {0, "physics_ode_autodisable", "1", "automatic disabling of objects which dont move for long period of time, makes object stacking a lot faster"};
 cvar_t physics_ode_autodisable_steps = {0, "physics_ode_autodisable_steps", "10", "how many steps object should be dormant to be autodisabled"};
 cvar_t physics_ode_autodisable_time = {0, "physics_ode_autodisable_time", "0", "how many seconds object should be dormant to be autodisabled"};
@@ -2527,6 +2527,7 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
        float bouncestop1 = 60.0f / 800.0f;
        float bouncefactor2 = 0.0f;
        float bouncestop2 = 60.0f / 800.0f;
+       float erp;
        dVector3 grav;
        prvm_edict_t *ed1, *ed2;
 
@@ -2606,6 +2607,10 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
        dWorldGetGravity((dWorldID)world->physics.ode_world, grav);
        bouncestop1 *= fabs(grav[2]);
 
+       // get erp
+       // select object that moves faster ang get it's erp
+       erp = (VectorLength2(PRVM_gameedictvector(ed1, velocity)) > VectorLength2(PRVM_gameedictvector(ed2, velocity))) ? PRVM_gameedictfloat(ed1, erp) : PRVM_gameedictfloat(ed2, erp);
+
        // generate contact points between the two non-space geoms
        numcontacts = dCollide(o1, o2, MAX_CONTACTS, &(contact[0].geom), sizeof(contact[0]));
        // add these contact points to the simulation
@@ -2613,7 +2618,7 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
        {
                contact[i].surface.mode = (physics_ode_contact_mu.value != -1 ? dContactApprox1 : 0) | (physics_ode_contact_erp.value != -1 ? dContactSoftERP : 0) | (physics_ode_contact_cfm.value != -1 ? dContactSoftCFM : 0) | (bouncefactor1 > 0 ? dContactBounce : 0);
                contact[i].surface.mu = physics_ode_contact_mu.value * ed1->priv.server->ode_friction * ed2->priv.server->ode_friction;
-               contact[i].surface.soft_erp = physics_ode_contact_erp.value;
+               contact[i].surface.soft_erp = physics_ode_contact_erp.value + erp;
                contact[i].surface.soft_cfm = physics_ode_contact_cfm.value;
                contact[i].surface.bounce = bouncefactor1;
                contact[i].surface.bounce_vel = bouncestop1;
@@ -2672,8 +2677,10 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
                        collisiontime += (Sys_DirtyTime() - tdelta3)*10000;
 
                        // run physics (move objects, calculate new velocities)
+                       // be sure not to pass 0 as step time because that causes an ODE error
                        dWorldSetQuickStepNumIterations((dWorldID)world->physics.ode_world, bound(1, physics_ode_worldstep_iterations.integer, 200));
-                       dWorldQuickStep((dWorldID)world->physics.ode_world, world->physics.ode_step);
+                       if (world->physics.ode_step > 0)
+                               dWorldQuickStep((dWorldID)world->physics.ode_world, world->physics.ode_step);
 
                        // clear the JointGroup now that we're done with it
                        dJointGroupEmpty((dJointGroupID)world->physics.ode_contactgroup);