From 0379d87611a257205292d2083646ff078f01675f Mon Sep 17 00:00:00 2001 From: rainmantsr Date: Mon, 30 Mar 2015 12:02:54 +0200 Subject: [PATCH] Added: GhostObject sweep- and raytest --- ...jme3_bullet_objects_PhysicsGhostObject.cpp | 112 ++++++++++++++++++ ...m_jme3_bullet_objects_PhysicsGhostObject.h | 16 +++ .../java/com/jme3/bullet/PhysicsSpace.java | 4 +- .../bullet/objects/PhysicsGhostObject.java | 41 +++++++ 4 files changed, 171 insertions(+), 2 deletions(-) diff --git a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsGhostObject.cpp b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsGhostObject.cpp index fa38c1b639..b4a5292306 100644 --- a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsGhostObject.cpp +++ b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsGhostObject.cpp @@ -315,6 +315,118 @@ extern "C" { return ghost->getCcdSquareMotionThreshold(); } + JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_rayTest_1native + (JNIEnv * env, jobject object, jobject from, jobject to, jlong objectId, jobject resultlist, jint flags) { + + btPairCachingGhostObject* ghost = reinterpret_cast(objectId); + if (ghost == NULL) { + jclass newExc = env->FindClass("java/lang/NullPointerException"); + env->ThrowNew(newExc, "The physics space does not exist."); + return; + } + + struct AllRayResultCallback : public btCollisionWorld::RayResultCallback { + + AllRayResultCallback(const btVector3& rayFromWorld, const btVector3 & rayToWorld) : m_rayFromWorld(rayFromWorld), m_rayToWorld(rayToWorld) { + } + jobject resultlist; + JNIEnv* env; + btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction + btVector3 m_rayToWorld; + + btVector3 m_hitNormalWorld; + btVector3 m_hitPointWorld; + + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) { + if (normalInWorldSpace) { + m_hitNormalWorld = rayResult.m_hitNormalLocal; + } + else { + m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal; + } + m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); + + jmeBulletUtil::addResult(env, resultlist, &m_hitNormalWorld, &m_hitPointWorld, rayResult.m_hitFraction, rayResult.m_collisionObject); + + return 1.f; + } + }; + + btVector3 native_to = btVector3(); + jmeBulletUtil::convert(env, to, &native_to); + + btVector3 native_from = btVector3(); + jmeBulletUtil::convert(env, from, &native_from); + + AllRayResultCallback resultCallback(native_from, native_to); + resultCallback.env = env; + resultCallback.resultlist = resultlist; + resultCallback.m_flags = flags; + ghost->rayTest(native_from, native_to, resultCallback); + return; + } + + + + JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_sweepTest_1native + (JNIEnv * env, jobject object, jlong shapeId, jobject from, jobject to, jlong objectId, jobject resultlist, jfloat allowedCcdPenetration) { + + btPairCachingGhostObject* ghost = reinterpret_cast(objectId); + if (ghost == NULL) { + jclass newExc = env->FindClass("java/lang/NullPointerException"); + env->ThrowNew(newExc, "The physics space does not exist."); + return; + } + + btCollisionShape* shape = reinterpret_cast (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; + ghost->convexSweepTest((btConvexShape *)shape, native_from, native_to, resultCallback, native_allowed_ccd_penetration); + return; + } + #ifdef __cplusplus } #endif diff --git a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsGhostObject.h b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsGhostObject.h index cf98e59705..b7f12d2017 100644 --- a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsGhostObject.h +++ b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsGhostObject.h @@ -161,6 +161,22 @@ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdM JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdSquareMotionThreshold (JNIEnv *, jobject, jlong); +/* +* Class: com_jme3_bullet_objects_PhysicsGhostObject +* Method : rayTest_native +* Signature : (Lcom / jme3 / math / Vector3f; Lcom / jme3 / math / Vector3f; JLjava / util / List;)V +*/ +JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_rayTest_1native +(JNIEnv *, jobject, jobject, jobject, jlong, jobject, jint); + +/* +* Class: com_jme3_bullet_objects_PhysicsGhostObject +* 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_objects_PhysicsGhostObject_sweepTest_1native +(JNIEnv *, jobject, jlong, jobject, jobject, jlong, jobject, jfloat); + #ifdef __cplusplus } #endif diff --git a/jme3-bullet/src/main/java/com/jme3/bullet/PhysicsSpace.java b/jme3-bullet/src/main/java/com/jme3/bullet/PhysicsSpace.java index 380dc3e169..80321aa390 100644 --- a/jme3-bullet/src/main/java/com/jme3/bullet/PhysicsSpace.java +++ b/jme3-bullet/src/main/java/com/jme3/bullet/PhysicsSpace.java @@ -803,7 +803,7 @@ public List rayTest(Vector3f from, Vector3f to, List results, int flags); + public native void rayTest_native(Vector3f from, Vector3f to, long objectId, List results, int flags); // private class InternalRayListener extends CollisionWorld.RayResultCallback { // @@ -841,7 +841,7 @@ public List sweepTest(CollisionShape shape, Transform st return sweepTest(shape, start, end, results, 0.0f); } - public native void sweepTest_native(long shape, Transform from, Transform to, long physicsSpaceId, List results, float allowedCcdPenetration); + public native void sweepTest_native(long shape, Transform from, Transform to, long objectId, List results, float allowedCcdPenetration); /** * Performs a sweep collision test and returns the results as a list of * PhysicsSweepTestResults
You have to use different Transforms for diff --git a/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsGhostObject.java b/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsGhostObject.java index 052e280e43..87eceb2880 100644 --- a/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsGhostObject.java +++ b/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsGhostObject.java @@ -31,8 +31,10 @@ */ package com.jme3.bullet.objects; +import com.jme3.bullet.collision.*; import com.jme3.bullet.collision.PhysicsCollisionObject; import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.math.Transform; import com.jme3.export.InputCapsule; import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; @@ -278,6 +280,45 @@ public float getCcdSquareMotionThreshold() { private native float getCcdSquareMotionThreshold(long objectId); + public List rayTest(Vector3f from, Vector3f to, List results, int rayTestFlags) { + results.clear(); + rayTest_native(from, to, objectId, results, rayTestFlags); + return results; + } + + public native void rayTest_native(Vector3f from, Vector3f to, long objectId, List results, int flags); + + /** + * Performs a sweep collision test and returns the results as a list of + * PhysicsSweepTestResults
You have to use different Transforms for + * start and end (at least distance > 0.4f). SweepTest will not see a + * collision if it starts INSIDE an object and is moving AWAY from its + * center. + */ + public List sweepTest(CollisionShape shape, Transform start, Transform end) { + List results = new LinkedList(); + sweepTest(shape, start, end , results); + return (List) results; + } + + public List sweepTest(CollisionShape shape, Transform start, Transform end, List results) { + return sweepTest(shape, start, end, results, 0.0f); + } + + public native void sweepTest_native(long shape, Transform from, Transform to, long objectId, List results, float allowedCcdPenetration); + /** + * Performs a sweep collision test and returns the results as a list of + * PhysicsSweepTestResults
You have to use different Transforms for + * 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 sweepTest(CollisionShape shape, Transform start, Transform end, List results, float allowedCcdPenetration ) { + results.clear(); + sweepTest_native(shape.getObjectId(), start, end, objectId, results, allowedCcdPenetration); + return results; + } + @Override public void write(JmeExporter e) throws IOException { super.write(e);