saharan / OimoPhysics

A cross-platform 3D physics engine
MIT License
863 stars 68 forks source link

Stepping a single rigid body #17

Closed Smoozilla closed 2 years ago

Smoozilla commented 5 years ago

Hello!

Is it possible to step a single rigid body?

For example I have a dozen dynamic rigid bodies and a dozen static bodies, I would like to retain the velocity and position on all dynamic bodies while stepping and updating the position/velocities of a single rigid body x number of times.

Can I do this? I've considered sleeping all bodies except the one I want to update but I don't think that would retain the velocities?

Thanks!

Smoozilla commented 5 years ago

I've decided to just cache positions before hand and restore them after the fact, turns out I need the positions before anyways.

If there was a way to exclude specific rigid bodies in the step (for performance considerations) that would be ideal, though it is required for what I need.

I'll leave this open for comments in these regards.

Thank you!

saharan commented 5 years ago

Hello,

Some functions do that internally, but they're not public so you cannot access them. I think the best way to do that (at least in the current version) is to rotate and translate a rigid body manually.

Assume that dt is the time-step size, and rb is the target rigid body to step. To translate rb,

rb.translate(rb.getLinearVelocity().scale(dt));

and to rotate rb (a bit complicated though),

var av = rb.getAngularVelocity();
var theta = av.length() * dt; // rotation angle
if (theta > 0) { // avoid normalizing the zero vector
    av.normalize();
    var dR = new Mat3().appendRotationEq(theta, av.x, av.y, av.z);
    rb.rotate(dR);
}

Hope this helps! I leave this issue open so as not to forget to implement APIs for the future release.

Thanks,

saharan commented 2 years ago

I considered implementing this feature to the core library, but things look like go a lot more complicated than I expected (treatment of external forces, should constraints be ignored?, etc...) and I decided not. Instead, maybe I add a helper function that makes applying rotational vector to transform easier.