[ODE] ODE and geom scales

Megan Fox shalinor at gmail.com
Fri Dec 17 10:44:47 MST 2004


To simplify things a bit, hopefully, here's the code I ended up with
to keep the body floating.  I make no guarantees that this is
physically accurate or ideal, and it does result in the last half
meter or so of restoration taking awhile... but it does work.

repulsorHeight is the desired distance between ground and ray origin
(desired hover height)
collisionDepth is the current distance between ground and ray origin
(present height)
repulsorUpForce is the max force that can be applied towards altitude
adjustment.

(technically, this has a DownForce analog too, but it isn't relevant
to the discussion at hand - I only use the code for lifts)

Also note that this code is designed to work with an arbitrary vector
facing, not just "down".  And you can drop the equal-and-opposite
force application if you like, but I find this greatly increases the
"strength" of how the movement feels - you can actually wobble box
stacks when standing on them, that sort of thing.

if (sensorList->repulsorUpForce && (sensorList->collisionDepth <
sensorList->repulsorHeight))
{
    // Grab out the data for the sensor
    vector3 sensorPos, pushDir;
    sensorList->Get(sensorPos, pushDir);

    // Rotate the vector to be in world-space
    quaternion curOrientation = this->targetEntity->GetRot();
    pushDir = curOrientation.rotate(pushDir);

    // Flip the vector (sensors always point in the "down" direction,
we want the "up" direction)
    pushDir = -pushDir;

    // Grab the relevant portion of the current velocity
    vector3 curVelocity = nOpende::BodyGetLinearVel(this->tempBodyID);
    vector3 velDir = curVelocity;
    velDir.norm();
    float relevantVel = curVelocity.len() * (velDir.dot(pushDir));

    vector3 forceToApply;

    // Now apply whatever up-force is necessary to fix the height of
the repulsor to desired levels
    if (relevantVel < sensorList->repulsorUpForce *
(sensorList->repulsorHeight - sensorList->collisionDepth))
        forceToApply = pushDir * (sensorList->repulsorUpForce *
(sensorList->repulsorHeight - sensorList->collisionDepth) -
relevantVel) / deltaTime;
    else if (relevantVel < (sensorList->repulsorHeight -
sensorList->collisionDepth))
        forceToApply = pushDir * ((sensorList->repulsorHeight -
sensorList->collisionDepth) - relevantVel) / deltaTime;

    this->AddImpulseAtRelPos(forceToApply, sensorPos);

    // If the collided-with geom has a body, apply the equal and
opposite counter-force
    if (sensorList->collidedWith)
    {
        nOpende::BodyEnable(sensorList->collidedWith);
        nOpende::BodyAddForceAtPos(sensorList->collidedWith,
-forceToApply, sensorList->collisionPos);
    }
}

> I like the idea of the hovering CCylinder, but how does that work with
> gravity ?
> 
> If you apply a vertical force up to make the CCylinder hover, gravity
> will be disabled. Doesn't
> that lead to strange behaviors ?
> 
> F. Brebion
> 
> 
> Megan Fox wrote:
> 
> >The trouble I had with the stairs-as-ramps approach was that then,
> >boxes and ragdolls falling down the stairs were terribly inconsistent,
> >and even spheres looked a little strange.
> >
> >
> >Thus, I use "real" stairs and the hovering CCylinder.  However, do be
> >aware that this creates a very specific point of contact below the
> >feet - one minute you're standing on a ledge, the next you're sliding
> >off of it.
> >
> >I'm not yet decided on whether or not this is "ok", though a possible
> >solution would be to simply cast a few more rays in addition to the
> >central ray.  You could still, technically, have geometry that could
> >slip between the rays, but most games aren't going to have geometry
> >that small anyways.
> >
> >-Megan Fox
> >
> >
> _______________________________________________
> ODE mailing list
> ODE at q12.org
> http://q12.org/mailman/listinfo/ode
>


More information about the ODE mailing list