bepu / bepuphysics2

Pure C# 3D real time physics simulation library, now with a higher version number.
Apache License 2.0
2.25k stars 261 forks source link

Body always sleeping #259

Closed Not1anted closed 1 year ago

Not1anted commented 1 year ago

Hello! so I just started using this library and it is working fine but I noticed something after a while.. for somereason whenever my body stops moving compeletly it just goes to sleep yeah ofc, but it never starts moving again after it is sleeping.. even changing its position doesn't help it just floats in the air and other bodys just pass through it.

I copy pasted the simulation setup code from the demoCallBacks project and still nothing happened. I am not sure what is causing this.

here is a video : testtt.webm

RossNordby commented 1 year ago

BodyReference fields return a direct memory reference to things like the body's position. Modifying the position does not (and, since it's nothing but a direct memory access, cannot) make the body wake up.

Since the body never wakes up, the bounding box of the sleeping body is never updated, and the broad phase thinks the body is still at the old location. When the broad phase detects a pair with that old position, narrow phase tests are dispatched- but they look up the current position. Since the current position is somewhere else, the narrow phase finds no contacts, and so nothing happens.

While it's a bit odd, this is expected behavior for the low level API. It intentionally doesn't do anything else besides provide memory access. If you want to wake the body up, set bodyReference.Awake = true.

If you'd like to wake the body at the same time as a pose modification, one option would be to add extension methods like so:

public static class Extensions
{
    public static void SetPose(this BodyReference body, RigidPose pose)
    {
        body.Awake = true;
        body.Pose = pose;
        //Since this isn't a direct memory access, you could also throw in more validation.
        Debug.Assert(float.Abs(pose.Orientation.Length() - 1) < 1e-6f, "Orientation should be unit length.");
    }
}

Another option would be to force the bounding box of the sleeping body to be updated using bodyReference.UpdateBounds().

Not1anted commented 1 year ago

ok yeah I see thanks for the help!