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 #include "com_jme3_bullet_PhysicsSpace.h" 33 #include "jmePhysicsSpace.h" 34 #include "jmeBulletUtil.h" 35 36 /** 37 * Author: Normen Hansen 38 */ 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /* 44 * Class: com_jme3_bullet_PhysicsSpace 45 * Method: createPhysicsSpace 46 * Signature: (FFFFFFI)J 47 */ 48 JNIEXPORT jlong JNICALL Java_com_jme3_bullet_PhysicsSpace_createPhysicsSpace 49 (JNIEnv * env, jobject object, jfloat minX, jfloat minY, jfloat minZ, jfloat maxX, jfloat maxY, jfloat maxZ, jint broadphase, jboolean threading) { 50 jmeClasses::initJavaClasses(env); 51 jmePhysicsSpace* space = new jmePhysicsSpace(env, object); 52 if (space == NULL) { 53 jclass newExc = env->FindClass("java/lang/NullPointerException"); 54 env->ThrowNew(newExc, "The physics space has not been created."); 55 return 0; 56 } 57 space->createPhysicsSpace(minX, minY, minZ, maxX, maxY, maxZ, broadphase, threading); 58 return reinterpret_cast<jlong>(space); 59 } 60 61 /* 62 * Class: com_jme3_bullet_PhysicsSpace 63 * Method: stepSimulation 64 * Signature: (JFIF)V 65 */ 66 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_stepSimulation 67 (JNIEnv * env, jobject object, jlong spaceId, jfloat tpf, jint maxSteps, jfloat accuracy) { 68 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 69 if (space == NULL) { 70 jclass newExc = env->FindClass("java/lang/NullPointerException"); 71 env->ThrowNew(newExc, "The physics space does not exist."); 72 return; 73 } 74 space->stepSimulation(tpf, maxSteps, accuracy); 75 } 76 77 /* 78 * Class: com_jme3_bullet_PhysicsSpace 79 * Method: addCollisionObject 80 * Signature: (JJ)V 81 */ 82 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addCollisionObject 83 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 84 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 85 btCollisionObject* collisionObject = reinterpret_cast<btCollisionObject*>(objectId); 86 if (space == NULL) { 87 jclass newExc = env->FindClass("java/lang/NullPointerException"); 88 env->ThrowNew(newExc, "The physics space does not exist."); 89 return; 90 } 91 if (collisionObject == NULL) { 92 jclass newExc = env->FindClass("java/lang/NullPointerException"); 93 env->ThrowNew(newExc, "The collision object does not exist."); 94 return; 95 } 96 jmeUserPointer *userPointer = (jmeUserPointer*)collisionObject->getUserPointer(); 97 userPointer -> space = space; 98 99 space->getDynamicsWorld()->addCollisionObject(collisionObject); 100 } 101 102 /* 103 * Class: com_jme3_bullet_PhysicsSpace 104 * Method: removeCollisionObject 105 * Signature: (JJ)V 106 */ 107 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeCollisionObject 108 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 109 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 110 btCollisionObject* collisionObject = reinterpret_cast<btCollisionObject*>(objectId); 111 if (space == NULL) { 112 jclass newExc = env->FindClass("java/lang/NullPointerException"); 113 env->ThrowNew(newExc, "The physics space does not exist."); 114 return; 115 } 116 if (collisionObject == NULL) { 117 jclass newExc = env->FindClass("java/lang/NullPointerException"); 118 env->ThrowNew(newExc, "The collision object does not exist."); 119 return; 120 } 121 space->getDynamicsWorld()->removeCollisionObject(collisionObject); 122 jmeUserPointer *userPointer = (jmeUserPointer*)collisionObject->getUserPointer(); 123 userPointer -> space = NULL; 124 } 125 126 /* 127 * Class: com_jme3_bullet_PhysicsSpace 128 * Method: addRigidBody 129 * Signature: (JJ)V 130 */ 131 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addRigidBody 132 (JNIEnv * env, jobject object, jlong spaceId, jlong rigidBodyId) { 133 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 134 btRigidBody* collisionObject = reinterpret_cast<btRigidBody*>(rigidBodyId); 135 if (space == NULL) { 136 jclass newExc = env->FindClass("java/lang/NullPointerException"); 137 env->ThrowNew(newExc, "The physics space does not exist."); 138 return; 139 } 140 if (collisionObject == NULL) { 141 jclass newExc = env->FindClass("java/lang/NullPointerException"); 142 env->ThrowNew(newExc, "The collision object does not exist."); 143 return; 144 } 145 jmeUserPointer *userPointer = (jmeUserPointer*)collisionObject->getUserPointer(); 146 userPointer -> space = space; 147 space->getDynamicsWorld()->addRigidBody(collisionObject); 148 } 149 150 /* 151 * Class: com_jme3_bullet_PhysicsSpace 152 * Method: removeRigidBody 153 * Signature: (JJ)V 154 */ 155 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeRigidBody 156 (JNIEnv * env, jobject object, jlong spaceId, jlong rigidBodyId) { 157 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 158 btRigidBody* collisionObject = reinterpret_cast<btRigidBody*>(rigidBodyId); 159 if (space == NULL) { 160 jclass newExc = env->FindClass("java/lang/NullPointerException"); 161 env->ThrowNew(newExc, "The physics space does not exist."); 162 return; 163 } 164 if (collisionObject == NULL) { 165 jclass newExc = env->FindClass("java/lang/NullPointerException"); 166 env->ThrowNew(newExc, "The collision object does not exist."); 167 return; 168 } 169 jmeUserPointer *userPointer = (jmeUserPointer*)collisionObject->getUserPointer(); 170 userPointer -> space = NULL; 171 space->getDynamicsWorld()->removeRigidBody(collisionObject); 172 } 173 174 /* 175 * Class: com_jme3_bullet_PhysicsSpace 176 * Method: addCharacterObject 177 * Signature: (JJ)V 178 */ 179 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addCharacterObject 180 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 181 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 182 btCollisionObject* collisionObject = reinterpret_cast<btCollisionObject*>(objectId); 183 if (space == NULL) { 184 jclass newExc = env->FindClass("java/lang/NullPointerException"); 185 env->ThrowNew(newExc, "The physics space does not exist."); 186 return; 187 } 188 if (collisionObject == NULL) { 189 jclass newExc = env->FindClass("java/lang/NullPointerException"); 190 env->ThrowNew(newExc, "The collision object does not exist."); 191 return; 192 } 193 jmeUserPointer *userPointer = (jmeUserPointer*)collisionObject->getUserPointer(); 194 userPointer -> space = space; 195 space->getDynamicsWorld()->addCollisionObject(collisionObject, 196 btBroadphaseProxy::CharacterFilter, 197 btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter 198 ); 199 } 200 201 /* 202 * Class: com_jme3_bullet_PhysicsSpace 203 * Method: removeCharacterObject 204 * Signature: (JJ)V 205 */ 206 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeCharacterObject 207 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 208 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 209 btCollisionObject* collisionObject = reinterpret_cast<btCollisionObject*>(objectId); 210 if (space == NULL) { 211 jclass newExc = env->FindClass("java/lang/NullPointerException"); 212 env->ThrowNew(newExc, "The physics space does not exist."); 213 return; 214 } 215 if (collisionObject == NULL) { 216 jclass newExc = env->FindClass("java/lang/NullPointerException"); 217 env->ThrowNew(newExc, "The collision object does not exist."); 218 return; 219 } 220 jmeUserPointer *userPointer = (jmeUserPointer*)collisionObject->getUserPointer(); 221 userPointer -> space = NULL; 222 space->getDynamicsWorld()->removeCollisionObject(collisionObject); 223 } 224 225 /* 226 * Class: com_jme3_bullet_PhysicsSpace 227 * Method: addAction 228 * Signature: (JJ)V 229 */ 230 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addAction 231 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 232 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 233 btActionInterface* actionObject = reinterpret_cast<btActionInterface*>(objectId); 234 if (space == NULL) { 235 jclass newExc = env->FindClass("java/lang/NullPointerException"); 236 env->ThrowNew(newExc, "The physics space does not exist."); 237 return; 238 } 239 if (actionObject == NULL) { 240 jclass newExc = env->FindClass("java/lang/NullPointerException"); 241 env->ThrowNew(newExc, "The action object does not exist."); 242 return; 243 } 244 space->getDynamicsWorld()->addAction(actionObject); 245 } 246 247 /* 248 * Class: com_jme3_bullet_PhysicsSpace 249 * Method: removeAction 250 * Signature: (JJ)V 251 */ 252 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeAction 253 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 254 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 255 btActionInterface* actionObject = reinterpret_cast<btActionInterface*>(objectId); 256 if (space == NULL) { 257 jclass newExc = env->FindClass("java/lang/NullPointerException"); 258 env->ThrowNew(newExc, "The physics space does not exist."); 259 return; 260 } 261 if (actionObject == NULL) { 262 jclass newExc = env->FindClass("java/lang/NullPointerException"); 263 env->ThrowNew(newExc, "The action object does not exist."); 264 return; 265 } 266 space->getDynamicsWorld()->removeAction(actionObject); 267 } 268 269 /* 270 * Class: com_jme3_bullet_PhysicsSpace 271 * Method: addVehicle 272 * Signature: (JJ)V 273 */ 274 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addVehicle 275 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 276 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 277 btActionInterface* actionObject = reinterpret_cast<btActionInterface*>(objectId); 278 if (space == NULL) { 279 jclass newExc = env->FindClass("java/lang/NullPointerException"); 280 env->ThrowNew(newExc, "The physics space does not exist."); 281 return; 282 } 283 if (actionObject == NULL) { 284 jclass newExc = env->FindClass("java/lang/NullPointerException"); 285 env->ThrowNew(newExc, "The vehicle object does not exist."); 286 return; 287 } 288 space->getDynamicsWorld()->addVehicle(actionObject); 289 } 290 291 /* 292 * Class: com_jme3_bullet_PhysicsSpace 293 * Method: removeVehicle 294 * Signature: (JJ)V 295 */ 296 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeVehicle 297 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 298 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 299 btActionInterface* actionObject = reinterpret_cast<btActionInterface*>(objectId); 300 if (space == NULL) { 301 jclass newExc = env->FindClass("java/lang/NullPointerException"); 302 env->ThrowNew(newExc, "The physics space does not exist."); 303 return; 304 } 305 if (actionObject == NULL) { 306 jclass newExc = env->FindClass("java/lang/NullPointerException"); 307 env->ThrowNew(newExc, "The action object does not exist."); 308 return; 309 } 310 space->getDynamicsWorld()->removeVehicle(actionObject); 311 } 312 313 /* 314 * Class: com_jme3_bullet_PhysicsSpace 315 * Method: addConstraint 316 * Signature: (JJ)V 317 */ 318 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addConstraint 319 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 320 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 321 btTypedConstraint* constraint = reinterpret_cast<btTypedConstraint*>(objectId); 322 if (space == NULL) { 323 jclass newExc = env->FindClass("java/lang/NullPointerException"); 324 env->ThrowNew(newExc, "The physics space does not exist."); 325 return; 326 } 327 if (constraint == NULL) { 328 jclass newExc = env->FindClass("java/lang/NullPointerException"); 329 env->ThrowNew(newExc, "The constraint object does not exist."); 330 return; 331 } 332 space->getDynamicsWorld()->addConstraint(constraint); 333 } 334 335 /* 336 * Class: com_jme3_bullet_PhysicsSpace 337 * Method: removeConstraint 338 * Signature: (JJ)V 339 */ 340 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeConstraint 341 (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) { 342 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 343 btTypedConstraint* constraint = reinterpret_cast<btTypedConstraint*>(objectId); 344 if (space == NULL) { 345 jclass newExc = env->FindClass("java/lang/NullPointerException"); 346 env->ThrowNew(newExc, "The physics space does not exist."); 347 return; 348 } 349 if (constraint == NULL) { 350 jclass newExc = env->FindClass("java/lang/NullPointerException"); 351 env->ThrowNew(newExc, "The constraint object does not exist."); 352 return; 353 } 354 space->getDynamicsWorld()->removeConstraint(constraint); 355 } 356 357 /* 358 * Class: com_jme3_bullet_PhysicsSpace 359 * Method: setGravity 360 * Signature: (JLcom/jme3/math/Vector3f;)V 361 */ 362 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_setGravity 363 (JNIEnv * env, jobject object, jlong spaceId, jobject vector) { 364 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 365 if (space == NULL) { 366 jclass newExc = env->FindClass("java/lang/NullPointerException"); 367 env->ThrowNew(newExc, "The physics space does not exist."); 368 return; 369 } 370 btVector3 gravity = btVector3(); 371 jmeBulletUtil::convert(env, vector, &gravity); 372 space->getDynamicsWorld()->setGravity(gravity); 373 } 374 375 /* 376 * Class: com_jme3_bullet_PhysicsSpace 377 * Method: initNativePhysics 378 * Signature: ()V 379 */ 380 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_initNativePhysics 381 (JNIEnv * env, jclass clazz) { 382 jmeClasses::initJavaClasses(env); 383 } 384 385 /* 386 * Class: com_jme3_bullet_PhysicsSpace 387 * Method: finalizeNative 388 * Signature: (J)V 389 */ 390 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_finalizeNative 391 (JNIEnv * env, jobject object, jlong spaceId) { 392 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId); 393 if (space == NULL) { 394 return; 395 } 396 delete(space); 397 } 398 399 JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_rayTest_1native 400 (JNIEnv * env, jobject object, jobject to, jobject from, jlong spaceId, jobject resultlist) { 401 402 jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*> (spaceId); 403 if (space == NULL) { 404 jclass newExc = env->FindClass("java/lang/NullPointerException"); 405 env->ThrowNew(newExc, "The physics space does not exist."); 406 return; 407 } 408 409 struct AllRayResultCallback : public btCollisionWorld::RayResultCallback { 410 411 AllRayResultCallback(const btVector3& rayFromWorld, const btVector3 & rayToWorld) : m_rayFromWorld(rayFromWorld), m_rayToWorld(rayToWorld) { 412 } 413 jobject resultlist; 414 JNIEnv* env; 415 btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction 416 btVector3 m_rayToWorld; 417 418 btVector3 m_hitNormalWorld; 419 btVector3 m_hitPointWorld; 420 421 virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) { 422 if (normalInWorldSpace) { 423 m_hitNormalWorld = rayResult.m_hitNormalLocal; 424 } else { 425 m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal; 426 } 427 m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); 428 429 jmeBulletUtil::addResult(env, resultlist, m_hitNormalWorld, m_hitPointWorld, rayResult.m_hitFraction, rayResult.m_collisionObject); 430 431 return 1.f; 432 } 433 }; 434 435 btVector3 native_to = btVector3(); 436 jmeBulletUtil::convert(env, to, &native_to); 437 438 btVector3 native_from = btVector3(); 439 jmeBulletUtil::convert(env, from, &native_from); 440 441 AllRayResultCallback resultCallback(native_from, native_to); 442 resultCallback.env = env; 443 resultCallback.resultlist = resultlist; 444 space->getDynamicsWorld()->rayTest(native_from, native_to, resultCallback); 445 return; 446 } 447 448 #ifdef __cplusplus 449 } 450 #endif 451