Add: sweepTest to jme3-bullet-native
This commit is contained in:
parent
1076b489ab
commit
31835366b2
@ -468,6 +468,68 @@ extern "C" {
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
@ -165,6 +165,15 @@ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_initNativePhysics
|
||||
JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_finalizeNative
|
||||
(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
|
||||
}
|
||||
#endif
|
||||
|
@ -59,6 +59,38 @@ void jmeBulletUtil::convert(JNIEnv* env, jobject in, btVector3* out) {
|
||||
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) {
|
||||
if (in == NULL || out == NULL) {
|
||||
jmeClasses::throwNPE(env);
|
||||
@ -325,3 +357,61 @@ void jmeBulletUtil::addResult(JNIEnv* env, jobject resultlist, btVector3* hitnor
|
||||
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, const btVector3* in, jobject 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 convertQuat(JNIEnv* env, jobject in, btMatrix3x3* 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 addSweepResult(JNIEnv* env, jobject resultlist, btVector3* hitnormal, btVector3* m_hitPointWorld, const btScalar m_hitFraction, const btCollisionObject* hitobject);
|
||||
private:
|
||||
jmeBulletUtil(){};
|
||||
~jmeBulletUtil(){};
|
||||
|
@ -91,6 +91,21 @@ jfieldID jmeClasses::PhysicsRay_collisionObject;
|
||||
jclass jmeClasses::PhysicsRay_listresult;
|
||||
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
|
||||
//JNIEnv* jmeClasses::env;
|
||||
JavaVM* jmeClasses::vm;
|
||||
@ -240,6 +255,70 @@ void jmeClasses::initJavaClasses(JNIEnv* env) {
|
||||
env->Throw(env->ExceptionOccurred());
|
||||
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) {
|
||||
|
@ -89,6 +89,18 @@ public:
|
||||
static jclass PhysicsRay_listresult;
|
||||
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 jmethodID DebugMeshCallback_addVector;
|
||||
|
||||
|
@ -820,6 +820,10 @@ public class PhysicsSpace {
|
||||
// return lrr.hitFraction;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* Performs a sweep collision test and returns the results as a list of
|
||||
* PhysicsSweepTestResults<br/> You have to use different Transforms for
|
||||
@ -828,16 +832,16 @@ public class PhysicsSpace {
|
||||
* center.
|
||||
*/
|
||||
public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end) {
|
||||
List<PhysicsSweepTestResult> results = new LinkedList<PhysicsSweepTestResult>();
|
||||
// if (!(shape.getCShape() instanceof ConvexShape)) {
|
||||
// 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;
|
||||
|
||||
List results = new LinkedList();
|
||||
sweepTest(shape, start, end , results);
|
||||
return (List<PhysicsSweepTestResult>) 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
|
||||
* 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
|
||||
* 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();
|
||||
// if (!(shape.getCShape() instanceof ConvexShape)) {
|
||||
// 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));
|
||||
sweepTest_native(shape.getObjectId(), start, end, physicsSpaceId, results, allowedCcdPenetration);
|
||||
return results;
|
||||
}
|
||||
|
||||
// private class InternalSweepListener extends CollisionWorld.ConvexResultCallback {
|
||||
//
|
||||
// private List<PhysicsSweepTestResult> results;
|
||||
//
|
||||
// public InternalSweepListener(List<PhysicsSweepTestResult> results) {
|
||||
// this.results = results;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public float addSingleResult(LocalConvexResult lcr, boolean bln) {
|
||||
// PhysicsCollisionObject obj = (PhysicsCollisionObject) lcr.hitCollisionObject.getUserPointer();
|
||||
// results.add(new PhysicsSweepTestResult(obj, Converter.convert(lcr.hitNormalLocal), lcr.hitFraction, bln));
|
||||
// return lcr.hitFraction;
|
||||
// }
|
||||
// }
|
||||
/* private class InternalSweepListener extends CollisionWorld.ConvexResultCallback {
|
||||
|
||||
private List<PhysicsSweepTestResult> results;
|
||||
|
||||
public InternalSweepListener(List<PhysicsSweepTestResult> results) {
|
||||
this.results = results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float addSingleResult(LocalConvexResult lcr, boolean bln) {
|
||||
PhysicsCollisionObject obj = (PhysicsCollisionObject) lcr.hitCollisionObject.getUserPointer();
|
||||
results.add(new PhysicsSweepTestResult(obj, Converter.convert(lcr.hitNormalLocal), lcr.hitFraction, bln));
|
||||
return lcr.hitFraction;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* destroys the current PhysicsSpace so that a new one can be created
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user