Skip to content

Commit

Permalink
allow zero-mass kinematic rigid bodies
Browse files Browse the repository at this point in the history
  • Loading branch information
stephengold committed May 18, 2023
1 parent 13a42bb commit 58f3c53
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 26 deletions.
26 changes: 7 additions & 19 deletions src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java
Original file line number Diff line number Diff line change
Expand Up @@ -620,9 +620,7 @@ assert getInternalType(objectId) == PcoType.rigid :
}
}

if (mass != massForStatic) {
setKinematic(kinematic);
}
setKinematic(kinematic);

postRebuild();

Expand Down Expand Up @@ -836,12 +834,6 @@ public void setInverseInertiaLocal(Vector3f inverseInertia) {
* (default=false)
*/
public void setKinematic(boolean kinematic) {
if (mass == massForStatic) {
throw new IllegalStateException(
"Cannot set/clear kinematic mode on a static body!");
}
assert !isStatic();

this.kinematic = kinematic;
long objectId = nativeId();
setKinematic(objectId, kinematic);
Expand Down Expand Up @@ -1101,7 +1093,7 @@ public Vector3f totalAppliedTorque(Vector3f storeResult) {
*/
protected void postRebuild() {
int flags = collisionFlags();
if (mass == massForStatic) {
if (mass == massForStatic && !kinematic) {
flags |= CollisionFlag.STATIC_OBJECT;
} else {
flags &= ~CollisionFlag.STATIC_OBJECT;
Expand Down Expand Up @@ -1178,17 +1170,17 @@ public void setGravity(Vector3f acceleration) {
}

/**
* Alter this body's mass. Bodies with mass=0 are static. For dynamic
* bodies, it is best to keep the mass on the order of 1.
* Alter this body's mass. Static bodies have mass=0. For dynamic bodies, it
* is best to keep the mass on the order of 1.
*
* @param mass the desired mass (>0) or 0 for a static body (default=1)
* @param mass the desired mass (≥0, default=1)
*/
@Override
public void setMass(float mass) {
Validate.nonNegative(mass, "mass");
CollisionShape shape = getCollisionShape();
assert shape != null;
if (mass != massForStatic) {
if (mass > massForStatic && !kinematic) {
validateDynamicShape(shape);
}
assert hasAssignedNativeObject();
Expand All @@ -1208,7 +1200,7 @@ public void setMass(float mass) {
updateMassProps(objectId, shape.nativeId(), mass);

int flags = collisionFlags();
if (mass == massForStatic) {
if (mass == massForStatic && !kinematic) {
flags |= CollisionFlag.STATIC_OBJECT;
} else {
flags &= ~CollisionFlag.STATIC_OBJECT;
Expand Down Expand Up @@ -1238,10 +1230,6 @@ public void setPhysicsLocation(Vector3f location) {
* @return true if the flags are equal, otherwise false
*/
private boolean checkKinematicFlag() {
if (mass == massForStatic) {
return true; // TODO
}

int flags = collisionFlags();
boolean nativeKinematicFlag
= (flags & CollisionFlag.KINEMATIC_OBJECT) != 0x0;
Expand Down
22 changes: 15 additions & 7 deletions src/main/native/glue/com_jme3_bullet_objects_PhysicsRigidBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,21 +663,29 @@ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setKinemati
btRigidBody * const pBody = reinterpret_cast<btRigidBody *> (bodyId);
NULL_CHK(pEnv, pBody, "The btRigidBody does not exist.",);
ASSERT_CHK(pEnv, pBody->getInternalType() & btCollisionObject::CO_RIGID_BODY,);
ASSERT_CHK(pEnv, !pBody->isStaticObject(),);

int flags = pBody->getCollisionFlags();
bool oldValue = pBody->isKinematicObject();

if (value && !oldValue) { // dynamic -> kinematic
flags = flags | btCollisionObject::CF_KINEMATIC_OBJECT;
if (value && !oldValue) { // dynamic/static -> kinematic
flags &= ~btCollisionObject::CF_STATIC_OBJECT;
flags |= btCollisionObject::CF_KINEMATIC_OBJECT;
pBody->setCollisionFlags(flags);

pBody->setActivationState(DISABLE_DEACTIVATION);

} else if (oldValue && !value) { // kinematic -> dynamic
flags = flags & ~btCollisionObject::CF_KINEMATIC_OBJECT;
} else if (oldValue && !value) { // kinematic -> dynamic/static
bool zeroMass = (pBody->getMass() == btScalar(0.0));
if (zeroMass) {
flags |= btCollisionObject::CF_STATIC_OBJECT;
}
flags &= ~btCollisionObject::CF_KINEMATIC_OBJECT;
pBody->setCollisionFlags(flags);
pBody->activate(true);
pBody->forceActivationState(ACTIVE_TAG);

if (!zeroMass) {
pBody->activate(true);
pBody->forceActivationState(ACTIVE_TAG);
}
}
}

Expand Down

0 comments on commit 58f3c53

Please sign in to comment.