From cf33c3c2dd4fcf3ae29da29715703814d3778679 Mon Sep 17 00:00:00 2001 From: Stephen Gold Date: Sat, 8 Dec 2018 00:07:44 -0800 Subject: [PATCH] implement setContactResponse(boolean) for PhysicsRigidBody (issue #964) (#966) partial --- ...ullet_collision_PhysicsCollisionObject.cpp | 38 +++++++- .../jme3/bullet/control/RigidBodyControl.java | 1 + .../jme3/bullet/control/VehicleControl.java | 1 + .../jme3/bullet/collision/CollisionFlag.java | 87 +++++++++++++++++++ .../collision/PhysicsCollisionObject.java | 29 +++++++ .../jme3/bullet/objects/PhysicsRigidBody.java | 26 ++++++ .../jme3/bullet/objects/PhysicsRigidBody.java | 23 ++++- 7 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 jme3-bullet/src/main/java/com/jme3/bullet/collision/CollisionFlag.java diff --git a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_collision_PhysicsCollisionObject.cpp b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_collision_PhysicsCollisionObject.cpp index e3852c76a..0c7f0161a 100644 --- a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_collision_PhysicsCollisionObject.cpp +++ b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_collision_PhysicsCollisionObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2018 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -143,6 +143,42 @@ extern "C" { } } + /* + * Class: com_jme3_bullet_collision_PhysicsCollisionObject + * Method: getCollisionFlags + * Signature: (J)I + */ + JNIEXPORT jint JNICALL Java_com_jme3_bullet_collision_PhysicsCollisionObject_getCollisionFlags + (JNIEnv *env, jobject object, jlong objectId) { + btCollisionObject* collisionObject = reinterpret_cast (objectId); + if (collisionObject == NULL) { + jclass newExc = env->FindClass("java/lang/NullPointerException"); + env->ThrowNew(newExc, "The native object does not exist."); + return 0; + } + + jint result = collisionObject->getCollisionFlags(); + return result; + } + + /* + * Class: com_jme3_bullet_collision_PhysicsCollisionObject + * Method: setCollisionFlags + * Signature: (JI)V + */ + JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_PhysicsCollisionObject_setCollisionFlags + (JNIEnv *env, jobject object, jlong objectId, jint desiredFlags) { + btCollisionObject* collisionObject = reinterpret_cast (objectId); + if (collisionObject == NULL) { + jclass newExc = env->FindClass("java/lang/NullPointerException"); + env->ThrowNew(newExc, "The native object does not exist."); + return; + } + + collisionObject->setCollisionFlags(desiredFlags); + } + + #ifdef __cplusplus } #endif diff --git a/jme3-bullet/src/common/java/com/jme3/bullet/control/RigidBodyControl.java b/jme3-bullet/src/common/java/com/jme3/bullet/control/RigidBodyControl.java index 6b8714da8..4094ab4db 100644 --- a/jme3-bullet/src/common/java/com/jme3/bullet/control/RigidBodyControl.java +++ b/jme3-bullet/src/common/java/com/jme3/bullet/control/RigidBodyControl.java @@ -150,6 +150,7 @@ public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl control.setCcdSweptSphereRadius(getCcdSweptSphereRadius()); control.setCollideWithGroups(getCollideWithGroups()); control.setCollisionGroup(getCollisionGroup()); + control.setContactResponse(isContactResponse()); control.setDamping(getLinearDamping(), getAngularDamping()); control.setFriction(getFriction()); control.setGravity(getGravity()); diff --git a/jme3-bullet/src/common/java/com/jme3/bullet/control/VehicleControl.java b/jme3-bullet/src/common/java/com/jme3/bullet/control/VehicleControl.java index ccc90091a..51210c6a7 100644 --- a/jme3-bullet/src/common/java/com/jme3/bullet/control/VehicleControl.java +++ b/jme3-bullet/src/common/java/com/jme3/bullet/control/VehicleControl.java @@ -168,6 +168,7 @@ public class VehicleControl extends PhysicsVehicle implements PhysicsControl, Jm control.setCcdSweptSphereRadius(getCcdSweptSphereRadius()); control.setCollideWithGroups(getCollideWithGroups()); control.setCollisionGroup(getCollisionGroup()); + control.setContactResponse(isContactResponse()); control.setDamping(getLinearDamping(), getAngularDamping()); control.setFriction(getFriction()); control.setGravity(getGravity()); diff --git a/jme3-bullet/src/main/java/com/jme3/bullet/collision/CollisionFlag.java b/jme3-bullet/src/main/java/com/jme3/bullet/collision/CollisionFlag.java new file mode 100644 index 000000000..6445af53f --- /dev/null +++ b/jme3-bullet/src/main/java/com/jme3/bullet/collision/CollisionFlag.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2018 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.bullet.collision; + +/** + * Named collision flags for a {@link PhysicsCollisionObject}. Values must agree + * with those in BulletCollision/CollisionDispatch/btCollisionObject.h + * + * @author Stephen Gold sgold@sonic.net + * @see PhysicsCollisionObject#getCollisionFlags(long) + */ +public class CollisionFlag { + /** + * flag for a static object + */ + final public static int STATIC_OBJECT = 0x1; + /** + * flag for a kinematic object + */ + final public static int KINEMATIC_OBJECT = 0x2; + /** + * flag for an object with no contact response, such as a PhysicsGhostObject + */ + final public static int NO_CONTACT_RESPONSE = 0x4; + /** + * flag to enable a custom material callback for per-triangle + * friction/restitution (not used by JME) + */ + final public static int CUSTOM_MATERIAL_CALLBACK = 0x8; + /** + * flag for a character object, such as a PhysicsCharacter + */ + final public static int CHARACTER_OBJECT = 0x10; + /** + * flag to disable debug visualization (not used by JME) + */ + final public static int DISABLE_VISUALIZE_OBJECT = 0x20; + /** + * flag to disable parallel/SPU processing (not used by JME) + */ + final public static int DISABLE_SPU_COLLISION_PROCESSING = 0x40; + /** + * flag not used by JME + */ + final public static int HAS_CONTACT_STIFFNESS_DAMPING = 0x80; + /** + * flag not used by JME + */ + final public static int HAS_CUSTOM_DEBUG_RENDERING_COLOR = 0x100; + /** + * flag not used by JME + */ + final public static int HAS_FRICTION_ANCHOR = 0x200; + /** + * flag not used by JME + */ + final public static int HAS_COLLISION_SOUND_TRIGGER = 0x400; +} diff --git a/jme3-bullet/src/main/java/com/jme3/bullet/collision/PhysicsCollisionObject.java b/jme3-bullet/src/main/java/com/jme3/bullet/collision/PhysicsCollisionObject.java index 443433623..ea8ced87c 100644 --- a/jme3-bullet/src/main/java/com/jme3/bullet/collision/PhysicsCollisionObject.java +++ b/jme3-bullet/src/main/java/com/jme3/bullet/collision/PhysicsCollisionObject.java @@ -254,6 +254,17 @@ public abstract class PhysicsCollisionObject implements Savable { return userObject; } + /** + * Test whether this object responds to contact with other objects. + * + * @return true if responsive, otherwise false + */ + public boolean isContactResponse() { + int flags = getCollisionFlags(objectId); + boolean result = (flags & CollisionFlag.NO_CONTACT_RESPONSE) == 0x0; + return result; + } + /** * Associate a user object (such as a Spatial) with this collision object. * @@ -314,6 +325,24 @@ public abstract class PhysicsCollisionObject implements Savable { collisionShape = shape; } + /** + * Read the collision flags of this object. Subclasses are responsible for + * cloning/reading/writing these flags. + * + * @param objectId the ID of the btCollisionObject (not zero) + * @return the collision flags (bit mask) + */ + native protected int getCollisionFlags(long objectId); + + /** + * Alter the collision flags of this object. Subclasses are responsible for + * cloning/reading/writing these flags. + * + * @param objectId the ID of the btCollisionObject (not zero) + * @param desiredFlags the desired collision flags (bit mask) + */ + native protected void setCollisionFlags(long objectId, int desiredFlags); + /** * Finalize this collision object just before it is destroyed. Should be * invoked only by a subclass or by the garbage collector. diff --git a/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java b/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java index 303060fe3..513187658 100644 --- a/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java +++ b/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java @@ -32,6 +32,7 @@ package com.jme3.bullet.objects; import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.CollisionFlag; import com.jme3.bullet.collision.PhysicsCollisionObject; import com.jme3.bullet.collision.shapes.CollisionShape; import com.jme3.bullet.collision.shapes.MeshCollisionShape; @@ -57,6 +58,11 @@ import java.util.logging.Logger; */ public class PhysicsRigidBody extends PhysicsCollisionObject { + /** + * copy of the contact response state: true→responds to contacts, + * false→doesn't respond (default=true) + */ + private boolean contactResponseState = true; /** * motion state */ @@ -370,6 +376,24 @@ public class PhysicsRigidBody extends PhysicsCollisionObject { return kinematic; } + /** + * Enable/disable this body's contact response. + * + * @param responsive true to respond to contacts, false to ignore them + * (default=true) + */ + public void setContactResponse(boolean responsive) { + int flags = getCollisionFlags(objectId); + if (responsive) { + flags &= ~CollisionFlag.NO_CONTACT_RESPONSE; + } else { + flags |= CollisionFlag.NO_CONTACT_RESPONSE; + } + setCollisionFlags(objectId, flags); + + contactResponseState = responsive; + } + /** * Alter the radius of the swept sphere used for continuous collision * detection (CCD). @@ -993,6 +1017,7 @@ public class PhysicsRigidBody extends PhysicsCollisionObject { capsule.write(getMass(), "mass", 1.0f); capsule.write(getGravity(), "gravity", Vector3f.ZERO); + capsule.write(isContactResponse(), "contactResponse", true); capsule.write(getFriction(), "friction", 0.5f); capsule.write(getRestitution(), "restitution", 0); Vector3f angularFactor = getAngularFactor(null); @@ -1033,6 +1058,7 @@ public class PhysicsRigidBody extends PhysicsCollisionObject { this.mass = mass; rebuildRigidBody(); setGravity((Vector3f) capsule.readSavable("gravity", Vector3f.ZERO.clone())); + setContactResponse(capsule.readBoolean("contactResponse", true)); setFriction(capsule.readFloat("friction", 0.5f)); setKinematic(capsule.readBoolean("kinematic", false)); diff --git a/jme3-jbullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java b/jme3-jbullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java index 6798c63fd..e6ebeecd8 100644 --- a/jme3-jbullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java +++ b/jme3-jbullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2018 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -276,6 +276,26 @@ public class PhysicsRigidBody extends PhysicsCollisionObject { return kinematic; } + /** + * Enable/disable this body's contact response. + * + * @param newState true to respond to contacts (default=true) + */ + public void setContactResponse(boolean newState) { + if (!newState) { + throw new UnsupportedOperationException("Not implemented."); + } + } + + /** + * Test whether this body responds to contacts. + * + * @return true if responsive, otherwise false + */ + public boolean isContactResponse() { + return true; + } + public void setCcdSweptSphereRadius(float radius) { rBody.setCcdSweptSphereRadius(radius); } @@ -650,6 +670,7 @@ public class PhysicsRigidBody extends PhysicsCollisionObject { this.mass = mass; rebuildRigidBody(); setGravity((Vector3f) capsule.readSavable("gravity", Vector3f.ZERO.clone())); + setContactResponse(capsule.readBoolean("contactResponse", true)); setFriction(capsule.readFloat("friction", 0.5f)); setKinematic(capsule.readBoolean("kinematic", false));