159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#include "jmePhysicsSpace.h"
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#include "jmeBulletUtil.h"
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#include <stdio.h>
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Author: Normen Hansen
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott BartajmePhysicsSpace::jmePhysicsSpace(JNIEnv* env, jobject javaSpace) {
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //TODO: global ref? maybe not -> cleaning, rather callback class?
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    this->javaPhysicsSpace = env->NewWeakGlobalRef(javaSpace);
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    this->env = env;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    env->GetJavaVM(&vm);
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (env->ExceptionCheck()) {
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        env->Throw(env->ExceptionOccurred());
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return;
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartavoid jmePhysicsSpace::attachThread() {
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#ifdef ANDROID
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    vm->AttachCurrentThread((JNIEnv**) &env, NULL);
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#elif defined (JNI_VERSION_1_2)
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    vm->AttachCurrentThread((void**) &env, NULL);
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#else
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    vm->AttachCurrentThread(&env, NULL);
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#endif
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott BartaJNIEnv* jmePhysicsSpace::getEnv() {
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    attachThread();
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    return this->env;
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartavoid jmePhysicsSpace::stepSimulation(jfloat tpf, jint maxSteps, jfloat accuracy) {
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    dynamicsWorld->stepSimulation(tpf, maxSteps, accuracy);
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott BartabtThreadSupportInterface* jmePhysicsSpace::createSolverThreadSupport(int maxNumThreads) {
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#ifdef _WIN32
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("solverThreads", SolverThreadFunc, SolverlsMemoryFunc, maxNumThreads);
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    Win32ThreadSupport* threadSupport = new Win32ThreadSupport(threadConstructionInfo);
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    threadSupport->startSPU();
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#elif defined (USE_PTHREADS)
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    PosixThreadSupport::ThreadConstructionInfo constructionInfo("collision", SolverThreadFunc,
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            SolverlsMemoryFunc, maxNumThreads);
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    PosixThreadSupport* threadSupport = new PosixThreadSupport(constructionInfo);
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    threadSupport->startSPU();
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#else
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads", SolverThreadFunc, SolverlsMemoryFunc);
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci);
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    threadSupport->startSPU();
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#endif
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    return threadSupport;
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott BartabtThreadSupportInterface* jmePhysicsSpace::createDispatchThreadSupport(int maxNumThreads) {
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#ifdef _WIN32
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("solverThreads", processCollisionTask, createCollisionLocalStoreMemory, maxNumThreads);
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    Win32ThreadSupport* threadSupport = new Win32ThreadSupport(threadConstructionInfo);
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    threadSupport->startSPU();
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#elif defined (USE_PTHREADS)
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    PosixThreadSupport::ThreadConstructionInfo solverConstructionInfo("solver", processCollisionTask,
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            createCollisionLocalStoreMemory, maxNumThreads);
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    PosixThreadSupport* threadSupport = new PosixThreadSupport(solverConstructionInfo);
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    threadSupport->startSPU();
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#else
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads", processCollisionTask, createCollisionLocalStoreMemory);
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci);
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    threadSupport->startSPU();
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta#endif
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    return threadSupport;
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartavoid jmePhysicsSpace::createPhysicsSpace(jfloat minX, jfloat minY, jfloat minZ, jfloat maxX, jfloat maxY, jfloat maxZ, jint broadphaseId, jboolean threading) {
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // collision configuration contains default setup for memory, collision setup
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btDefaultCollisionConstructionInfo cci;
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //    if(threading){
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //        cci.m_defaultMaxPersistentManifoldPoolSize = 32768;
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //    }
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(cci);
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btVector3 min = btVector3(minX, minY, minZ);
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btVector3 max = btVector3(maxX, maxY, maxZ);
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btBroadphaseInterface* broadphase;
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    switch (broadphaseId) {
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        case 0:
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            broadphase = new btSimpleBroadphase();
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            break;
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        case 1:
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            broadphase = new btAxisSweep3(min, max);
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            break;
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        case 2:
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //TODO: 32bit!
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            broadphase = new btAxisSweep3(min, max);
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            break;
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        case 3:
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            broadphase = new btDbvtBroadphase();
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            break;
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        case 4:
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //            broadphase = new btGpu3DGridBroadphase(
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //                    min, max,
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //                    20, 20, 20,
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //                    10000, 1000, 25);
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            break;
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btCollisionDispatcher* dispatcher;
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btConstraintSolver* solver;
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (threading) {
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        btThreadSupportInterface* dispatchThreads = createDispatchThreadSupport(4);
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dispatcher = new SpuGatheringCollisionDispatcher(dispatchThreads, 4, collisionConfiguration);
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dispatcher->setDispatcherFlags(btCollisionDispatcher::CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION);
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    } else {
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dispatcher = new btCollisionDispatcher(collisionConfiguration);
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (threading) {
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        btThreadSupportInterface* solverThreads = createSolverThreadSupport(4);
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        solver = new btParallelConstraintSolver(solverThreads);
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    } else {
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        solver = new btSequentialImpulseConstraintSolver;
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //create dynamics world
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    dynamicsWorld = world;
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    dynamicsWorld->setWorldUserInfo(this);
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //parallel solver requires the contacts to be in a contiguous pool, so avoid dynamic allocation
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (threading) {
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        world->getSimulationIslandManager()->setSplitIslands(false);
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        world->getSolverInfo().m_numIterations = 4;
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        world->getSolverInfo().m_solverMode = SOLVER_SIMD + SOLVER_USE_WARMSTARTING; //+SOLVER_RANDMIZE_ORDER;
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        world->getDispatchInfo().m_enableSPU = true;
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    dynamicsWorld->setGravity(btVector3(0, -9.81f, 0));
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    struct jmeFilterCallback : public btOverlapFilterCallback {
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // return true when pairs need collision
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy * proxy1) const {
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //            bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //            collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (collides) {
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                btCollisionObject* co0 = (btCollisionObject*) proxy0->m_clientObject;
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                btCollisionObject* co1 = (btCollisionObject*) proxy1->m_clientObject;
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                jmeUserPointer *up0 = (jmeUserPointer*) co0 -> getUserPointer();
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                jmeUserPointer *up1 = (jmeUserPointer*) co1 -> getUserPointer();
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (up0 != NULL && up1 != NULL) {
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    collides = (up0->group & up1->groups) != 0;
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    collides = collides && (up1->group & up0->groups);
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    //add some additional logic here that modified 'collides'
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return collides;
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return false;
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return collides;
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    };
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    dynamicsWorld->getPairCache()->setOverlapFilterCallback(new jmeFilterCallback());
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    dynamicsWorld->setInternalTickCallback(&jmePhysicsSpace::preTickCallback, static_cast<void *> (this), true);
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    dynamicsWorld->setInternalTickCallback(&jmePhysicsSpace::postTickCallback, static_cast<void *> (this));
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (gContactProcessedCallback == NULL) {
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        gContactProcessedCallback = &jmePhysicsSpace::contactProcessedCallback;
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartavoid jmePhysicsSpace::preTickCallback(btDynamicsWorld *world, btScalar timeStep) {
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    jmePhysicsSpace* dynamicsWorld = (jmePhysicsSpace*) world->getWorldUserInfo();
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    JNIEnv* env = dynamicsWorld->getEnv();
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    jobject javaPhysicsSpace = env->NewLocalRef(dynamicsWorld->getJavaPhysicsSpace());
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (javaPhysicsSpace != NULL) {
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        env->CallVoidMethod(javaPhysicsSpace, jmeClasses::PhysicsSpace_preTick, timeStep);
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        env->DeleteLocalRef(javaPhysicsSpace);
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (env->ExceptionCheck()) {
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            env->Throw(env->ExceptionOccurred());
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartavoid jmePhysicsSpace::postTickCallback(btDynamicsWorld *world, btScalar timeStep) {
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    jmePhysicsSpace* dynamicsWorld = (jmePhysicsSpace*) world->getWorldUserInfo();
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    JNIEnv* env = dynamicsWorld->getEnv();
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    jobject javaPhysicsSpace = env->NewLocalRef(dynamicsWorld->getJavaPhysicsSpace());
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (javaPhysicsSpace != NULL) {
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        env->CallVoidMethod(javaPhysicsSpace, jmeClasses::PhysicsSpace_postTick, timeStep);
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        env->DeleteLocalRef(javaPhysicsSpace);
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (env->ExceptionCheck()) {
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            env->Throw(env->ExceptionOccurred());
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartabool jmePhysicsSpace::contactProcessedCallback(btManifoldPoint &cp, void *body0, void *body1) {
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //    printf("contactProcessedCallback %d %dn", body0, body1);
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btCollisionObject* co0 = (btCollisionObject*) body0;
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    jmeUserPointer *up0 = (jmeUserPointer*) co0 -> getUserPointer();
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    btCollisionObject* co1 = (btCollisionObject*) body1;
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    jmeUserPointer *up1 = (jmeUserPointer*) co1 -> getUserPointer();
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (up0 != NULL) {
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        jmePhysicsSpace *dynamicsWorld = (jmePhysicsSpace *)up0->space;
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (dynamicsWorld != NULL) {
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            JNIEnv* env = dynamicsWorld->getEnv();
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            jobject javaPhysicsSpace = env->NewLocalRef(dynamicsWorld->getJavaPhysicsSpace());
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (javaPhysicsSpace != NULL) {
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                jobject javaCollisionObject0 = env->NewLocalRef(up0->javaCollisionObject);
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                jobject javaCollisionObject1 = env->NewLocalRef(up1->javaCollisionObject);
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                env->CallVoidMethod(javaPhysicsSpace, jmeClasses::PhysicsSpace_addCollisionEvent, javaCollisionObject0, javaCollisionObject1, (jlong) & cp);
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                env->DeleteLocalRef(javaPhysicsSpace);
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                env->DeleteLocalRef(javaCollisionObject0);
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                env->DeleteLocalRef(javaCollisionObject1);
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (env->ExceptionCheck()) {
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    env->Throw(env->ExceptionOccurred());
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return true;
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    return true;
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott BartabtDynamicsWorld* jmePhysicsSpace::getDynamicsWorld() {
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    return dynamicsWorld;
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartajobject jmePhysicsSpace::getJavaPhysicsSpace() {
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    return javaPhysicsSpace;
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott BartajmePhysicsSpace::~jmePhysicsSpace() {
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    delete(dynamicsWorld);
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}