Home | History | Annotate | Download | only in bullet-native
      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