Bladeren bron

Merge branch 'master' of git://github.com/rainmantsr/jmonkeyengine into rainmantsr-master

shadowislord 10 jaren geleden
bovenliggende
commit
55829d46cf

+ 62 - 0
jme3-bullet-native/src/native/cpp/com_jme3_bullet_PhysicsSpace.cpp

@@ -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

+ 9 - 0
jme3-bullet-native/src/native/cpp/com_jme3_bullet_PhysicsSpace.h

@@ -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

+ 90 - 0
jme3-bullet-native/src/native/cpp/jmeBulletUtil.cpp

@@ -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);
+}

+ 3 - 0
jme3-bullet-native/src/native/cpp/jmeBulletUtil.h

@@ -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(){};

+ 79 - 0
jme3-bullet-native/src/native/cpp/jmeClasses.cpp

@@ -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) {

+ 12 - 0
jme3-bullet-native/src/native/cpp/jmeClasses.h

@@ -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;
 

+ 32 - 29
jme3-bullet/src/main/java/com/jme3/bullet/PhysicsSpace.java

@@ -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,48 +832,47 @@ 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
-     * 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
      */