stephengold / Libbulletjme

A JNI interface to Bullet Physics and V-HACD
https://stephengold.github.io/Libbulletjme/lbj-en/English/overview.html
Other
84 stars 10 forks source link

PhysicsCharacter.onGround() is unreliable #18

Closed stephengold closed 2 years ago

stephengold commented 2 years ago

I saw strange character behaviors while writing tutorials for LBJ. Most of the time PhysicsCharacter.onGround() returns the correct value, but occasionally it returns true when the character is unsupported.

This allows jumping to unlimited height in tests such as HelloWalk, TestPhysicsCharacter, and TestQ3. It might be related the character's vertical velocity being nearly zero.

stephengold commented 2 years ago

Interesting that the issue doesn't appear in HelloCharacter.

stephengold commented 2 years ago

It appears in HelloGhost, but not if I configure the character's gravity to 59.9 psu/sec2 instead of 60. And note that HelloCharacter uses the default gravity, which is 29.4 psu/sec2.

stephengold commented 2 years ago

Sure enough:

bool btKinematicCharacterController::onGround() const
{
    return (fabs(m_verticalVelocity) < SIMD_EPSILON) && (fabs(m_verticalOffset) < SIMD_EPSILON);
}
stephengold commented 2 years ago

btKinematicCharacterController is chock full of thoughtless hacks and copypasta. It could benefit greatly from a complete rewrite. But not today! The less I modify it, the happier I'll be. Ideally, I'd simply add an isOnGround() method to the jmeKcc subclass and invoke that in place of btKinematicCharacterController::onGround().

btKinematicCharacterController contains a few protected fields that seem relevant:

Of those 3 fields, m_wasJumping seems closest to providing the desired functionality. I've run a few tests, and it looks good.

stephengold commented 2 years ago

Okay, the fix is in Libbulletjme v14.5.0. In hindsight, I wish I'd made it return onGround() && !m_wasJumping;---less risk of a false positive that way.

stephengold commented 2 years ago

As written, TestPhysicsCharacter, TestQ3, and TestWalkingChar do not invoke onGround()---they permit jumping even when the character is airborne. In order to test this fix, those apps need minor modifications

stephengold commented 7 months ago

There's an issue with the current solution because it returns true after the character steps off the supporting surface. See the Forum discussion: https://hub.jmonkeyengine.org/t/linear-velocity-inconsistency-on-collisionlistener/47446/4