1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /**
34  * Author: Normen Hansen
35  */
36 
37 #include <BulletCollision/CollisionDispatch/btGhostObject.h>
38 
39 #include "com_jme3_bullet_objects_PhysicsGhostObject.h"
40 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
41 #include "jmeBulletUtil.h"
42 #include "jmePhysicsSpace.h"
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48     /*
49      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
50      * Method:    createGhostObject
51      * Signature: ()J
52      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_createGhostObject(JNIEnv * env,jobject object)53     JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_createGhostObject
54     (JNIEnv * env, jobject object) {
55         jmeClasses::initJavaClasses(env);
56         btPairCachingGhostObject* ghost = new btPairCachingGhostObject();
57         return reinterpret_cast<jlong>(ghost);
58     }
59 
60     /*
61      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
62      * Method:    setGhostFlags
63      * Signature: (J)V
64      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_setGhostFlags(JNIEnv * env,jobject object,jlong objectId)65     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setGhostFlags
66     (JNIEnv *env, jobject object, jlong objectId) {
67         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
68         if (ghost == NULL) {
69             jclass newExc = env->FindClass("java/lang/NullPointerException");
70             env->ThrowNew(newExc, "The native object does not exist.");
71             return;
72         }
73         ghost->setCollisionFlags(ghost->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
74     }
75 
76     /*
77      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
78      * Method:    setPhysicsLocation
79      * Signature: (JLcom/jme3/math/Vector3f;)V
80      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsLocation(JNIEnv * env,jobject object,jlong objectId,jobject value)81     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsLocation
82     (JNIEnv *env, jobject object, jlong objectId, jobject value) {
83         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
84         if (ghost == NULL) {
85             jclass newExc = env->FindClass("java/lang/NullPointerException");
86             env->ThrowNew(newExc, "The native object does not exist.");
87             return;
88         }
89         jmeBulletUtil::convert(env, value, &ghost->getWorldTransform().getOrigin());
90     }
91 
92     /*
93      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
94      * Method:    setPhysicsRotation
95      * Signature: (JLcom/jme3/math/Matrix3f;)V
96      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsRotation__JLcom_jme3_math_Matrix3f_2(JNIEnv * env,jobject object,jlong objectId,jobject value)97     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsRotation__JLcom_jme3_math_Matrix3f_2
98     (JNIEnv *env, jobject object, jlong objectId, jobject value) {
99         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
100         if (ghost == NULL) {
101             jclass newExc = env->FindClass("java/lang/NullPointerException");
102             env->ThrowNew(newExc, "The native object does not exist.");
103             return;
104         }
105         jmeBulletUtil::convert(env, value, &ghost->getWorldTransform().getBasis());
106     }
107 
108     /*
109      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
110      * Method:    setPhysicsRotation
111      * Signature: (JLcom/jme3/math/Quaternion;)V
112      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsRotation__JLcom_jme3_math_Quaternion_2(JNIEnv * env,jobject object,jlong objectId,jobject value)113     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsRotation__JLcom_jme3_math_Quaternion_2
114     (JNIEnv *env, jobject object, jlong objectId, jobject value) {
115         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
116         if (ghost == NULL) {
117             jclass newExc = env->FindClass("java/lang/NullPointerException");
118             env->ThrowNew(newExc, "The native object does not exist.");
119             return;
120         }
121         jmeBulletUtil::convertQuat(env, value, &ghost->getWorldTransform().getBasis());
122     }
123 
124     /*
125      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
126      * Method:    getPhysicsLocation
127      * Signature: (JLcom/jme3/math/Vector3f;)V
128      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsLocation(JNIEnv * env,jobject object,jlong objectId,jobject value)129     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsLocation
130     (JNIEnv *env, jobject object, jlong objectId, jobject value) {
131         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
132         if (ghost == NULL) {
133             jclass newExc = env->FindClass("java/lang/NullPointerException");
134             env->ThrowNew(newExc, "The native object does not exist.");
135             return;
136         }
137         jmeBulletUtil::convert(env, &ghost->getWorldTransform().getOrigin(), value);
138     }
139 
140     /*
141      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
142      * Method:    getPhysicsRotation
143      * Signature: (JLcom/jme3/math/Quaternion;)V
144      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsRotation(JNIEnv * env,jobject object,jlong objectId,jobject value)145     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsRotation
146     (JNIEnv *env, jobject object, jlong objectId, jobject value) {
147         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
148         if (ghost == NULL) {
149             jclass newExc = env->FindClass("java/lang/NullPointerException");
150             env->ThrowNew(newExc, "The native object does not exist.");
151             return;
152         }
153         jmeBulletUtil::convertQuat(env, &ghost->getWorldTransform().getBasis(), value);
154     }
155 
156     /*
157      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
158      * Method:    getPhysicsRotationMatrix
159      * Signature: (JLcom/jme3/math/Matrix3f;)V
160      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsRotationMatrix(JNIEnv * env,jobject object,jlong objectId,jobject value)161     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsRotationMatrix
162     (JNIEnv *env, jobject object, jlong objectId, jobject value) {
163         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
164         if (ghost == NULL) {
165             jclass newExc = env->FindClass("java/lang/NullPointerException");
166             env->ThrowNew(newExc, "The native object does not exist.");
167             return;
168         }
169         jmeBulletUtil::convert(env, &ghost->getWorldTransform().getBasis(), value);
170     }
171 
172     class jmeGhostOverlapCallback : public btOverlapCallback {
173         JNIEnv* m_env;
174         jobject m_object;
175     public:
jmeGhostOverlapCallback(JNIEnv * env,jobject object)176         jmeGhostOverlapCallback(JNIEnv *env, jobject object)
177                 :m_env(env),
178                  m_object(object)
179         {
180         }
~jmeGhostOverlapCallback()181         virtual ~jmeGhostOverlapCallback() {}
processOverlap(btBroadphasePair & pair)182         virtual bool    processOverlap(btBroadphasePair& pair)
183         {
184             btCollisionObject *co1 = (btCollisionObject *)pair.m_pProxy1->m_clientObject;
185             jmeUserPointer *up1 = (jmeUserPointer*)co1 -> getUserPointer();
186             jobject javaCollisionObject1 = m_env->NewLocalRef(up1->javaCollisionObject);
187             m_env->CallVoidMethod(m_object, jmeClasses::PhysicsGhostObject_addOverlappingObject, javaCollisionObject1);
188             m_env->DeleteLocalRef(javaCollisionObject1);
189             if (m_env->ExceptionCheck()) {
190                 m_env->Throw(m_env->ExceptionOccurred());
191                 return false;
192             }
193 
194             return false;
195         }
196     };
197 
198     /*
199      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
200      * Method:    getOverlappingObjects
201      * Signature: (J)V
202      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_getOverlappingObjects(JNIEnv * env,jobject object,jlong objectId)203     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getOverlappingObjects
204       (JNIEnv *env, jobject object, jlong objectId) {
205         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
206         if (ghost == NULL) {
207             jclass newExc = env->FindClass("java/lang/NullPointerException");
208             env->ThrowNew(newExc, "The native object does not exist.");
209             return;
210         }
211         btHashedOverlappingPairCache * pc = ghost->getOverlappingPairCache();
212         jmeGhostOverlapCallback cb(env, object);
213         pc -> processAllOverlappingPairs(&cb, NULL);
214     }
215     /*
216      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
217      * Method:    getOverlappingCount
218      * Signature: (J)I
219      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_getOverlappingCount(JNIEnv * env,jobject object,jlong objectId)220     JNIEXPORT jint JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getOverlappingCount
221     (JNIEnv *env, jobject object, jlong objectId) {
222         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
223         if (ghost == NULL) {
224             jclass newExc = env->FindClass("java/lang/NullPointerException");
225             env->ThrowNew(newExc, "The native object does not exist.");
226             return 0;
227         }
228         return ghost->getNumOverlappingObjects();
229     }
230 
231     /*
232      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
233      * Method:    setCcdSweptSphereRadius
234      * Signature: (JF)V
235      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_setCcdSweptSphereRadius(JNIEnv * env,jobject object,jlong objectId,jfloat value)236     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setCcdSweptSphereRadius
237     (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
238         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
239         if (ghost == NULL) {
240             jclass newExc = env->FindClass("java/lang/NullPointerException");
241             env->ThrowNew(newExc, "The native object does not exist.");
242             return;
243         }
244         ghost->setCcdSweptSphereRadius(value);
245     }
246 
247     /*
248      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
249      * Method:    setCcdMotionThreshold
250      * Signature: (JF)V
251      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_setCcdMotionThreshold(JNIEnv * env,jobject object,jlong objectId,jfloat value)252     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setCcdMotionThreshold
253     (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
254         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
255         if (ghost == NULL) {
256             jclass newExc = env->FindClass("java/lang/NullPointerException");
257             env->ThrowNew(newExc, "The native object does not exist.");
258             return;
259         }
260         ghost->setCcdMotionThreshold(value);
261     }
262 
263     /*
264      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
265      * Method:    getCcdSweptSphereRadius
266      * Signature: (J)F
267      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdSweptSphereRadius(JNIEnv * env,jobject object,jlong objectId)268     JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdSweptSphereRadius
269     (JNIEnv *env, jobject object, jlong objectId) {
270         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
271         if (ghost == NULL) {
272             jclass newExc = env->FindClass("java/lang/NullPointerException");
273             env->ThrowNew(newExc, "The native object does not exist.");
274             return 0;
275         }
276         return ghost->getCcdSweptSphereRadius();
277     }
278 
279     /*
280      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
281      * Method:    getCcdMotionThreshold
282      * Signature: (J)F
283      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdMotionThreshold(JNIEnv * env,jobject object,jlong objectId)284     JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdMotionThreshold
285     (JNIEnv *env, jobject object, jlong objectId) {
286         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
287         if (ghost == NULL) {
288             jclass newExc = env->FindClass("java/lang/NullPointerException");
289             env->ThrowNew(newExc, "The native object does not exist.");
290             return 0;
291         }
292         return ghost->getCcdMotionThreshold();
293     }
294 
295     /*
296      * Class:     com_jme3_bullet_objects_PhysicsGhostObject
297      * Method:    getCcdSquareMotionThreshold
298      * Signature: (J)F
299      */
Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdSquareMotionThreshold(JNIEnv * env,jobject object,jlong objectId)300     JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdSquareMotionThreshold
301     (JNIEnv *env, jobject object, jlong objectId) {
302         btPairCachingGhostObject* ghost = reinterpret_cast<btPairCachingGhostObject*>(objectId);
303         if (ghost == NULL) {
304             jclass newExc = env->FindClass("java/lang/NullPointerException");
305             env->ThrowNew(newExc, "The native object does not exist.");
306             return 0;
307         }
308         return ghost->getCcdSquareMotionThreshold();
309     }
310 
311 #ifdef __cplusplus
312 }
313 #endif
314