Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions jme3-bullet-native/src/native/cpp/com_jme3_bullet_PhysicsSpace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 90 additions & 0 deletions jme3-bullet-native/src/native/cpp/jmeBulletUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
3 changes: 3 additions & 0 deletions jme3-bullet-native/src/native/cpp/jmeBulletUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@ class jmeBulletUtil{
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(){};
Expand Down
79 changes: 79 additions & 0 deletions jme3-bullet-native/src/native/cpp/jmeClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
12 changes: 12 additions & 0 deletions jme3-bullet-native/src/native/cpp/jmeClasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@ class jmeClasses {
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;

Expand Down
61 changes: 32 additions & 29 deletions jme3-bullet/src/main/java/com/jme3/bullet/PhysicsSpace.java
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,10 @@ public List<PhysicsRayTestResult> rayTest(Vector3f from, Vector3f to, List<Physi
// 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
Expand All @@ -828,48 +832,47 @@ public List<PhysicsRayTestResult> rayTest(Vector3f from, Vector3f to, List<Physi
* 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
* start and end (at least distance > 0.4f). SweepTest will not see a
* start and end (at least distance > allowedCcdPenetration). SweepTest will not see a
* 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
*/
Expand Down