Add: sweepTest to jme3-bullet-native

experimental
rainmantsr 10 years ago
parent 1076b489ab
commit 31835366b2
  1. 62
      jme3-bullet-native/src/native/cpp/com_jme3_bullet_PhysicsSpace.cpp
  2. 9
      jme3-bullet-native/src/native/cpp/com_jme3_bullet_PhysicsSpace.h
  3. 90
      jme3-bullet-native/src/native/cpp/jmeBulletUtil.cpp
  4. 3
      jme3-bullet-native/src/native/cpp/jmeBulletUtil.h
  5. 79
      jme3-bullet-native/src/native/cpp/jmeClasses.cpp
  6. 12
      jme3-bullet-native/src/native/cpp/jmeClasses.h
  7. 59
      jme3-bullet/src/main/java/com/jme3/bullet/PhysicsSpace.java

@ -468,6 +468,68 @@ extern "C" {
return; return;
} }
JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_sweepTest_1native
(JNIEnv * env, jobject object, jlong shapeId, jobject from, jobject to, jlong spaceId, jobject resultlist, jfloat allowedCcdPenetration) {
jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*> (spaceId);
if (space == NULL) {
jclass newExc = env->FindClass("java/lang/NullPointerException");
env->ThrowNew(newExc, "The physics space does not exist.");
return;
}
btCollisionShape* shape = reinterpret_cast<btCollisionShape*> (shapeId);
if (shape == NULL) {
jclass newExc = env->FindClass("java/lang/NullPointerException");
env->ThrowNew(newExc, "The shape does not exist.");
return;
}
struct AllConvexResultCallback : public btCollisionWorld::ConvexResultCallback {
AllConvexResultCallback(const btTransform& convexFromWorld, const btTransform & convexToWorld) : m_convexFromWorld(convexFromWorld), m_convexToWorld(convexToWorld) {
}
jobject resultlist;
JNIEnv* env;
btTransform m_convexFromWorld; //used to calculate hitPointWorld from hitFraction
btTransform m_convexToWorld;
btVector3 m_hitNormalWorld;
btVector3 m_hitPointWorld;
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace) {
if (normalInWorldSpace) {
m_hitNormalWorld = convexResult.m_hitNormalLocal;
}
else {
m_hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis() * convexResult.m_hitNormalLocal;
}
m_hitPointWorld.setInterpolate3(m_convexFromWorld.getBasis() * m_convexFromWorld.getOrigin(), m_convexToWorld.getBasis() * m_convexToWorld.getOrigin(), convexResult.m_hitFraction);
jmeBulletUtil::addSweepResult(env, resultlist, &m_hitNormalWorld, &m_hitPointWorld, convexResult.m_hitFraction, convexResult.m_hitCollisionObject);
return 1.f;
}
};
btTransform native_to = btTransform();
jmeBulletUtil::convert(env, to, &native_to);
btTransform native_from = btTransform();
jmeBulletUtil::convert(env, from, &native_from);
btScalar native_allowed_ccd_penetration = btScalar(allowedCcdPenetration);
AllConvexResultCallback resultCallback(native_from, native_to);
resultCallback.env = env;
resultCallback.resultlist = resultlist;
space->getDynamicsWorld()->convexSweepTest((btConvexShape *) shape, native_from, native_to, resultCallback, native_allowed_ccd_penetration);
return;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -165,6 +165,15 @@ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_initNativePhysics
JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_finalizeNative JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_finalizeNative
(JNIEnv *, jobject, jlong); (JNIEnv *, jobject, jlong);
/*
* Class: com_jme3_bullet_PhysicsSpace
* Method : sweepTest_native
* Signature: (J;L;Lcom/jme3/math/Transform;Lcom/jme3/math/Transform;L;JLjava/util/List;F)V
*/
JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_sweepTest_1native
(JNIEnv *, jobject, jlong, jobject, jobject, jlong, jobject, jfloat);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -59,6 +59,38 @@ void jmeBulletUtil::convert(JNIEnv* env, jobject in, btVector3* out) {
out->setZ(z); out->setZ(z);
} }
void jmeBulletUtil::convert(JNIEnv* env, jobject in, btQuaternion* out) {
if (in == NULL || out == NULL) {
jmeClasses::throwNPE(env);
}
float x = env->GetFloatField(in, jmeClasses::Quaternion_x);
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
float y = env->GetFloatField(in, jmeClasses::Quaternion_y); //env->CallFloatMethod(in, jmeClasses::Vector3f_getY);
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
float z = env->GetFloatField(in, jmeClasses::Quaternion_z); //env->CallFloatMethod(in, jmeClasses::Vector3f_getZ);
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
float w = env->GetFloatField(in, jmeClasses::Quaternion_w); //env->CallFloatMethod(in, jmeClasses::Vector3f_getZ);
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
out->setX(x);
out->setY(y);
out->setZ(z);
out->setW(w);
}
void jmeBulletUtil::convert(JNIEnv* env, const btVector3* in, jobject out) { void jmeBulletUtil::convert(JNIEnv* env, const btVector3* in, jobject out) {
if (in == NULL || out == NULL) { if (in == NULL || out == NULL) {
jmeClasses::throwNPE(env); jmeClasses::throwNPE(env);
@ -325,3 +357,61 @@ void jmeBulletUtil::addResult(JNIEnv* env, jobject resultlist, btVector3* hitnor
return; return;
} }
} }
void jmeBulletUtil::addSweepResult(JNIEnv* env, jobject resultlist, btVector3* hitnormal, btVector3* m_hitPointWorld, btScalar m_hitFraction, const btCollisionObject* hitobject) {
jobject singleresult = env->AllocObject(jmeClasses::PhysicsSweep_Class);
jobject hitnormalvec = env->AllocObject(jmeClasses::Vector3f);
convert(env, hitnormal, hitnormalvec);
jmeUserPointer *up1 = (jmeUserPointer*)hitobject->getUserPointer();
env->SetObjectField(singleresult, jmeClasses::PhysicsSweep_normalInWorldSpace, hitnormalvec);
env->SetFloatField(singleresult, jmeClasses::PhysicsSweep_hitfraction, m_hitFraction);
env->SetObjectField(singleresult, jmeClasses::PhysicsSweep_collisionObject, up1->javaCollisionObject);
env->CallVoidMethod(resultlist, jmeClasses::PhysicsSweep_addmethod, singleresult);
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
}
void jmeBulletUtil::convert(JNIEnv* env, jobject in, btTransform* out) {
if (in == NULL || out == NULL) {
jmeClasses::throwNPE(env);
}
jobject translation_vec = env->CallObjectMethod(in, jmeClasses::Transform_translation);
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
jobject rot_quat = env->CallObjectMethod(in, jmeClasses::Transform_rotation);
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
/*
//Scale currently not supported by bullet
//@TBD: Create an assertion somewhere to avoid scale values
jobject scale_vec = env->GetObjectField(in, jmeClasses::Transform_scale);
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
*/
btVector3 native_translation_vec = btVector3();
//btVector3 native_scale_vec = btVector3();
btQuaternion native_rot_quat = btQuaternion();
convert(env, translation_vec, &native_translation_vec);
//convert(env, scale_vec, native_scale_vec);
convert(env, rot_quat, &native_rot_quat);
out->setRotation(native_rot_quat);
out->setOrigin(native_translation_vec);
}

@ -42,10 +42,13 @@ public:
static void convert(JNIEnv* env, jobject in, btVector3* out); static void convert(JNIEnv* env, jobject in, btVector3* out);
static void convert(JNIEnv* env, const btVector3* in, jobject out); static void convert(JNIEnv* env, const btVector3* in, jobject out);
static void convert(JNIEnv* env, jobject in, btMatrix3x3* out); static void convert(JNIEnv* env, jobject in, btMatrix3x3* out);
static void convert(JNIEnv* env, jobject in, btQuaternion* out);
static void convert(JNIEnv* env, const btMatrix3x3* in, jobject out); static void convert(JNIEnv* env, const btMatrix3x3* in, jobject out);
static void convertQuat(JNIEnv* env, jobject in, btMatrix3x3* out); static void convertQuat(JNIEnv* env, jobject in, btMatrix3x3* out);
static void convertQuat(JNIEnv* env, const btMatrix3x3* in, jobject out); static void convertQuat(JNIEnv* env, const btMatrix3x3* in, jobject out);
static void convert(JNIEnv* env, jobject in, btTransform* out);
static void addResult(JNIEnv* env, jobject resultlist, btVector3* hitnormal, btVector3* m_hitPointWorld,const btScalar m_hitFraction,const btCollisionObject* hitobject); static void addResult(JNIEnv* env, jobject resultlist, btVector3* hitnormal, btVector3* m_hitPointWorld,const btScalar m_hitFraction,const btCollisionObject* hitobject);
static void addSweepResult(JNIEnv* env, jobject resultlist, btVector3* hitnormal, btVector3* m_hitPointWorld, const btScalar m_hitFraction, const btCollisionObject* hitobject);
private: private:
jmeBulletUtil(){}; jmeBulletUtil(){};
~jmeBulletUtil(){}; ~jmeBulletUtil(){};

@ -91,6 +91,21 @@ jfieldID jmeClasses::PhysicsRay_collisionObject;
jclass jmeClasses::PhysicsRay_listresult; jclass jmeClasses::PhysicsRay_listresult;
jmethodID jmeClasses::PhysicsRay_addmethod; jmethodID jmeClasses::PhysicsRay_addmethod;
jclass jmeClasses::PhysicsSweep_Class;
jmethodID jmeClasses::PhysicsSweep_newSingleResult;
jfieldID jmeClasses::PhysicsSweep_normalInWorldSpace;
jfieldID jmeClasses::PhysicsSweep_hitfraction;
jfieldID jmeClasses::PhysicsSweep_collisionObject;
jclass jmeClasses::PhysicsSweep_listresult;
jmethodID jmeClasses::PhysicsSweep_addmethod;
jclass jmeClasses::Transform;
jmethodID jmeClasses::Transform_rotation;
jmethodID jmeClasses::Transform_translation;
//private fields //private fields
//JNIEnv* jmeClasses::env; //JNIEnv* jmeClasses::env;
JavaVM* jmeClasses::vm; JavaVM* jmeClasses::vm;
@ -240,6 +255,70 @@ void jmeClasses::initJavaClasses(JNIEnv* env) {
env->Throw(env->ExceptionOccurred()); env->Throw(env->ExceptionOccurred());
return; return;
} }
PhysicsSweep_Class = (jclass)env->NewGlobalRef(env->FindClass("com/jme3/bullet/collision/PhysicsSweepTestResult"));
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
PhysicsSweep_newSingleResult = env->GetMethodID(PhysicsSweep_Class, "<init>", "()V");
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
PhysicsSweep_normalInWorldSpace = env->GetFieldID(PhysicsSweep_Class, "hitNormalLocal", "Lcom/jme3/math/Vector3f;");
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
PhysicsSweep_hitfraction = env->GetFieldID(PhysicsSweep_Class, "hitFraction", "F");
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
PhysicsSweep_collisionObject = env->GetFieldID(PhysicsSweep_Class, "collisionObject", "Lcom/jme3/bullet/collision/PhysicsCollisionObject;");
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
PhysicsSweep_listresult = env->FindClass("java/util/List");
PhysicsSweep_listresult = (jclass)env->NewGlobalRef(PhysicsSweep_listresult);
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
PhysicsSweep_addmethod = env->GetMethodID(PhysicsSweep_listresult, "add", "(Ljava/lang/Object;)Z");
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
Transform = (jclass)env->NewGlobalRef(env->FindClass("com/jme3/math/Transform"));
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
Transform_rotation = env->GetMethodID(Transform, "getRotation", "()Lcom/jme3/math/Quaternion;");
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
Transform_translation = env->GetMethodID(Transform, "getTranslation", "()Lcom/jme3/math/Vector3f;");
if (env->ExceptionCheck()) {
env->Throw(env->ExceptionOccurred());
return;
}
} }
void jmeClasses::throwNPE(JNIEnv* env) { void jmeClasses::throwNPE(JNIEnv* env) {

@ -89,6 +89,18 @@ public:
static jclass PhysicsRay_listresult; static jclass PhysicsRay_listresult;
static jmethodID PhysicsRay_addmethod; static jmethodID PhysicsRay_addmethod;
static jclass PhysicsSweep_Class;
static jmethodID PhysicsSweep_newSingleResult;
static jfieldID PhysicsSweep_normalInWorldSpace;
static jfieldID PhysicsSweep_hitfraction;
static jfieldID PhysicsSweep_collisionObject;
static jclass PhysicsSweep_listresult;
static jmethodID PhysicsSweep_addmethod;
static jclass Transform;
static jmethodID Transform_rotation;
static jmethodID Transform_translation;
static jclass DebugMeshCallback; static jclass DebugMeshCallback;
static jmethodID DebugMeshCallback_addVector; static jmethodID DebugMeshCallback_addVector;

@ -820,6 +820,10 @@ public class PhysicsSpace {
// return lrr.hitFraction; // return lrr.hitFraction;
// } // }
// } // }
//
//
/** /**
* Performs a sweep collision test and returns the results as a list of * Performs a sweep collision test and returns the results as a list of
* PhysicsSweepTestResults<br/> You have to use different Transforms for * PhysicsSweepTestResults<br/> You have to use different Transforms for
@ -828,16 +832,16 @@ public class PhysicsSpace {
* center. * center.
*/ */
public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end) { public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end) {
List<PhysicsSweepTestResult> results = new LinkedList<PhysicsSweepTestResult>(); List results = new LinkedList();
// if (!(shape.getCShape() instanceof ConvexShape)) { sweepTest(shape, start, end , results);
// logger.log(Level.WARNING, "Trying to sweep test with incompatible mesh shape!"); return (List<PhysicsSweepTestResult>) results;
// return results; }
// }
// dynamicsWorld.convexSweepTest((ConvexShape) shape.getCShape(), Converter.convert(start, sweepTrans1), Converter.convert(end, sweepTrans2), new InternalSweepListener(results));
return results;
public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end, List<PhysicsSweepTestResult> results) {
return sweepTest(shape, start, end, results, 0.0f);
} }
public native void sweepTest_native(long shape, Transform from, Transform to, long physicsSpaceId, List<PhysicsSweepTestResult> results, float allowedCcdPenetration);
/** /**
* Performs a sweep collision test and returns the results as a list of * Performs a sweep collision test and returns the results as a list of
* PhysicsSweepTestResults<br/> You have to use different Transforms for * PhysicsSweepTestResults<br/> You have to use different Transforms for
@ -845,31 +849,30 @@ public class PhysicsSpace {
* collision if it starts INSIDE an object and is moving AWAY from its * collision if it starts INSIDE an object and is moving AWAY from its
* center. * center.
*/ */
public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end, List<PhysicsSweepTestResult> results) { public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end, List<PhysicsSweepTestResult> results, float allowedCcdPenetration ) {
results.clear(); results.clear();
// if (!(shape.getCShape() instanceof ConvexShape)) { sweepTest_native(shape.getObjectId(), start, end, physicsSpaceId, results, allowedCcdPenetration);
// logger.log(Level.WARNING, "Trying to sweep test with incompatible mesh shape!");
// return results;
// }
// dynamicsWorld.convexSweepTest((ConvexShape) shape.getCShape(), Converter.convert(start, sweepTrans1), Converter.convert(end, sweepTrans2), new InternalSweepListener(results));
return results; return results;
} }
// private class InternalSweepListener extends CollisionWorld.ConvexResultCallback { /* private class InternalSweepListener extends CollisionWorld.ConvexResultCallback {
//
// private List<PhysicsSweepTestResult> results; private List<PhysicsSweepTestResult> results;
//
// public InternalSweepListener(List<PhysicsSweepTestResult> results) { public InternalSweepListener(List<PhysicsSweepTestResult> results) {
// this.results = results; this.results = results;
// } }
//
// @Override @Override
// public float addSingleResult(LocalConvexResult lcr, boolean bln) { public float addSingleResult(LocalConvexResult lcr, boolean bln) {
// PhysicsCollisionObject obj = (PhysicsCollisionObject) lcr.hitCollisionObject.getUserPointer(); PhysicsCollisionObject obj = (PhysicsCollisionObject) lcr.hitCollisionObject.getUserPointer();
// results.add(new PhysicsSweepTestResult(obj, Converter.convert(lcr.hitNormalLocal), lcr.hitFraction, bln)); results.add(new PhysicsSweepTestResult(obj, Converter.convert(lcr.hitNormalLocal), lcr.hitFraction, bln));
// return lcr.hitFraction; return lcr.hitFraction;
// } }
// } }
*/
/** /**
* destroys the current PhysicsSpace so that a new one can be created * destroys the current PhysicsSpace so that a new one can be created
*/ */

Loading…
Cancel
Save