- dGeomSetBody(ed->priv.server->ode_geom, ed->priv.server->ode_body);
- dBodySetPosition(body, origin[0], origin[1], origin[2]);
- dBodySetRotation(body, r[0]);
- dBodySetLinearVel(body, velocity[0], velocity[1], velocity[2]);
- dBodySetAngularVel(body, spinvelocity[0], spinvelocity[1], spinvelocity[2]);
- dBodySetGravityMode(body, gravity);
- dBodySetData(body, (void*)ed);
- // setting body to NULL makes an immovable object
- if (movetype != MOVETYPE_PHYSICS)
- dGeomSetBody(ed->priv.server->ode_geom, 0);
+ if(body)
+ {
+ if(movetype == MOVETYPE_PHYSICS)
+ {
+ dGeomSetBody((dGeomID)ed->priv.server->ode_geom, body);
+ dBodySetPosition(body, origin[0], origin[1], origin[2]);
+ dBodySetRotation(body, r[0]);
+ dBodySetLinearVel(body, velocity[0], velocity[1], velocity[2]);
+ dBodySetAngularVel(body, spinvelocity[0], spinvelocity[1], spinvelocity[2]);
+ dBodySetGravityMode(body, gravity);
+ }
+ else
+ {
+ dGeomSetBody((dGeomID)ed->priv.server->ode_geom, body);
+ dBodySetPosition(body, origin[0], origin[1], origin[2]);
+ dBodySetRotation(body, r[0]);
+ dBodySetLinearVel(body, velocity[0], velocity[1], velocity[2]);
+ dBodySetAngularVel(body, spinvelocity[0], spinvelocity[1], spinvelocity[2]);
+ dBodySetGravityMode(body, gravity);
+ dGeomSetBody((dGeomID)ed->priv.server->ode_geom, 0);
+ }
+ }
+ else
+ {
+ // no body... then let's adjust the parameters of the geom directly
+ dGeomSetBody((dGeomID)ed->priv.server->ode_geom, 0); // just in case we previously HAD a body (which should never happen)
+ dGeomSetPosition((dGeomID)ed->priv.server->ode_geom, origin[0], origin[1], origin[2]);
+ dGeomSetRotation((dGeomID)ed->priv.server->ode_geom, r[0]);
+ }
+ }
+
+ if(body)
+ {
+
+ // limit movement speed to prevent missed collisions at high speed
+ ovelocity = dBodyGetLinearVel(body);
+ ospinvelocity = dBodyGetAngularVel(body);
+ movelimit = ed->priv.server->ode_movelimit * world->physics.ode_movelimit;
+ test = VectorLength2(ovelocity);
+ if (test > movelimit*movelimit)
+ {
+ // scale down linear velocity to the movelimit
+ // scale down angular velocity the same amount for consistency
+ f = movelimit / sqrt(test);
+ VectorScale(ovelocity, f, velocity);
+ VectorScale(ospinvelocity, f, spinvelocity);
+ dBodySetLinearVel(body, velocity[0], velocity[1], velocity[2]);
+ dBodySetAngularVel(body, spinvelocity[0], spinvelocity[1], spinvelocity[2]);
+ }
+
+ // make sure the angular velocity is not exploding
+ spinlimit = physics_ode_spinlimit.value;
+ test = VectorLength2(ospinvelocity);
+ if (test > spinlimit)
+ {
+ dBodySetAngularVel(body, 0, 0, 0);
+ }
+
+ // apply functions and clear stack
+ for(func = ed->priv.server->ode_func; func; func = nextf)
+ {
+ nextf = func->next;
+ World_Physics_ApplyCmd(ed, func);
+ Mem_Free(func);
+ }
+ ed->priv.server->ode_func = NULL;