diff --git a/engine/src/bullet/com/jme3/bullet/BulletAppState.java b/engine/src/bullet/com/jme3/bullet/BulletAppState.java
new file mode 100644
index 000000000..753441bb4
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/BulletAppState.java
@@ -0,0 +1,278 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet;
+
+import com.jme3.app.Application;
+import com.jme3.app.state.AppState;
+import com.jme3.app.state.AppStateManager;
+import com.jme3.bullet.PhysicsSpace.BroadphaseType;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * BulletAppState
allows using bullet physics in an Application.
+ * @author normenhansen
+ */
+public class BulletAppState implements AppState, PhysicsTickListener {
+
+ protected boolean initialized = false;
+ protected Application app;
+ protected AppStateManager stateManager;
+ protected ScheduledThreadPoolExecutor executor;
+ protected PhysicsSpace pSpace;
+ protected ThreadingType threadingType = ThreadingType.SEQUENTIAL;
+ protected BroadphaseType broadphaseType = BroadphaseType.DBVT;
+ protected Vector3f worldMin = new Vector3f(-10000f, -10000f, -10000f);
+ protected Vector3f worldMax = new Vector3f(10000f, 10000f, 10000f);
+ private float speed = 1;
+ protected boolean active = true;
+ protected float tpf;
+ protected Future physicsFuture;
+
+ /**
+ * Creates a new BulletAppState running a PhysicsSpace for physics simulation,
+ * use getStateManager().addState(bulletAppState) to enable physics for an Application.
+ */
+ public BulletAppState() {
+ }
+
+ /**
+ * Creates a new BulletAppState running a PhysicsSpace for physics simulation,
+ * use getStateManager().addState(bulletAppState) to enable physics for an Application.
+ * @param broadphaseType The type of broadphase collision detection, BroadphaseType.DVBT is the default
+ */
+ public BulletAppState(BroadphaseType broadphaseType) {
+ this(new Vector3f(-10000f, -10000f, -10000f), new Vector3f(10000f, 10000f, 10000f), broadphaseType);
+ }
+
+ /**
+ * Creates a new BulletAppState running a PhysicsSpace for physics simulation,
+ * use getStateManager().addState(bulletAppState) to enable physics for an Application.
+ * An AxisSweep broadphase is used.
+ * @param worldMin The minimum world extent
+ * @param worldMax The maximum world extent
+ */
+ public BulletAppState(Vector3f worldMin, Vector3f worldMax) {
+ this(worldMin, worldMax, BroadphaseType.AXIS_SWEEP_3);
+ }
+
+ public BulletAppState(Vector3f worldMin, Vector3f worldMax, BroadphaseType broadphaseType) {
+ this.worldMin.set(worldMin);
+ this.worldMax.set(worldMax);
+ this.broadphaseType = broadphaseType;
+ }
+
+ private boolean startPhysicsOnExecutor() {
+ if (executor != null) {
+ executor.shutdown();
+ }
+ executor = new ScheduledThreadPoolExecutor(1);
+ final BulletAppState app = this;
+ Callable call = new Callable() {
+
+ public Boolean call() throws Exception {
+ detachedPhysicsLastUpdate = System.currentTimeMillis();
+ pSpace = new PhysicsSpace(worldMin, worldMax, broadphaseType);
+ pSpace.addTickListener(app);
+ return true;
+ }
+ };
+ try {
+ return executor.submit(call).get();
+ } catch (InterruptedException ex) {
+ Logger.getLogger(BulletAppState.class.getName()).log(Level.SEVERE, null, ex);
+ return false;
+ } catch (ExecutionException ex) {
+ Logger.getLogger(BulletAppState.class.getName()).log(Level.SEVERE, null, ex);
+ return false;
+ }
+ }
+ private Callable parallelPhysicsUpdate = new Callable() {
+
+ public Boolean call() throws Exception {
+ pSpace.update(tpf * getSpeed());
+ return true;
+ }
+ };
+ long detachedPhysicsLastUpdate = 0;
+ private Callable detachedPhysicsUpdate = new Callable() {
+
+ public Boolean call() throws Exception {
+ pSpace.update(getPhysicsSpace().getAccuracy() * getSpeed());
+ pSpace.distributeEvents();
+ long update = System.currentTimeMillis() - detachedPhysicsLastUpdate;
+ detachedPhysicsLastUpdate = System.currentTimeMillis();
+ executor.schedule(detachedPhysicsUpdate, Math.round(getPhysicsSpace().getAccuracy() * 1000000.0f) - (update * 1000), TimeUnit.MICROSECONDS);
+ return true;
+ }
+ };
+
+ public PhysicsSpace getPhysicsSpace() {
+ return pSpace;
+ }
+
+ /**
+ * The physics system is started automatically on attaching, if you want to start it
+ * before for some reason, you can use this method.
+ */
+ public void startPhysics() {
+ //start physics thread(pool)
+ if (threadingType == ThreadingType.PARALLEL) {
+ startPhysicsOnExecutor();
+// } else if (threadingType == ThreadingType.DETACHED) {
+// startPhysicsOnExecutor();
+// executor.submit(detachedPhysicsUpdate);
+ } else {
+ pSpace = new PhysicsSpace(worldMin, worldMax, broadphaseType);
+ }
+ pSpace.addTickListener(this);
+ initialized = true;
+ }
+
+ public void initialize(AppStateManager stateManager, Application app) {
+ if (!initialized) {
+ startPhysics();
+ }
+ initialized = true;
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.active = enabled;
+ }
+
+ public boolean isEnabled() {
+ return active;
+ }
+
+ public void stateAttached(AppStateManager stateManager) {
+ if (!initialized) {
+ startPhysics();
+ }
+ if (threadingType == ThreadingType.PARALLEL) {
+ PhysicsSpace.setLocalThreadPhysicsSpace(pSpace);
+ }
+ }
+
+ public void stateDetached(AppStateManager stateManager) {
+ }
+
+ public void update(float tpf) {
+ if (!active) {
+ return;
+ }
+// if (threadingType != ThreadingType.DETACHED) {
+ pSpace.distributeEvents();
+// }
+ this.tpf = tpf;
+ }
+
+ public void render(RenderManager rm) {
+ if (!active) {
+ return;
+ }
+ if (threadingType == ThreadingType.PARALLEL) {
+ physicsFuture = executor.submit(parallelPhysicsUpdate);
+ } else if (threadingType == ThreadingType.SEQUENTIAL) {
+ pSpace.update(active ? tpf * speed : 0);
+ } else {
+ }
+ }
+
+ public void postRender() {
+ if (physicsFuture != null) {
+ try {
+ physicsFuture.get();
+ physicsFuture = null;
+ } catch (InterruptedException ex) {
+ Logger.getLogger(BulletAppState.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (ExecutionException ex) {
+ Logger.getLogger(BulletAppState.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ public void cleanup() {
+ if (executor != null) {
+ executor.shutdown();
+ executor = null;
+ }
+ pSpace.removeTickListener(this);
+ pSpace.destroy();
+ }
+
+ /**
+ * @return the threadingType
+ */
+ public ThreadingType getThreadingType() {
+ return threadingType;
+ }
+
+ /**
+ * Use before attaching state
+ * @param threadingType the threadingType to set
+ */
+ public void setThreadingType(ThreadingType threadingType) {
+ this.threadingType = threadingType;
+ }
+
+ /**
+ * Use before attaching state
+ */
+ public void setBroadphaseType(BroadphaseType broadphaseType) {
+ this.broadphaseType = broadphaseType;
+ }
+
+ /**
+ * Use before attaching state
+ */
+ public void setWorldMin(Vector3f worldMin) {
+ this.worldMin = worldMin;
+ }
+
+ /**
+ * Use before attaching state
+ */
+ public void setWorldMax(Vector3f worldMax) {
+ this.worldMax = worldMax;
+ }
+
+ public float getSpeed() {
+ return speed;
+ }
+
+ public void setSpeed(float speed) {
+ this.speed = speed;
+ }
+
+ public void prePhysicsTick(PhysicsSpace space, float f) {
+ }
+
+ public void physicsTick(PhysicsSpace space, float f) {
+ }
+
+ public enum ThreadingType {
+
+ /**
+ * Default mode; user update, physics update and rendering happen sequentially (single threaded)
+ */
+ SEQUENTIAL,
+ /**
+ * Parallel threaded mode; physics update and rendering are executed in parallel, update order is kept.
+ * Multiple BulletAppStates will execute in parallel in this mode.
+ */
+ PARALLEL,
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/PhysicsSpace.java b/engine/src/bullet/com/jme3/bullet/PhysicsSpace.java
new file mode 100644
index 000000000..e443c07b9
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/PhysicsSpace.java
@@ -0,0 +1,930 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet;
+
+import com.jme3.app.AppTask;
+import com.jme3.asset.AssetManager;
+import com.jme3.math.Vector3f;
+import com.jme3.bullet.collision.PhysicsCollisionEvent;
+import com.jme3.bullet.collision.PhysicsCollisionEventFactory;
+import com.jme3.bullet.collision.PhysicsCollisionGroupListener;
+import com.jme3.bullet.collision.PhysicsCollisionListener;
+import com.jme3.bullet.collision.PhysicsCollisionObject;
+import com.jme3.bullet.collision.PhysicsRayTestResult;
+import com.jme3.bullet.collision.PhysicsSweepTestResult;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.control.PhysicsControl;
+import com.jme3.bullet.control.RigidBodyControl;
+import com.jme3.bullet.joints.PhysicsJoint;
+import com.jme3.bullet.objects.PhysicsGhostObject;
+import com.jme3.bullet.objects.PhysicsCharacter;
+import com.jme3.bullet.objects.PhysicsVehicle;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.math.Transform;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * PhysicsSpace - The central jbullet-jme physics space
+ * @author normenhansen
+ */
+public class PhysicsSpace {
+
+ public static final int AXIS_X = 0;
+ public static final int AXIS_Y = 1;
+ public static final int AXIS_Z = 2;
+ private long physicsSpaceId = 0;
+ private static ThreadLocal>> pQueueTL =
+ new ThreadLocal>>() {
+
+ @Override
+ protected ConcurrentLinkedQueue> initialValue() {
+ return new ConcurrentLinkedQueue>();
+ }
+ };
+ private ConcurrentLinkedQueue> pQueue = new ConcurrentLinkedQueue>();
+ private static ThreadLocal physicsSpaceTL = new ThreadLocal();
+ private BroadphaseType broadphaseType = BroadphaseType.DBVT;
+// private DiscreteDynamicsWorld dynamicsWorld = null;
+// private BroadphaseInterface broadphase;
+// private CollisionDispatcher dispatcher;
+// private ConstraintSolver solver;
+// private DefaultCollisionConfiguration collisionConfiguration;
+// private Map physicsGhostNodes = new ConcurrentHashMap();
+ private Map physicsNodes = new ConcurrentHashMap();
+ private List physicsJoints = new LinkedList();
+ private List collisionListeners = new LinkedList();
+ private List collisionEvents = new LinkedList();
+ private Map collisionGroupListeners = new ConcurrentHashMap();
+ private ConcurrentLinkedQueue tickListeners = new ConcurrentLinkedQueue();
+ private PhysicsCollisionEventFactory eventFactory = new PhysicsCollisionEventFactory();
+ private Vector3f worldMin = new Vector3f(-10000f, -10000f, -10000f);
+ private Vector3f worldMax = new Vector3f(10000f, 10000f, 10000f);
+ private float accuracy = 1f / 60f;
+ private int maxSubSteps = 4;
+ private AssetManager debugManager;
+
+ static {
+// System.loadLibrary("bulletjme");
+// initNativePhysics();
+ }
+
+ /**
+ * Get the current PhysicsSpace running on this thread
+ * For parallel physics, this can also be called from the OpenGL thread to receive the PhysicsSpace
+ * @return the PhysicsSpace running on this thread
+ */
+ public static PhysicsSpace getPhysicsSpace() {
+ return physicsSpaceTL.get();
+ }
+
+ /**
+ * Used internally
+ * @param space
+ */
+ public static void setLocalThreadPhysicsSpace(PhysicsSpace space) {
+ physicsSpaceTL.set(space);
+ }
+
+ public PhysicsSpace() {
+ this(new Vector3f(-10000f, -10000f, -10000f), new Vector3f(10000f, 10000f, 10000f), BroadphaseType.DBVT);
+ }
+
+ public PhysicsSpace(BroadphaseType broadphaseType) {
+ this(new Vector3f(-10000f, -10000f, -10000f), new Vector3f(10000f, 10000f, 10000f), broadphaseType);
+ }
+
+ public PhysicsSpace(Vector3f worldMin, Vector3f worldMax) {
+ this(worldMin, worldMax, BroadphaseType.AXIS_SWEEP_3);
+ }
+
+ public PhysicsSpace(Vector3f worldMin, Vector3f worldMax, BroadphaseType broadphaseType) {
+ this.worldMin.set(worldMin);
+ this.worldMax.set(worldMax);
+ this.broadphaseType = broadphaseType;
+ create();
+ System.loadLibrary("bulletjme");
+ initNativePhysics();
+ }
+
+ /**
+ * Has to be called from the (designated) physics thread
+ */
+ public void create() {
+ //TODO: boroadphase!
+ System.loadLibrary("bulletjme");
+ initNativePhysics();
+ physicsSpaceId = createPhysicsSpace(worldMin.x, worldMin.y, worldMin.z, worldMax.x, worldMax.y, worldMax.z, 3, false);
+ pQueueTL.set(pQueue);
+ physicsSpaceTL.set(this);
+
+// collisionConfiguration = new DefaultCollisionConfiguration();
+// dispatcher = new CollisionDispatcher(collisionConfiguration);
+// switch (broadphaseType) {
+// case SIMPLE:
+// broadphase = new SimpleBroadphase();
+// break;
+// case AXIS_SWEEP_3:
+// broadphase = new AxisSweep3(Converter.convert(worldMin), Converter.convert(worldMax));
+// break;
+// case AXIS_SWEEP_3_32:
+// broadphase = new AxisSweep3_32(Converter.convert(worldMin), Converter.convert(worldMax));
+// break;
+// case DBVT:
+// broadphase = new DbvtBroadphase();
+// break;
+// }
+//
+// solver = new SequentialImpulseConstraintSolver();
+//
+// dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
+// dynamicsWorld.setGravity(new javax.vecmath.Vector3f(0, -9.81f, 0));
+//
+// broadphase.getOverlappingPairCache().setInternalGhostPairCallback(new GhostPairCallback());
+// GImpactCollisionAlgorithm.registerAlgorithm(dispatcher);
+//
+// //register filter callback for tick / collision
+// setTickCallback();
+// setContactCallbacks();
+// //register filter callback for collision groups
+// setOverlapFilterCallback();
+ }
+
+ private native long createPhysicsSpace(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, int broadphaseType, boolean threading);
+
+ private void preTick_native(float f) {
+ AppTask task = pQueue.poll();
+ task = pQueue.poll();
+ while (task != null) {
+ while (task.isCancelled()) {
+ task = pQueue.poll();
+ }
+ try {
+ task.invoke();
+ } catch (Exception ex) {
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ task = pQueue.poll();
+ }
+ for (Iterator it = tickListeners.iterator(); it.hasNext();) {
+ PhysicsTickListener physicsTickCallback = it.next();
+ physicsTickCallback.prePhysicsTick(this, f);
+ }
+ }
+
+ private void postTick_native(float f) {
+ for (Iterator it = tickListeners.iterator(); it.hasNext();) {
+ PhysicsTickListener physicsTickCallback = it.next();
+ physicsTickCallback.physicsTick(this, f);
+ }
+ }
+
+ private void addCollision_native(){
+
+ }
+
+ private boolean needCollision_native(PhysicsCollisionObject objectA, PhysicsCollisionObject objectB){
+ return false;
+ }
+
+// private void setOverlapFilterCallback() {
+// OverlapFilterCallback callback = new OverlapFilterCallback() {
+//
+// public boolean needBroadphaseCollision(BroadphaseProxy bp, BroadphaseProxy bp1) {
+// boolean collides = (bp.collisionFilterGroup & bp1.collisionFilterMask) != 0;
+// if (collides) {
+// collides = (bp1.collisionFilterGroup & bp.collisionFilterMask) != 0;
+// }
+// if (collides) {
+// assert (bp.clientObject instanceof com.bulletphysics.collision.dispatch.CollisionObject && bp.clientObject instanceof com.bulletphysics.collision.dispatch.CollisionObject);
+// com.bulletphysics.collision.dispatch.CollisionObject colOb = (com.bulletphysics.collision.dispatch.CollisionObject) bp.clientObject;
+// com.bulletphysics.collision.dispatch.CollisionObject colOb1 = (com.bulletphysics.collision.dispatch.CollisionObject) bp1.clientObject;
+// assert (colOb.getUserPointer() != null && colOb1.getUserPointer() != null);
+// PhysicsCollisionObject collisionObject = (PhysicsCollisionObject) colOb.getUserPointer();
+// PhysicsCollisionObject collisionObject1 = (PhysicsCollisionObject) colOb1.getUserPointer();
+// if ((collisionObject.getCollideWithGroups() & collisionObject1.getCollisionGroup()) > 0
+// || (collisionObject1.getCollideWithGroups() & collisionObject.getCollisionGroup()) > 0) {
+// PhysicsCollisionGroupListener listener = collisionGroupListeners.get(collisionObject.getCollisionGroup());
+// PhysicsCollisionGroupListener listener1 = collisionGroupListeners.get(collisionObject1.getCollisionGroup());
+// if (listener != null) {
+// return listener.collide(collisionObject, collisionObject1);
+// } else if (listener1 != null) {
+// return listener1.collide(collisionObject, collisionObject1);
+// }
+// return true;
+// } else {
+// return false;
+// }
+// }
+// return collides;
+// }
+// };
+// dynamicsWorld.getPairCache().setOverlapFilterCallback(callback);
+// }
+// private void setTickCallback() {
+// final PhysicsSpace space = this;
+// InternalTickCallback callback2 = new InternalTickCallback() {
+//
+// @Override
+// public void internalTick(DynamicsWorld dw, float f) {
+// //execute task list
+// AppTask task = pQueue.poll();
+// task = pQueue.poll();
+// while (task != null) {
+// while (task.isCancelled()) {
+// task = pQueue.poll();
+// }
+// try {
+// task.invoke();
+// } catch (Exception ex) {
+// Logger.getLogger(PhysicsSpace.class.getName()).log(Level.SEVERE, null, ex);
+// }
+// task = pQueue.poll();
+// }
+// for (Iterator it = tickListeners.iterator(); it.hasNext();) {
+// PhysicsTickListener physicsTickCallback = it.next();
+// physicsTickCallback.prePhysicsTick(space, f);
+// }
+// }
+// };
+// dynamicsWorld.setPreTickCallback(callback2);
+// InternalTickCallback callback = new InternalTickCallback() {
+//
+// @Override
+// public void internalTick(DynamicsWorld dw, float f) {
+// for (Iterator it = tickListeners.iterator(); it.hasNext();) {
+// PhysicsTickListener physicsTickCallback = it.next();
+// physicsTickCallback.physicsTick(space, f);
+// }
+// }
+// };
+// dynamicsWorld.setInternalTickCallback(callback, this);
+// }
+// private void setContactCallbacks() {
+// BulletGlobals.setContactAddedCallback(new ContactAddedCallback() {
+//
+// public boolean contactAdded(ManifoldPoint cp, com.bulletphysics.collision.dispatch.CollisionObject colObj0,
+// int partId0, int index0, com.bulletphysics.collision.dispatch.CollisionObject colObj1, int partId1,
+// int index1) {
+// System.out.println("contact added");
+// return true;
+// }
+// });
+//
+// BulletGlobals.setContactProcessedCallback(new ContactProcessedCallback() {
+//
+// public boolean contactProcessed(ManifoldPoint cp, Object body0, Object body1) {
+// if (body0 instanceof CollisionObject && body1 instanceof CollisionObject) {
+// PhysicsCollisionObject node = null, node1 = null;
+// CollisionObject rBody0 = (CollisionObject) body0;
+// CollisionObject rBody1 = (CollisionObject) body1;
+// node = (PhysicsCollisionObject) rBody0.getUserPointer();
+// node1 = (PhysicsCollisionObject) rBody1.getUserPointer();
+// collisionEvents.add(eventFactory.getEvent(PhysicsCollisionEvent.TYPE_PROCESSED, node, node1, cp));
+// }
+// return true;
+// }
+// });
+//
+// BulletGlobals.setContactDestroyedCallback(new ContactDestroyedCallback() {
+//
+// public boolean contactDestroyed(Object userPersistentData) {
+// System.out.println("contact destroyed");
+// return true;
+// }
+// });
+// }
+ /**
+ * updates the physics space
+ * @param time the current time value
+ */
+ public void update(float time) {
+ update(time, maxSubSteps);
+ }
+
+ /**
+ * updates the physics space, uses maxSteps
+ * @param time the current time value
+ * @param maxSteps
+ */
+ public void update(float time, int maxSteps) {
+// if (getDynamicsWorld() == null) {
+// return;
+// }
+ //step simulation
+ stepSimulation(physicsSpaceId, time, maxSteps, accuracy);
+ }
+
+ private native void stepSimulation(long space, float time, int maxSteps, float accuracy);
+
+ public void distributeEvents() {
+ //add collision callbacks
+ synchronized (collisionEvents) {
+ for (Iterator it = collisionEvents.iterator(); it.hasNext();) {
+ PhysicsCollisionEvent physicsCollisionEvent = it.next();
+ for (PhysicsCollisionListener listener : collisionListeners) {
+ listener.collision(physicsCollisionEvent);
+ }
+ //recycle events
+ eventFactory.recycle(physicsCollisionEvent);
+ it.remove();
+ }
+ }
+ }
+
+ public static Future enqueueOnThisThread(Callable callable) {
+ AppTask task = new AppTask(callable);
+ System.out.println("created apptask");
+ pQueueTL.get().add(task);
+ return task;
+ }
+
+ /**
+ * calls the callable on the next physics tick (ensuring e.g. force applying)
+ * @param
+ * @param callable
+ * @return
+ */
+ public Future enqueue(Callable callable) {
+ AppTask task = new AppTask(callable);
+ pQueue.add(task);
+ return task;
+ }
+
+ /**
+ * adds an object to the physics space
+ * @param obj the PhysicsControl or Spatial with PhysicsControl to add
+ */
+ public void add(Object obj) {
+ if (obj instanceof PhysicsControl) {
+ ((PhysicsControl) obj).setPhysicsSpace(this);
+ } else if (obj instanceof Spatial) {
+ Spatial node = (Spatial) obj;
+ PhysicsControl control = node.getControl(PhysicsControl.class);
+ control.setPhysicsSpace(this);
+ } else if (obj instanceof PhysicsCollisionObject) {
+ addCollisionObject((PhysicsCollisionObject) obj);
+ } else if (obj instanceof PhysicsJoint) {
+ addJoint((PhysicsJoint) obj);
+ } else {
+ throw (new UnsupportedOperationException("Cannot add this kind of object to the physics space."));
+ }
+ }
+
+ public void addCollisionObject(PhysicsCollisionObject obj) {
+ if (obj instanceof PhysicsGhostObject) {
+ addGhostObject((PhysicsGhostObject) obj);
+ } else if (obj instanceof PhysicsRigidBody) {
+ addRigidBody((PhysicsRigidBody) obj);
+ } else if (obj instanceof PhysicsVehicle) {
+ addRigidBody((PhysicsVehicle) obj);
+ } else if (obj instanceof PhysicsCharacter) {
+ addCharacter((PhysicsCharacter) obj);
+ }
+ }
+
+ /**
+ * removes an object from the physics space
+ * @param obj the PhysicsControl or Spatial with PhysicsControl to remove
+ */
+ public void remove(Object obj) {
+ if (obj instanceof PhysicsControl) {
+ ((PhysicsControl) obj).setPhysicsSpace(null);
+ } else if (obj instanceof Spatial) {
+ Spatial node = (Spatial) obj;
+ PhysicsControl control = node.getControl(PhysicsControl.class);
+ control.setPhysicsSpace(null);
+ } else if (obj instanceof PhysicsCollisionObject) {
+ removeCollisionObject((PhysicsCollisionObject) obj);
+ } else if (obj instanceof PhysicsJoint) {
+ removeJoint((PhysicsJoint) obj);
+ } else {
+ throw (new UnsupportedOperationException("Cannot remove this kind of object from the physics space."));
+ }
+ }
+
+ public void removeCollisionObject(PhysicsCollisionObject obj) {
+ if (obj instanceof PhysicsGhostObject) {
+ removeGhostObject((PhysicsGhostObject) obj);
+ } else if (obj instanceof PhysicsRigidBody) {
+ removeRigidBody((PhysicsRigidBody) obj);
+ } else if (obj instanceof PhysicsCharacter) {
+ removeCharacter((PhysicsCharacter) obj);
+ }
+ }
+
+ /**
+ * adds all physics controls and joints in the given spatial node to the physics space
+ * (e.g. after loading from disk) - recursive if node
+ * @param spatial the rootnode containing the physics objects
+ */
+ public void addAll(Spatial spatial) {
+ if (spatial.getControl(RigidBodyControl.class) != null) {
+ RigidBodyControl physicsNode = spatial.getControl(RigidBodyControl.class);
+ if (!physicsNodes.containsValue(physicsNode)) {
+ physicsNode.setPhysicsSpace(this);
+ }
+ //add joints
+ List joints = physicsNode.getJoints();
+ for (Iterator it1 = joints.iterator(); it1.hasNext();) {
+ PhysicsJoint physicsJoint = it1.next();
+ //add connected physicsnodes if they are not already added
+ if (!physicsNodes.containsValue(physicsJoint.getBodyA())) {
+ if (physicsJoint.getBodyA() instanceof PhysicsControl) {
+ add(physicsJoint.getBodyA());
+ } else {
+ addRigidBody(physicsJoint.getBodyA());
+ }
+ }
+ if (!physicsNodes.containsValue(physicsJoint.getBodyB())) {
+ if (physicsJoint.getBodyA() instanceof PhysicsControl) {
+ add(physicsJoint.getBodyB());
+ } else {
+ addRigidBody(physicsJoint.getBodyB());
+ }
+ }
+ if (!physicsJoints.contains(physicsJoint)) {
+ addJoint(physicsJoint);
+ }
+ }
+ } else if (spatial.getControl(PhysicsControl.class) != null) {
+ spatial.getControl(PhysicsControl.class).setPhysicsSpace(this);
+ }
+ //recursion
+ if (spatial instanceof Node) {
+ List children = ((Node) spatial).getChildren();
+ for (Iterator it = children.iterator(); it.hasNext();) {
+ Spatial spat = it.next();
+ addAll(spat);
+ }
+ }
+ }
+
+ /**
+ * Removes all physics controls and joints in the given spatial from the physics space
+ * (e.g. before saving to disk) - recursive if node
+ * @param spatial the rootnode containing the physics objects
+ */
+ public void removeAll(Spatial spatial) {
+ if (spatial.getControl(RigidBodyControl.class) != null) {
+ RigidBodyControl physicsNode = spatial.getControl(RigidBodyControl.class);
+ if (physicsNodes.containsValue(physicsNode)) {
+ physicsNode.setPhysicsSpace(null);
+ }
+ //remove joints
+ List joints = physicsNode.getJoints();
+ for (Iterator it1 = joints.iterator(); it1.hasNext();) {
+ PhysicsJoint physicsJoint = it1.next();
+ //add connected physicsnodes if they are not already added
+ if (physicsNodes.containsValue(physicsJoint.getBodyA())) {
+ if (physicsJoint.getBodyA() instanceof PhysicsControl) {
+ remove(physicsJoint.getBodyA());
+ } else {
+ removeRigidBody(physicsJoint.getBodyA());
+ }
+ }
+ if (physicsNodes.containsValue(physicsJoint.getBodyB())) {
+ if (physicsJoint.getBodyA() instanceof PhysicsControl) {
+ remove(physicsJoint.getBodyB());
+ } else {
+ removeRigidBody(physicsJoint.getBodyB());
+ }
+ }
+ if (physicsJoints.contains(physicsJoint)) {
+ removeJoint(physicsJoint);
+ }
+ }
+ } else if (spatial.getControl(PhysicsControl.class) != null) {
+ spatial.getControl(PhysicsControl.class).setPhysicsSpace(null);
+ }
+ //recursion
+ if (spatial instanceof Node) {
+ List children = ((Node) spatial).getChildren();
+ for (Iterator it = children.iterator(); it.hasNext();) {
+ Spatial spat = it.next();
+ if (spat instanceof Node) {
+ removeAll((Node) spat);
+ }
+ }
+ }
+ }
+
+ private native void addCollisionObject(long space, long id);
+
+ private native void removeCollisionObject(long space, long id);
+
+ private native void addRigidBody(long space, long id);
+
+ private native void removeRigidBody(long space, long id);
+
+ private native void addCharacterObject(long space, long id);
+
+ private native void removeCharacterObject(long space, long id);
+
+ private native void addAction(long space, long id);
+
+ private native void removeAction(long space, long id);
+
+ private native void addVehicle(long space, long id);
+
+ private native void removeVehicle(long space, long id);
+
+ private native void addConstraint(long space, long id);
+
+ private native void removeConstraint(long space, long id);
+
+ private void addGhostObject(PhysicsGhostObject node) {
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Adding ghost object {0} to physics space.", Long.toHexString(node.getObjectId()));
+ addCollisionObject(physicsSpaceId, node.getObjectId());
+ }
+
+ private void removeGhostObject(PhysicsGhostObject node) {
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Removing ghost object {0} from physics space.", Long.toHexString(node.getObjectId()));
+ removeCollisionObject(physicsSpaceId, node.getObjectId());
+ }
+
+ private void addCharacter(PhysicsCharacter node) {
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Adding character {0} to physics space.", Long.toHexString(node.getObjectId()));
+ addCharacterObject(physicsSpaceId, node.getObjectId());
+ addAction(physicsSpaceId, node.getControllerId());
+// dynamicsWorld.addCollisionObject(node.getObjectId(), CollisionFilterGroups.CHARACTER_FILTER, (short) (CollisionFilterGroups.STATIC_FILTER | CollisionFilterGroups.DEFAULT_FILTER));
+// dynamicsWorld.addAction(node.getControllerId());
+ }
+
+ private void removeCharacter(PhysicsCharacter node) {
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Removing character {0} from physics space.", Long.toHexString(node.getObjectId()));
+ removeAction(physicsSpaceId, node.getControllerId());
+ removeCharacterObject(physicsSpaceId, node.getObjectId());
+// dynamicsWorld.removeAction(node.getControllerId());
+// dynamicsWorld.removeCollisionObject(node.getObjectId());
+ }
+
+ private void addRigidBody(PhysicsRigidBody node) {
+ physicsNodes.put(node.getObjectId(), node);
+
+ //Workaround
+ //It seems that adding a Kinematic RigidBody to the dynamicWorld prevent it from being non kinematic again afterward.
+ //so we add it non kinematic, then set it kinematic again.
+ boolean kinematic = false;
+ if (node.isKinematic()) {
+ kinematic = true;
+ node.setKinematic(false);
+ }
+ addRigidBody(physicsSpaceId, node.getObjectId());
+ if (kinematic) {
+ node.setKinematic(true);
+ }
+
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Adding RigidBody {0} to physics space.", node.getObjectId());
+ if (node instanceof PhysicsVehicle) {
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Adding vehicle constraint {0} to physics space.", Long.toHexString(((PhysicsVehicle) node).getVehicleId()));
+ ((PhysicsVehicle) node).createVehicle(this);
+ addVehicle(physicsSpaceId, ((PhysicsVehicle) node).getVehicleId());
+// dynamicsWorld.addVehicle(((PhysicsVehicle) node).getVehicleId());
+ }
+ }
+
+ private void removeRigidBody(PhysicsRigidBody node) {
+ if (node instanceof PhysicsVehicle) {
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Removing vehicle constraint {0} from physics space.", Long.toHexString(((PhysicsVehicle) node).getVehicleId()));
+ removeVehicle(physicsSpaceId, ((PhysicsVehicle) node).getVehicleId());
+// dynamicsWorld.removeVehicle(((PhysicsVehicle) node).getVehicleId());
+ }
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Removing RigidBody {0} from physics space.", Long.toHexString(node.getObjectId()));
+ physicsNodes.remove(node.getObjectId());
+ removeRigidBody(physicsSpaceId, node.getObjectId());
+ }
+
+ private void addJoint(PhysicsJoint joint) {
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Adding Joint {0} to physics space.", Long.toHexString(joint.getObjectId()));
+ physicsJoints.add(joint);
+ addConstraint(physicsSpaceId, joint.getObjectId());
+// dynamicsWorld.addConstraint(joint.getObjectId(), !joint.isCollisionBetweenLinkedBodys());
+ }
+
+ private void removeJoint(PhysicsJoint joint) {
+ Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Removing Joint {0} from physics space.", Long.toHexString(joint.getObjectId()));
+ physicsJoints.remove(joint);
+ removeConstraint(physicsSpaceId, joint.getObjectId());
+// dynamicsWorld.removeConstraint(joint.getObjectId());
+ }
+
+ /**
+ * Sets the gravity of the PhysicsSpace, set before adding physics objects!
+ * @param gravity
+ */
+ public void setGravity(Vector3f gravity) {
+// dynamicsWorld.setGravity(Converter.convert(gravity));
+ setGravity(physicsSpaceId, gravity);
+ }
+
+ private native void setGravity(long spaceId, Vector3f gravity);
+
+// /**
+// * applies gravity value to all objects
+// */
+// public void applyGravity() {
+//// dynamicsWorld.applyGravity();
+// }
+//
+// /**
+// * clears forces of all objects
+// */
+// public void clearForces() {
+//// dynamicsWorld.clearForces();
+// }
+//
+ /**
+ * Adds the specified listener to the physics tick listeners.
+ * The listeners are called on each physics step, which is not necessarily
+ * each frame but is determined by the accuracy of the physics space.
+ * @param listener
+ */
+ public void addTickListener(PhysicsTickListener listener) {
+ tickListeners.add(listener);
+ }
+
+ public void removeTickListener(PhysicsTickListener listener) {
+ tickListeners.remove(listener);
+ }
+
+ /**
+ * Adds a CollisionListener that will be informed about collision events
+ * @param listener the CollisionListener to add
+ */
+ public void addCollisionListener(PhysicsCollisionListener listener) {
+ collisionListeners.add(listener);
+ }
+
+ /**
+ * Removes a CollisionListener from the list
+ * @param listener the CollisionListener to remove
+ */
+ public void removeCollisionListener(PhysicsCollisionListener listener) {
+ collisionListeners.remove(listener);
+ }
+
+ /**
+ * Adds a listener for a specific collision group, such a listener can disable collisions when they happen.
+ * There can be only one listener per collision group.
+ * @param listener
+ * @param collisionGroup
+ */
+ public void addCollisionGroupListener(PhysicsCollisionGroupListener listener, int collisionGroup) {
+ collisionGroupListeners.put(collisionGroup, listener);
+ }
+
+ public void removeCollisionGroupListener(int collisionGroup) {
+ collisionGroupListeners.remove(collisionGroup);
+ }
+
+ /**
+ * Performs a ray collision test and returns the results as a list of PhysicsRayTestResults
+ */
+ public List rayTest(Vector3f from, Vector3f to) {
+ List results = new LinkedList();
+// dynamicsWorld.rayTest(Converter.convert(from, rayVec1), Converter.convert(to, rayVec2), new InternalRayListener(results));
+ return results;
+ }
+
+ /**
+ * Performs a ray collision test and returns the results as a list of PhysicsRayTestResults
+ */
+ public List rayTest(Vector3f from, Vector3f to, List results) {
+ results.clear();
+// dynamicsWorld.rayTest(Converter.convert(from, rayVec1), Converter.convert(to, rayVec2), new InternalRayListener(results));
+ return results;
+ }
+
+// private class InternalRayListener extends CollisionWorld.RayResultCallback {
+//
+// private List results;
+//
+// public InternalRayListener(List results) {
+// this.results = results;
+// }
+//
+// @Override
+// public float addSingleResult(LocalRayResult lrr, boolean bln) {
+// PhysicsCollisionObject obj = (PhysicsCollisionObject) lrr.collisionObject.getUserPointer();
+// results.add(new PhysicsRayTestResult(obj, Converter.convert(lrr.hitNormalLocal), lrr.hitFraction, bln));
+// return lrr.hitFraction;
+// }
+// }
+ /**
+ * Performs a sweep collision test and returns the results as a list of PhysicsSweepTestResults
+ * You have to use different Transforms for start and end (at least distance > 0.4f).
+ * SweepTest will not see a collision if it starts INSIDE an object and is moving AWAY from its center.
+ */
+ public List sweepTest(CollisionShape shape, Transform start, Transform end) {
+ List results = new LinkedList();
+// if (!(shape.getCShape() instanceof ConvexShape)) {
+// Logger.getLogger(PhysicsSpace.class.getName()).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;
+
+ }
+
+ /**
+ * Performs a sweep collision test and returns the results as a list of PhysicsSweepTestResults
+ * You have to use different Transforms for start and end (at least distance > 0.4f).
+ * SweepTest will not see a collision if it starts INSIDE an object and is moving AWAY from its center.
+ */
+ public List sweepTest(CollisionShape shape, Transform start, Transform end, List results) {
+ results.clear();
+// if (!(shape.getCShape() instanceof ConvexShape)) {
+// Logger.getLogger(PhysicsSpace.class.getName()).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;
+ }
+
+// private class InternalSweepListener extends CollisionWorld.ConvexResultCallback {
+//
+// private List results;
+//
+// public InternalSweepListener(List 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
+ */
+ public void destroy() {
+ physicsNodes.clear();
+ physicsJoints.clear();
+
+// dynamicsWorld.destroy();
+// dynamicsWorld = null;
+ }
+
+ /**
+ // * used internally
+ // * @return the dynamicsWorld
+ // */
+ public long getSpaceId() {
+ return physicsSpaceId;
+ }
+
+ public BroadphaseType getBroadphaseType() {
+ return broadphaseType;
+ }
+
+ public void setBroadphaseType(BroadphaseType broadphaseType) {
+ this.broadphaseType = broadphaseType;
+ }
+
+ /**
+ * Sets the maximum amount of extra steps that will be used to step the physics
+ * when the fps is below the physics fps. Doing this maintains determinism in physics.
+ * For example a maximum number of 2 can compensate for framerates as low as 30fps
+ * when the physics has the default accuracy of 60 fps. Note that setting this
+ * value too high can make the physics drive down its own fps in case its overloaded.
+ * @param steps The maximum number of extra steps, default is 4.
+ */
+ public void setMaxSubSteps(int steps) {
+ maxSubSteps = steps;
+ }
+
+ /**
+ * get the current accuracy of the physics computation
+ * @return the current accuracy
+ */
+ public float getAccuracy() {
+ return accuracy;
+ }
+
+ /**
+ * sets the accuracy of the physics computation, default=1/60s
+ * @param accuracy
+ */
+ public void setAccuracy(float accuracy) {
+ this.accuracy = accuracy;
+ }
+
+ public Vector3f getWorldMin() {
+ return worldMin;
+ }
+
+ /**
+ * only applies for AXIS_SWEEP broadphase
+ * @param worldMin
+ */
+ public void setWorldMin(Vector3f worldMin) {
+ this.worldMin.set(worldMin);
+ }
+
+ public Vector3f getWorldMax() {
+ return worldMax;
+ }
+
+ /**
+ * only applies for AXIS_SWEEP broadphase
+ * @param worldMax
+ */
+ public void setWorldMax(Vector3f worldMax) {
+ this.worldMax.set(worldMax);
+ }
+
+ /**
+ * Enable debug display for physics
+ * @param manager AssetManager to use to create debug materials
+ */
+ public void enableDebug(AssetManager manager) {
+ debugManager = manager;
+ }
+
+ /**
+ * Disable debug display
+ */
+ public void disableDebug() {
+ debugManager = null;
+ }
+
+ public AssetManager getDebugManager() {
+ return debugManager;
+ }
+
+ public static native void initNativePhysics();
+
+ /**
+ * interface with Broadphase types
+ */
+ public enum BroadphaseType {
+
+ /**
+ * basic Broadphase
+ */
+ SIMPLE,
+ /**
+ * better Broadphase, needs worldBounds , max Object number = 16384
+ */
+ AXIS_SWEEP_3,
+ /**
+ * better Broadphase, needs worldBounds , max Object number = 65536
+ */
+ AXIS_SWEEP_3_32,
+ /**
+ * Broadphase allowing quicker adding/removing of physics objects
+ */
+ DBVT;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing PhysicsSpace {0}", Long.toHexString(physicsSpaceId));
+ finalizeNative(physicsSpaceId);
+ }
+
+ private native void finalizeNative(long objectId);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/PhysicsTickListener.java b/engine/src/bullet/com/jme3/bullet/PhysicsTickListener.java
new file mode 100644
index 000000000..0f3bbca8c
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/PhysicsTickListener.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet;
+
+/**
+ * Implement this interface to be called from the physics thread on a physics update.
+ * @author normenhansen
+ */
+public interface PhysicsTickListener {
+
+ /**
+ * Called before the physics is actually stepped, use to apply forces etc.
+ * @param space
+ * @param f
+ */
+ public void prePhysicsTick(PhysicsSpace space, float f);
+
+ /**
+ * Called after the physics has been stepped, use to check for forces etc.
+ * @param space
+ * @param f
+ */
+ public void physicsTick(PhysicsSpace space, float f);
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionEvent.java b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionEvent.java
new file mode 100644
index 000000000..e79e315fe
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionEvent.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision;
+
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Spatial;
+import java.util.EventObject;
+
+/**
+ * A CollisionEvent stores all information about a collision in the PhysicsWorld.
+ * Do not store this Object, as it will be reused after the collision() method has been called.
+ * Get/reference all data you need in the collide method.
+ * @author normenhansen
+ */
+public class PhysicsCollisionEvent extends EventObject {
+
+ public static final int TYPE_ADDED = 0;
+ public static final int TYPE_PROCESSED = 1;
+ public static final int TYPE_DESTROYED = 2;
+ private int type;
+ private PhysicsCollisionObject nodeA;
+ private PhysicsCollisionObject nodeB;
+ public final Vector3f localPointA;
+ public final Vector3f localPointB;
+ public final Vector3f positionWorldOnB;
+ public final Vector3f positionWorldOnA;
+ public final Vector3f normalWorldOnB;
+ public float distance1;
+ public float combinedFriction;
+ public float combinedRestitution;
+ public int partId0;
+ public int partId1;
+ public int index0;
+ public int index1;
+ public Object userPersistentData;
+ public float appliedImpulse;
+ public boolean lateralFrictionInitialized;
+ public float appliedImpulseLateral1;
+ public float appliedImpulseLateral2;
+ public int lifeTime;
+ public final Vector3f lateralFrictionDir1;
+ public final Vector3f lateralFrictionDir2;
+
+ public PhysicsCollisionEvent(int type, PhysicsCollisionObject nodeA, PhysicsCollisionObject nodeB) {
+ this(type, nodeA, nodeB, new Vector3f(), new Vector3f(), new Vector3f(), new Vector3f(), new Vector3f(), 0, 0, 0, 0, 0, 0, 0, null, 0, false, 0, 0, 0, new Vector3f(), new Vector3f());
+ }
+
+ public PhysicsCollisionEvent(int type, PhysicsCollisionObject nodeA, PhysicsCollisionObject nodeB, Vector3f localPointA, Vector3f localPointB, Vector3f positionWorldOnB, Vector3f positionWorldOnA, Vector3f normalWorldOnB, float distance1, float combinedFriction, float combinedRestitution, int partId0, int partId1, int index0, int index1, Object userPersistentData, float appliedImpulse, boolean lateralFrictionInitialized, float appliedImpulseLateral1, float appliedImpulseLateral2, int lifeTime, Vector3f lateralFrictionDir1, Vector3f lateralFrictionDir2) {
+ super(nodeA);
+ this.type = type;
+ this.nodeA = nodeA;
+ this.nodeB = nodeB;
+ this.localPointA = localPointA;
+ this.localPointB = localPointB;
+ this.positionWorldOnB = positionWorldOnB;
+ this.positionWorldOnA = positionWorldOnA;
+ this.normalWorldOnB = normalWorldOnB;
+ this.distance1 = distance1;
+ this.combinedFriction = combinedFriction;
+ this.combinedRestitution = combinedRestitution;
+ this.partId0 = partId0;
+ this.partId1 = partId1;
+ this.index0 = index0;
+ this.index1 = index1;
+ this.userPersistentData = userPersistentData;
+ this.appliedImpulse = appliedImpulse;
+ this.lateralFrictionInitialized = lateralFrictionInitialized;
+ this.appliedImpulseLateral1 = appliedImpulseLateral1;
+ this.appliedImpulseLateral2 = appliedImpulseLateral2;
+ this.lifeTime = lifeTime;
+ this.lateralFrictionDir1 = lateralFrictionDir1;
+ this.lateralFrictionDir2 = lateralFrictionDir2;
+ }
+
+ /**
+ * used by event factory, called when event is destroyed
+ */
+ public void clean() {
+ source = null;
+ this.type = 0;
+ this.nodeA = null;
+ this.nodeB = null;
+// this.localPointA = null;
+// this.localPointB = null;
+// this.positionWorldOnB = null;
+// this.positionWorldOnA = null;
+// this.normalWorldOnB = null;
+// this.distance1 = null
+// this.combinedFriction = null;
+// this.combinedRestitution = null;
+// this.partId0 = null;
+// this.partId1 = null;
+// this.index0 = null;
+// this.index1 = null;
+ this.userPersistentData = null;
+// this.appliedImpulse = null;
+// this.lateralFrictionInitialized = null;
+// this.appliedImpulseLateral1 = null;
+// this.appliedImpulseLateral2 = null;
+// this.lifeTime = null;
+// this.lateralFrictionDir1 = null;
+// this.lateralFrictionDir2 = null;
+ }
+
+ /**
+ * used by event factory, called when event reused
+ */
+ public void refactor(int type, PhysicsCollisionObject source, PhysicsCollisionObject nodeB, Vector3f localPointA, Vector3f localPointB, Vector3f positionWorldOnB, Vector3f positionWorldOnA, Vector3f normalWorldOnB, float distance1, float combinedFriction, float combinedRestitution, int partId0, int partId1, int index0, int index1, Object userPersistentData, float appliedImpulse, boolean lateralFrictionInitialized, float appliedImpulseLateral1, float appliedImpulseLateral2, int lifeTime, Vector3f lateralFrictionDir1, Vector3f lateralFrictionDir2) {
+ this.source = source;
+ this.type = type;
+ this.nodeA = source;
+ this.nodeB = nodeB;
+ this.localPointA.set(localPointA);
+ this.localPointB.set(localPointB);
+ this.positionWorldOnB.set(positionWorldOnB);
+ this.positionWorldOnA.set(positionWorldOnA);
+ this.normalWorldOnB.set(normalWorldOnB);
+ this.distance1 = distance1;
+ this.combinedFriction = combinedFriction;
+ this.combinedRestitution = combinedRestitution;
+ this.partId0 = partId0;
+ this.partId1 = partId1;
+ this.index0 = index0;
+ this.index1 = index1;
+ this.userPersistentData = userPersistentData;
+ this.appliedImpulse = appliedImpulse;
+ this.lateralFrictionInitialized = lateralFrictionInitialized;
+ this.appliedImpulseLateral1 = appliedImpulseLateral1;
+ this.appliedImpulseLateral2 = appliedImpulseLateral2;
+ this.lifeTime = lifeTime;
+ this.lateralFrictionDir1.set(lateralFrictionDir1);
+ this.lateralFrictionDir2.set(lateralFrictionDir2);
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * @return A Spatial if the UserObject of the PhysicsCollisionObject is a Spatial
+ */
+ public Spatial getNodeA() {
+ if (nodeA.getUserObject() instanceof Spatial) {
+ return (Spatial) nodeA.getUserObject();
+ }
+ return null;
+ }
+
+ /**
+ * @return A Spatial if the UserObject of the PhysicsCollisionObject is a Spatial
+ */
+ public Spatial getNodeB() {
+ if (nodeB.getUserObject() instanceof Spatial) {
+ return (Spatial) nodeB.getUserObject();
+ }
+ return null;
+ }
+
+ public PhysicsCollisionObject getObjectA() {
+ return nodeA;
+ }
+
+ public PhysicsCollisionObject getObjectB() {
+ return nodeB;
+ }
+
+ public float getAppliedImpulse() {
+ return appliedImpulse;
+ }
+
+ public float getAppliedImpulseLateral1() {
+ return appliedImpulseLateral1;
+ }
+
+ public float getAppliedImpulseLateral2() {
+ return appliedImpulseLateral2;
+ }
+
+ public float getCombinedFriction() {
+ return combinedFriction;
+ }
+
+ public float getCombinedRestitution() {
+ return combinedRestitution;
+ }
+
+ public float getDistance1() {
+ return distance1;
+ }
+
+ public int getIndex0() {
+ return index0;
+ }
+
+ public int getIndex1() {
+ return index1;
+ }
+
+ public Vector3f getLateralFrictionDir1() {
+ return lateralFrictionDir1;
+ }
+
+ public Vector3f getLateralFrictionDir2() {
+ return lateralFrictionDir2;
+ }
+
+ public boolean isLateralFrictionInitialized() {
+ return lateralFrictionInitialized;
+ }
+
+ public int getLifeTime() {
+ return lifeTime;
+ }
+
+ public Vector3f getLocalPointA() {
+ return localPointA;
+ }
+
+ public Vector3f getLocalPointB() {
+ return localPointB;
+ }
+
+ public Vector3f getNormalWorldOnB() {
+ return normalWorldOnB;
+ }
+
+ public int getPartId0() {
+ return partId0;
+ }
+
+ public int getPartId1() {
+ return partId1;
+ }
+
+ public Vector3f getPositionWorldOnA() {
+ return positionWorldOnA;
+ }
+
+ public Vector3f getPositionWorldOnB() {
+ return positionWorldOnB;
+ }
+
+ public Object getUserPersistentData() {
+ return userPersistentData;
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionEventFactory.java b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionEventFactory.java
new file mode 100644
index 000000000..51d4fe4ca
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionEventFactory.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class PhysicsCollisionEventFactory {
+
+ private ConcurrentLinkedQueue eventBuffer = new ConcurrentLinkedQueue();
+
+ public PhysicsCollisionEvent getEvent(int type, PhysicsCollisionObject source, PhysicsCollisionObject nodeB) {
+ PhysicsCollisionEvent event = eventBuffer.poll();
+ if (event == null) {
+ event = new PhysicsCollisionEvent(type, source, nodeB);
+ }else{
+// event.refactor(type, source, nodeB);
+ }
+ return event;
+ }
+
+ public void recycle(PhysicsCollisionEvent event) {
+ event.clean();
+ eventBuffer.add(event);
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionGroupListener.java b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionGroupListener.java
new file mode 100644
index 000000000..739598c25
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionGroupListener.java
@@ -0,0 +1,25 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.jme3.bullet.collision;
+
+/**
+ *
+ * @author normenhansen
+ */
+public interface PhysicsCollisionGroupListener {
+
+ /**
+ * Called when two physics objects of the registered group are about to collide, called from physics thread.
+ * This is only called when the collision will happen based on the collisionGroup and collideWithGroups
+ * settings in the PhysicsCollisionObject. That is the case when one of the partys has the
+ * collisionGroup of the other in its collideWithGroups set.
+ * @param nodeA CollisionObject #1
+ * @param nodeB CollisionObject #2
+ * @return true if the collision should happen, false otherwise
+ */
+ public boolean collide(PhysicsCollisionObject nodeA, PhysicsCollisionObject nodeB);
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionListener.java b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionListener.java
new file mode 100644
index 000000000..2739c04dc
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionListener.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision;
+
+/**
+ * Interface for Objects that want to be informed about collision events in the physics space
+ * @author normenhansen
+ */
+public interface PhysicsCollisionListener {
+
+ /**
+ * Called when a collision happened in the PhysicsSpace, called from render thread.
+ * Do not store the event object as it will be cleared after the method has finished.
+ * @param event the CollisionEvent
+ */
+ public void collision(PhysicsCollisionEvent event);
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionObject.java b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionObject.java
new file mode 100644
index 000000000..491197c1c
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/PhysicsCollisionObject.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.util.DebugShapeFactory;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.export.Savable;
+import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.debug.Arrow;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Base class for collision objects (PhysicsRigidBody, PhysicsGhostObject)
+ * @author normenhansen
+ */
+public abstract class PhysicsCollisionObject implements Savable {
+
+ protected long objectId = 0;
+ protected Spatial debugShape;
+ protected Arrow debugArrow;
+ protected Geometry debugArrowGeom;
+ protected Material debugMaterialBlue;
+ protected Material debugMaterialRed;
+ protected Material debugMaterialGreen;
+ protected Material debugMaterialYellow;
+ protected CollisionShape collisionShape;
+ public static final int COLLISION_GROUP_NONE = 0x00000000;
+ public static final int COLLISION_GROUP_01 = 0x00000001;
+ public static final int COLLISION_GROUP_02 = 0x00000002;
+ public static final int COLLISION_GROUP_03 = 0x00000004;
+ public static final int COLLISION_GROUP_04 = 0x00000008;
+ public static final int COLLISION_GROUP_05 = 0x00000010;
+ public static final int COLLISION_GROUP_06 = 0x00000020;
+ public static final int COLLISION_GROUP_07 = 0x00000040;
+ public static final int COLLISION_GROUP_08 = 0x00000080;
+ public static final int COLLISION_GROUP_09 = 0x00000100;
+ public static final int COLLISION_GROUP_10 = 0x00000200;
+ public static final int COLLISION_GROUP_11 = 0x00000400;
+ public static final int COLLISION_GROUP_12 = 0x00000800;
+ public static final int COLLISION_GROUP_13 = 0x00001000;
+ public static final int COLLISION_GROUP_14 = 0x00002000;
+ public static final int COLLISION_GROUP_15 = 0x00004000;
+ public static final int COLLISION_GROUP_16 = 0x00008000;
+ protected int collisionGroup = 0x00000001;
+ protected int collisionGroupsMask = 0x00000001;
+ private Object userObject;
+
+ /**
+ * Sets a CollisionShape to this physics object, note that the object should
+ * not be in the physics space when adding a new collision shape as it is rebuilt
+ * on the physics side.
+ * @param collisionShape the CollisionShape to set
+ */
+ public void setCollisionShape(CollisionShape collisionShape) {
+ this.collisionShape = collisionShape;
+ updateDebugShape();
+ }
+
+ /**
+ * @return the CollisionShape of this PhysicsNode, to be able to reuse it with
+ * other physics nodes (increases performance)
+ */
+ public CollisionShape getCollisionShape() {
+ return collisionShape;
+ }
+
+ /**
+ * Returns the collision group for this collision shape
+ * @return
+ */
+ public int getCollisionGroup() {
+ return collisionGroup;
+ }
+
+ /**
+ * Sets the collision group number for this physics object.
+ * The groups are integer bit masks and some pre-made variables are available in CollisionObject.
+ * All physics objects are by default in COLLISION_GROUP_01.
+ * Two object will collide when one of the partys has the
+ * collisionGroup of the other in its collideWithGroups set.
+ * @param collisionGroup the collisionGroup to set
+ */
+ public void setCollisionGroup(int collisionGroup) {
+ this.collisionGroup = collisionGroup;
+ }
+
+ /**
+ * Add a group that this object will collide with.
+ * Two object will collide when one of the partys has the
+ * collisionGroup of the other in its collideWithGroups set.
+ * @param collisionGroup
+ */
+ public void addCollideWithGroup(int collisionGroup) {
+ this.collisionGroupsMask = this.collisionGroupsMask | collisionGroup;
+ }
+
+ /**
+ * Remove a group from the list this object collides with.
+ * @param collisionGroup
+ */
+ public void removeCollideWithGroup(int collisionGroup) {
+ this.collisionGroupsMask = this.collisionGroupsMask & ~collisionGroup;
+ }
+
+ /**
+ * Directly set the bitmask for collision groups that this object collides with.
+ * @param collisionGroup
+ */
+ public void setCollideWithGroups(int collisionGroups) {
+ this.collisionGroupsMask = collisionGroups;
+ }
+
+ /**
+ * Gets the bitmask of collision groups that this object collides with.
+ * @return
+ */
+ public int getCollideWithGroups() {
+ return collisionGroupsMask;
+ }
+
+ /**
+ * Creates a visual debug shape of the current collision shape of this physics object
+ * Does not work with detached physics, please switch to PARALLEL or SEQUENTIAL for debugging
+ * @param manager AssetManager to load the default wireframe material for the debug shape
+ */
+ protected Spatial attachDebugShape(AssetManager manager) {
+ debugMaterialBlue = new Material(manager, "Common/MatDefs/Misc/WireColor.j3md");
+ debugMaterialBlue.setColor("Color", ColorRGBA.Blue);
+ debugMaterialGreen = new Material(manager, "Common/MatDefs/Misc/WireColor.j3md");
+ debugMaterialGreen.setColor("Color", ColorRGBA.Green);
+ debugMaterialRed = new Material(manager, "Common/MatDefs/Misc/WireColor.j3md");
+ debugMaterialRed.setColor("Color", ColorRGBA.Red);
+ debugMaterialYellow = new Material(manager, "Common/MatDefs/Misc/WireColor.j3md");
+ debugMaterialYellow.setColor("Color", ColorRGBA.Yellow);
+ debugArrow = new Arrow(Vector3f.UNIT_XYZ);
+ debugArrowGeom = new Geometry("DebugArrow", debugArrow);
+ debugArrowGeom.setMaterial(debugMaterialGreen);
+ return attachDebugShape();
+ }
+
+ /**
+ * creates a debug shape for this CollisionObject
+ * @param manager
+ * @return
+ */
+ public Spatial createDebugShape(AssetManager manager){
+ return attachDebugShape(manager);
+ }
+
+ protected Spatial attachDebugShape(Material material) {
+ debugMaterialBlue = material;
+ debugMaterialGreen = material;
+ debugMaterialRed = material;
+ debugMaterialYellow = material;
+ debugArrow = new Arrow(Vector3f.UNIT_XYZ);
+ debugArrowGeom = new Geometry("DebugArrow", debugArrow);
+ debugArrowGeom.setMaterial(debugMaterialGreen);
+ return attachDebugShape();
+ }
+
+ public Spatial debugShape() {
+ return debugShape;
+ }
+
+ /**
+ * Creates a visual debug shape of the current collision shape of this physics object
+ * Does not work with detached physics, please switch to PARALLEL or SEQUENTIAL for debugging
+ * @param material Material to use for the debug shape
+ */
+ protected Spatial attachDebugShape() {
+ if (debugShape != null) {
+ detachDebugShape();
+ }
+ Spatial spatial = getDebugShape();
+ this.debugShape = spatial;
+ return debugShape;
+ }
+
+ protected void updateDebugShape() {
+ if (debugShape != null) {
+ detachDebugShape();
+ attachDebugShape();
+ }
+ }
+
+ protected Spatial getDebugShape() {
+ Spatial spatial = DebugShapeFactory.getDebugShape(collisionShape);
+ if (spatial == null) {
+ return new Node("nullnode");
+ }
+ if (spatial instanceof Node) {
+ List children = ((Node) spatial).getChildren();
+ for (Iterator it1 = children.iterator(); it1.hasNext();) {
+ Spatial spatial1 = it1.next();
+ Geometry geom = ((Geometry) spatial1);
+ geom.setMaterial(debugMaterialBlue);
+ geom.setCullHint(Spatial.CullHint.Never);
+ }
+ } else {
+ Geometry geom = ((Geometry) spatial);
+ geom.setMaterial(debugMaterialBlue);
+ geom.setCullHint(Spatial.CullHint.Never);
+ }
+ spatial.setCullHint(Spatial.CullHint.Never);
+ return spatial;
+ }
+
+ /**
+ * Removes the debug shape
+ */
+ public void detachDebugShape() {
+ debugShape = null;
+ }
+
+ /**
+ * @return the userObject
+ */
+ public Object getUserObject() {
+ return userObject;
+ }
+
+ /**
+ * @param userObject the userObject to set
+ */
+ public void setUserObject(Object userObject) {
+ this.userObject = userObject;
+ }
+
+ public long getObjectId(){
+ return objectId;
+ }
+
+ protected native void attachCollisionShape(long objectId, long collisionShapeId);
+
+ @Override
+ public void write(JmeExporter e) throws IOException {
+ OutputCapsule capsule = e.getCapsule(this);
+ capsule.write(collisionGroup, "collisionGroup", 0x00000001);
+ capsule.write(collisionGroupsMask, "collisionGroupsMask", 0x00000001);
+ capsule.write(debugShape, "debugShape", null);
+ capsule.write(collisionShape, "collisionShape", null);
+ }
+
+ @Override
+ public void read(JmeImporter e) throws IOException {
+ InputCapsule capsule = e.getCapsule(this);
+ collisionGroup = capsule.readInt("collisionGroup", 0x00000001);
+ collisionGroupsMask = capsule.readInt("collisionGroupsMask", 0x00000001);
+ debugShape = (Spatial) capsule.readSavable("debugShape", null);
+ CollisionShape shape = (CollisionShape) capsule.readSavable("collisionShape", null);
+ collisionShape = shape;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing CollisionObject {0}", Long.toHexString(objectId));
+ finalizeNative(objectId);
+ }
+
+ protected native void finalizeNative(long objectId);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/PhysicsRayTestResult.java b/engine/src/bullet/com/jme3/bullet/collision/PhysicsRayTestResult.java
new file mode 100644
index 000000000..1941344c3
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/PhysicsRayTestResult.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision;
+
+import com.jme3.math.Vector3f;
+
+/**
+ * Contains the results of a PhysicsSpace rayTest
+ * @author normenhansen
+ */
+public class PhysicsRayTestResult {
+
+ private PhysicsCollisionObject collisionObject;
+ private Vector3f hitNormalLocal;
+ private float hitFraction;
+ private boolean normalInWorldSpace;
+
+ public PhysicsRayTestResult() {
+ }
+
+ public PhysicsRayTestResult(PhysicsCollisionObject collisionObject, Vector3f hitNormalLocal, float hitFraction, boolean normalInWorldSpace) {
+ this.collisionObject = collisionObject;
+ this.hitNormalLocal = hitNormalLocal;
+ this.hitFraction = hitFraction;
+ this.normalInWorldSpace = normalInWorldSpace;
+ }
+
+ /**
+ * @return the collisionObject
+ */
+ public PhysicsCollisionObject getCollisionObject() {
+ return collisionObject;
+ }
+
+ /**
+ * @return the hitNormalLocal
+ */
+ public Vector3f getHitNormalLocal() {
+ return hitNormalLocal;
+ }
+
+ /**
+ * @return the hitFraction
+ */
+ public float getHitFraction() {
+ return hitFraction;
+ }
+
+ /**
+ * @return the normalInWorldSpace
+ */
+ public boolean isNormalInWorldSpace() {
+ return normalInWorldSpace;
+ }
+
+ public void fill(PhysicsCollisionObject collisionObject, Vector3f hitNormalLocal, float hitFraction, boolean normalInWorldSpace) {
+ this.collisionObject = collisionObject;
+ this.hitNormalLocal = hitNormalLocal;
+ this.hitFraction = hitFraction;
+ this.normalInWorldSpace = normalInWorldSpace;
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/PhysicsSweepTestResult.java b/engine/src/bullet/com/jme3/bullet/collision/PhysicsSweepTestResult.java
new file mode 100644
index 000000000..d513204eb
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/PhysicsSweepTestResult.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision;
+
+import com.jme3.math.Vector3f;
+
+/**
+ * Contains the results of a PhysicsSpace rayTest
+ * @author normenhansen
+ */
+public class PhysicsSweepTestResult {
+
+ private PhysicsCollisionObject collisionObject;
+ private Vector3f hitNormalLocal;
+ private float hitFraction;
+ private boolean normalInWorldSpace;
+
+ public PhysicsSweepTestResult() {
+ }
+
+ public PhysicsSweepTestResult(PhysicsCollisionObject collisionObject, Vector3f hitNormalLocal, float hitFraction, boolean normalInWorldSpace) {
+ this.collisionObject = collisionObject;
+ this.hitNormalLocal = hitNormalLocal;
+ this.hitFraction = hitFraction;
+ this.normalInWorldSpace = normalInWorldSpace;
+ }
+
+ /**
+ * @return the collisionObject
+ */
+ public PhysicsCollisionObject getCollisionObject() {
+ return collisionObject;
+ }
+
+ /**
+ * @return the hitNormalLocal
+ */
+ public Vector3f getHitNormalLocal() {
+ return hitNormalLocal;
+ }
+
+ /**
+ * @return the hitFraction
+ */
+ public float getHitFraction() {
+ return hitFraction;
+ }
+
+ /**
+ * @return the normalInWorldSpace
+ */
+ public boolean isNormalInWorldSpace() {
+ return normalInWorldSpace;
+ }
+
+ public void fill(PhysicsCollisionObject collisionObject, Vector3f hitNormalLocal, float hitFraction, boolean normalInWorldSpace) {
+ this.collisionObject = collisionObject;
+ this.hitNormalLocal = hitNormalLocal;
+ this.hitFraction = hitFraction;
+ this.normalInWorldSpace = normalInWorldSpace;
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/RagdollCollisionListener.java b/engine/src/bullet/com/jme3/bullet/collision/RagdollCollisionListener.java
new file mode 100644
index 000000000..44805a428
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/RagdollCollisionListener.java
@@ -0,0 +1,17 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.collision;
+
+import com.jme3.animation.Bone;
+
+/**
+ *
+ * @author Nehon
+ */
+public interface RagdollCollisionListener {
+
+ public void collide(Bone bone, PhysicsCollisionObject object, PhysicsCollisionEvent event);
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/BoxCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/BoxCollisionShape.java
new file mode 100644
index 000000000..94d6ea4f3
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/BoxCollisionShape.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.Vector3f;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Basic box collision shape
+ * @author normenhansen
+ */
+public class BoxCollisionShape extends CollisionShape {
+
+ private Vector3f halfExtents;
+
+ public BoxCollisionShape() {
+ }
+
+ /**
+ * creates a collision box from the given halfExtents
+ * @param halfExtents the halfExtents of the CollisionBox
+ */
+ public BoxCollisionShape(Vector3f halfExtents) {
+ this.halfExtents = halfExtents;
+ createShape();
+ }
+
+ public final Vector3f getHalfExtents() {
+ return halfExtents;
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(halfExtents, "halfExtents", new Vector3f(1, 1, 1));
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ Vector3f halfExtents = (Vector3f) capsule.readSavable("halfExtents", new Vector3f(1, 1, 1));
+ this.halfExtents = halfExtents;
+ createShape();
+ }
+
+ protected void createShape() {
+ objectId = createShape(halfExtents);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+// cShape = new BoxShape(Converter.convert(halfExtents));
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(Vector3f halfExtents);
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/CapsuleCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/CapsuleCollisionShape.java
new file mode 100644
index 000000000..2f5ccc573
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/CapsuleCollisionShape.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Basic capsule collision shape
+ * @author normenhansen
+ */
+public class CapsuleCollisionShape extends CollisionShape{
+ protected float radius,height;
+ protected int axis;
+
+ public CapsuleCollisionShape() {
+ }
+
+ /**
+ * creates a new CapsuleCollisionShape with the given radius and height
+ * @param radius the radius of the capsule
+ * @param height the height of the capsule
+ */
+ public CapsuleCollisionShape(float radius, float height) {
+ this.radius=radius;
+ this.height=height;
+ this.axis=1;
+ createShape();
+ }
+
+ /**
+ * creates a capsule shape around the given axis (0=X,1=Y,2=Z)
+ * @param radius
+ * @param height
+ * @param axis
+ */
+ public CapsuleCollisionShape(float radius, float height, int axis) {
+ this.radius=radius;
+ this.height=height;
+ this.axis=axis;
+ createShape();
+ }
+
+ public float getRadius() {
+ return radius;
+ }
+
+ public float getHeight() {
+ return height;
+ }
+
+ public int getAxis() {
+ return axis;
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(radius, "radius", 0.5f);
+ capsule.write(height, "height", 1);
+ capsule.write(axis, "axis", 1);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ radius = capsule.readFloat("radius", 0.5f);
+ height = capsule.readFloat("height", 0.5f);
+ axis = capsule.readInt("axis", 1);
+ createShape();
+ }
+
+ protected void createShape(){
+ objectId = createShape(axis, radius, height);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+ setScale(scale);
+ setMargin(margin);
+// switch(axis){
+// case 0:
+// objectId=new CapsuleShapeX(radius,height);
+// break;
+// case 1:
+// objectId=new CapsuleShape(radius,height);
+// break;
+// case 2:
+// objectId=new CapsuleShapeZ(radius,height);
+// break;
+// }
+// objectId.setLocalScaling(Converter.convert(getScale()));
+// objectId.setMargin(margin);
+ }
+
+ private native long createShape(int axis, float radius, float height);
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/CollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/CollisionShape.java
new file mode 100644
index 000000000..81454ea95
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/CollisionShape.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.Vector3f;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import com.jme3.export.Savable;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This Object holds information about a jbullet CollisionShape to be able to reuse
+ * CollisionShapes (as suggested in bullet manuals)
+ * TODO: add static methods to create shapes from nodes (like jbullet-jme constructor)
+ * @author normenhansen
+ */
+public abstract class CollisionShape implements Savable {
+
+ protected long objectId = 0;
+ protected Vector3f scale = new Vector3f(1, 1, 1);
+ protected float margin = 0.0f;
+
+ public CollisionShape() {
+ }
+
+// /**
+// * used internally, not safe
+// */
+// public void calculateLocalInertia(long objectId, float mass) {
+// if (this.objectId == 0) {
+// return;
+// }
+//// if (this instanceof MeshCollisionShape) {
+//// vector.set(0, 0, 0);
+//// } else {
+// calculateLocalInertia(objectId, this.objectId, mass);
+//// objectId.calculateLocalInertia(mass, vector);
+//// }
+// }
+//
+// private native void calculateLocalInertia(long objectId, long shapeId, float mass);
+
+ /**
+ * used internally
+ */
+ public long getObjectId() {
+ return objectId;
+ }
+
+ /**
+ * used internally
+ */
+ public void setObjectId(long id) {
+ this.objectId = id;
+ }
+
+ public void setScale(Vector3f scale) {
+ this.scale.set(scale);
+ setLocalScaling(objectId, scale);
+ }
+
+ public Vector3f getScale() {
+ return scale;
+ }
+
+ public float getMargin() {
+ return getMargin(objectId);
+ }
+
+ private native float getMargin(long objectId);
+
+ public void setMargin(float margin) {
+ setMargin(objectId, margin);
+ this.margin = margin;
+ }
+
+ private native void setLocalScaling(long obectId, Vector3f scale);
+
+ private native void setMargin(long objectId, float margin);
+
+ public void write(JmeExporter ex) throws IOException {
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(scale, "scale", new Vector3f(1, 1, 1));
+ capsule.write(getMargin(), "margin", 0.0f);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ InputCapsule capsule = im.getCapsule(this);
+ this.scale = (Vector3f) capsule.readSavable("scale", new Vector3f(1, 1, 1));
+ this.margin = capsule.readFloat("margin", 0.0f);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing CollisionShape {0}", Long.toHexString(objectId));
+ finalizeNative(objectId);
+ }
+
+ private native void finalizeNative(long objectId);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/CompoundCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/CompoundCollisionShape.java
new file mode 100644
index 000000000..f09d35ef7
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/CompoundCollisionShape.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.bullet.collision.shapes.infos.ChildCollisionShape;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Vector3f;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * A CompoundCollisionShape allows combining multiple base shapes
+ * to generate a more sophisticated shape.
+ * @author normenhansen
+ */
+public class CompoundCollisionShape extends CollisionShape {
+
+ protected ArrayList children = new ArrayList();
+
+ public CompoundCollisionShape() {
+ objectId = createShape();//new CompoundShape();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+ }
+
+ /**
+ * adds a child shape at the given local translation
+ * @param shape the child shape to add
+ * @param location the local location of the child shape
+ */
+ public void addChildShape(CollisionShape shape, Vector3f location) {
+// Transform transA = new Transform(Converter.convert(new Matrix3f()));
+// Converter.convert(location, transA.origin);
+// children.add(new ChildCollisionShape(location.clone(), new Matrix3f(), shape));
+// ((CompoundShape) objectId).addChildShape(transA, shape.getObjectId());
+ addChildShape(shape, location, new Matrix3f());
+ }
+
+ /**
+ * adds a child shape at the given local translation
+ * @param shape the child shape to add
+ * @param location the local location of the child shape
+ */
+ public void addChildShape(CollisionShape shape, Vector3f location, Matrix3f rotation) {
+ if(shape instanceof CompoundCollisionShape){
+ throw new IllegalStateException("CompoundCollisionShapes cannot have CompoundCollisionShapes as children!");
+ }
+// Transform transA = new Transform(Converter.convert(rotation));
+// Converter.convert(location, transA.origin);
+// Converter.convert(rotation, transA.basis);
+ children.add(new ChildCollisionShape(location.clone(), rotation.clone(), shape));
+ addChildShape(objectId, shape.getObjectId(), location, rotation);
+// ((CompoundShape) objectId).addChildShape(transA, shape.getObjectId());
+ }
+
+ private void addChildShapeDirect(CollisionShape shape, Vector3f location, Matrix3f rotation) {
+ if(shape instanceof CompoundCollisionShape){
+ throw new IllegalStateException("CompoundCollisionShapes cannot have CompoundCollisionShapes as children!");
+ }
+// Transform transA = new Transform(Converter.convert(rotation));
+// Converter.convert(location, transA.origin);
+// Converter.convert(rotation, transA.basis);
+ addChildShape(objectId, shape.getObjectId(), location, rotation);
+// ((CompoundShape) objectId).addChildShape(transA, shape.getObjectId());
+ }
+
+ /**
+ * removes a child shape
+ * @param shape the child shape to remove
+ */
+ public void removeChildShape(CollisionShape shape) {
+ removeChildShape(objectId, shape.getObjectId());
+// ((CompoundShape) objectId).removeChildShape(shape.getObjectId());
+ for (Iterator it = children.iterator(); it.hasNext();) {
+ ChildCollisionShape childCollisionShape = it.next();
+ if (childCollisionShape.shape == shape) {
+ it.remove();
+ }
+ }
+ }
+
+ public List getChildren() {
+ return children;
+ }
+
+ /**
+ * WARNING - CompoundCollisionShape scaling has no effect.
+ */
+ @Override
+ public void setScale(Vector3f scale) {
+ Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "CompoundCollisionShape cannot be scaled");
+ }
+
+ private native long createShape();
+
+ private native long addChildShape(long objectId, long childId, Vector3f location, Matrix3f rotation);
+
+ private native long removeChildShape(long objectId, long childId);
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.writeSavableArrayList(children, "children", new ArrayList());
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ children = capsule.readSavableArrayList("children", new ArrayList());
+ setScale(scale);
+ setMargin(margin);
+ loadChildren();
+ }
+
+ private void loadChildren() {
+ for (Iterator it = children.iterator(); it.hasNext();) {
+ ChildCollisionShape child = it.next();
+ addChildShapeDirect(child.shape, child.location, child.rotation);
+ }
+ }
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/ConeCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/ConeCollisionShape.java
new file mode 100644
index 000000000..f01b58588
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/ConeCollisionShape.java
@@ -0,0 +1,81 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class ConeCollisionShape extends CollisionShape {
+
+ protected float radius;
+ protected float height;
+ protected int axis;
+
+ public ConeCollisionShape() {
+ }
+
+ public ConeCollisionShape(float radius, float height, int axis) {
+ this.radius = radius;
+ this.height = radius;
+ this.axis = axis;
+ createShape();
+ }
+
+ public ConeCollisionShape(float radius, float height) {
+ this.radius = radius;
+ this.height = radius;
+ this.axis = PhysicsSpace.AXIS_Y;
+ createShape();
+ }
+
+ public float getRadius() {
+ return radius;
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(radius, "radius", 0.5f);
+ capsule.write(height, "height", 0.5f);
+ capsule.write(axis, "axis", 0.5f);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ radius = capsule.readFloat("radius", 0.5f);
+ radius = capsule.readFloat("height", 0.5f);
+ radius = capsule.readFloat("axis", 0.5f);
+ createShape();
+ }
+
+ protected void createShape() {
+ objectId = createShape(axis, radius, height);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+// if (axis == PhysicsSpace.AXIS_X) {
+// objectId = new ConeShapeX(radius, height);
+// } else if (axis == PhysicsSpace.AXIS_Y) {
+// objectId = new ConeShape(radius, height);
+// } else if (axis == PhysicsSpace.AXIS_Z) {
+// objectId = new ConeShapeZ(radius, height);
+// }
+// objectId.setLocalScaling(Converter.convert(getScale()));
+// objectId.setMargin(margin);
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(int axis, float radius, float height);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/CylinderCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/CylinderCollisionShape.java
new file mode 100644
index 000000000..edb22da3d
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/CylinderCollisionShape.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.Vector3f;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Basic cylinder collision shape
+ * @author normenhansen
+ */
+public class CylinderCollisionShape extends CollisionShape {
+
+ protected Vector3f halfExtents;
+ protected int axis;
+
+ public CylinderCollisionShape() {
+ }
+
+ /**
+ * creates a cylinder shape from the given halfextents
+ * @param halfExtents the halfextents to use
+ */
+ public CylinderCollisionShape(Vector3f halfExtents) {
+ this.halfExtents = halfExtents;
+ this.axis = 2;
+ createShape();
+ }
+
+ /**
+ * Creates a cylinder shape around the given axis from the given halfextents
+ * @param halfExtents the halfextents to use
+ * @param axis (0=X,1=Y,2=Z)
+ */
+ public CylinderCollisionShape(Vector3f halfExtents, int axis) {
+ this.halfExtents = halfExtents;
+ this.axis = axis;
+ createShape();
+ }
+
+ public final Vector3f getHalfExtents() {
+ return halfExtents;
+ }
+
+ public int getAxis() {
+ return axis;
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(halfExtents, "halfExtents", new Vector3f(0.5f, 0.5f, 0.5f));
+ capsule.write(axis, "axis", 1);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ halfExtents = (Vector3f) capsule.readSavable("halfExtents", new Vector3f(0.5f, 0.5f, 0.5f));
+ axis = capsule.readInt("axis", 1);
+ createShape();
+ }
+
+ protected void createShape() {
+ objectId = createShape(axis, halfExtents);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+// switch (axis) {
+// case 0:
+// objectId = new CylinderShapeX(Converter.convert(halfExtents));
+// break;
+// case 1:
+// objectId = new CylinderShape(Converter.convert(halfExtents));
+// break;
+// case 2:
+// objectId = new CylinderShapeZ(Converter.convert(halfExtents));
+// break;
+// }
+// objectId.setLocalScaling(Converter.convert(getScale()));
+// objectId.setMargin(margin);
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(int axis, Vector3f halfExtents);
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/GImpactCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/GImpactCollisionShape.java
new file mode 100644
index 000000000..2e253d1e9
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/GImpactCollisionShape.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.scene.Mesh;
+import com.jme3.bullet.util.NativeMeshUtil;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import com.jme3.scene.VertexBuffer.Type;
+import com.jme3.scene.mesh.IndexBuffer;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Basic mesh collision shape
+ * @author normenhansen
+ */
+public class GImpactCollisionShape extends CollisionShape {
+
+// protected Vector3f worldScale;
+ protected int numVertices, numTriangles, vertexStride, triangleIndexStride;
+ protected ByteBuffer triangleIndexBase, vertexBase;
+ protected long meshId = 0;
+// protected IndexedMesh bulletMesh;
+
+ public GImpactCollisionShape() {
+ }
+
+ /**
+ * creates a collision shape from the given Mesh
+ * @param mesh the Mesh to use
+ */
+ public GImpactCollisionShape(Mesh mesh) {
+ createCollisionMesh(mesh);
+ }
+
+ private void createCollisionMesh(Mesh mesh) {
+ triangleIndexBase = ByteBuffer.allocateDirect(mesh.getTriangleCount() * 3 * 4).order(ByteOrder.nativeOrder());
+ vertexBase = ByteBuffer.allocateDirect(mesh.getVertexCount() * 3 * 4).order(ByteOrder.nativeOrder());
+// triangleIndexBase = ByteBuffer.allocate(mesh.getTriangleCount() * 3 * 4);
+// vertexBase = ByteBuffer.allocate(mesh.getVertexCount() * 3 * 4);
+ numVertices = mesh.getVertexCount();
+ vertexStride = 12; //3 verts * 4 bytes per.
+ numTriangles = mesh.getTriangleCount();
+ triangleIndexStride = 12; //3 index entries * 4 bytes each.
+
+ IndexBuffer indices = mesh.getIndexBuffer();
+ FloatBuffer vertices = mesh.getFloatBuffer(Type.Position);
+ vertices.rewind();
+
+ int verticesLength = mesh.getVertexCount() * 3;
+ for (int i = 0; i < verticesLength; i++) {
+ float tempFloat = vertices.get();
+ vertexBase.putFloat(tempFloat);
+ }
+
+ int indicesLength = mesh.getTriangleCount() * 3;
+ for (int i = 0; i < indicesLength; i++) {
+ triangleIndexBase.putInt(indices.get(i));
+ }
+ vertices.rewind();
+ vertices.clear();
+
+ createShape();
+ }
+
+// /**
+// * creates a jme mesh from the collision shape, only needed for debugging
+// */
+// public Mesh createJmeMesh() {
+// return Converter.convert(bulletMesh);
+// }
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+// capsule.write(worldScale, "worldScale", new Vector3f(1, 1, 1));
+ capsule.write(numVertices, "numVertices", 0);
+ capsule.write(numTriangles, "numTriangles", 0);
+ capsule.write(vertexStride, "vertexStride", 0);
+ capsule.write(triangleIndexStride, "triangleIndexStride", 0);
+
+ capsule.write(triangleIndexBase.array(), "triangleIndexBase", new byte[0]);
+ capsule.write(vertexBase.array(), "vertexBase", new byte[0]);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+// worldScale = (Vector3f) capsule.readSavable("worldScale", new Vector3f(1, 1, 1));
+ numVertices = capsule.readInt("numVertices", 0);
+ numTriangles = capsule.readInt("numTriangles", 0);
+ vertexStride = capsule.readInt("vertexStride", 0);
+ triangleIndexStride = capsule.readInt("triangleIndexStride", 0);
+
+ triangleIndexBase = ByteBuffer.wrap(capsule.readByteArray("triangleIndexBase", new byte[0]));
+ vertexBase = ByteBuffer.wrap(capsule.readByteArray("vertexBase", new byte[0]));
+ createShape();
+ }
+
+ protected void createShape() {
+// bulletMesh = new IndexedMesh();
+// bulletMesh.numVertices = numVertices;
+// bulletMesh.numTriangles = numTriangles;
+// bulletMesh.vertexStride = vertexStride;
+// bulletMesh.triangleIndexStride = triangleIndexStride;
+// bulletMesh.triangleIndexBase = triangleIndexBase;
+// bulletMesh.vertexBase = vertexBase;
+// bulletMesh.triangleIndexBase = triangleIndexBase;
+// TriangleIndexVertexArray tiv = new TriangleIndexVertexArray(numTriangles, triangleIndexBase, triangleIndexStride, numVertices, vertexBase, vertexStride);
+// objectId = new GImpactMeshShape(tiv);
+// objectId.setLocalScaling(Converter.convert(worldScale));
+// ((GImpactMeshShape)objectId).updateBound();
+// objectId.setLocalScaling(Converter.convert(getScale()));
+// objectId.setMargin(margin);
+ meshId = NativeMeshUtil.createTriangleIndexVertexArray(triangleIndexBase, vertexBase, numTriangles, numVertices, vertexStride, triangleIndexStride);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Mesh {0}", Long.toHexString(meshId));
+ objectId = createShape(meshId);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(long meshId);
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing Mesh {0}", Long.toHexString(meshId));
+ finalizeNative(meshId);
+ }
+
+ private native void finalizeNative(long objectId);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/HeightfieldCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/HeightfieldCollisionShape.java
new file mode 100644
index 000000000..2c2da1323
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/HeightfieldCollisionShape.java
@@ -0,0 +1,145 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.FastMath;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Mesh;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Uses Bullet Physics Heightfield terrain collision system. This is MUCH faster
+ * than using a regular mesh.
+ * There are a couple tricks though:
+ * -No rotation or translation is supported.
+ * -The collision bbox must be centered around 0,0,0 with the height above and below the y-axis being
+ * equal on either side. If not, the whole collision box is shifted vertically and things don't collide
+ * as they should.
+ *
+ * @author Brent Owens
+ */
+public class HeightfieldCollisionShape extends CollisionShape {
+
+ protected int heightStickWidth;
+ protected int heightStickLength;
+ protected float[] heightfieldData;
+ protected float heightScale;
+ protected float minHeight;
+ protected float maxHeight;
+ protected int upAxis;
+ protected boolean flipQuadEdges;
+ protected ByteBuffer bbuf;
+// protected FloatBuffer fbuf;
+
+ public HeightfieldCollisionShape() {
+ }
+
+ public HeightfieldCollisionShape(float[] heightmap) {
+ createCollisionHeightfield(heightmap, Vector3f.UNIT_XYZ);
+ }
+
+ public HeightfieldCollisionShape(float[] heightmap, Vector3f scale) {
+ createCollisionHeightfield(heightmap, scale);
+ }
+
+ protected void createCollisionHeightfield(float[] heightmap, Vector3f worldScale) {
+ this.scale = worldScale;
+ this.heightScale = 1;//don't change away from 1, we use worldScale instead to scale
+
+ this.heightfieldData = heightmap;
+
+ float min = heightfieldData[0];
+ float max = heightfieldData[0];
+ // calculate min and max height
+ for (int i = 0; i < heightfieldData.length; i++) {
+ if (heightfieldData[i] < min) {
+ min = heightfieldData[i];
+ }
+ if (heightfieldData[i] > max) {
+ max = heightfieldData[i];
+ }
+ }
+ // we need to center the terrain collision box at 0,0,0 for BulletPhysics. And to do that we need to set the
+ // min and max height to be equal on either side of the y axis, otherwise it gets shifted and collision is incorrect.
+ if (max < 0) {
+ max = -min;
+ } else {
+ if (Math.abs(max) > Math.abs(min)) {
+ min = -max;
+ } else {
+ max = -min;
+ }
+ }
+ this.minHeight = min;
+ this.maxHeight = max;
+
+ this.upAxis = 1;
+ this.flipQuadEdges = false;
+
+ heightStickWidth = (int) FastMath.sqrt(heightfieldData.length);
+ heightStickLength = heightStickWidth;
+
+
+ createShape();
+ }
+
+ protected void createShape() {
+ bbuf = ByteBuffer.allocateDirect(heightfieldData.length * 4).order(ByteOrder.nativeOrder());
+// fbuf = bbuf.asFloatBuffer();//FloatBuffer.wrap(heightfieldData);
+// fbuf.rewind();
+// fbuf.put(heightfieldData);
+ for (int i = 0; i < heightfieldData.length; i++) {
+ float f = heightfieldData[i];
+ bbuf.putFloat(f);
+ }
+// fbuf.rewind();
+ objectId = createShape(heightStickWidth, heightStickLength, bbuf, heightScale, minHeight, maxHeight, upAxis, flipQuadEdges);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(int heightStickWidth, int heightStickLength, ByteBuffer heightfieldData, float heightScale, float minHeight, float maxHeight, int upAxis, boolean flipQuadEdges);
+
+ public Mesh createJmeMesh() {
+ //TODO return Converter.convert(bulletMesh);
+ return null;
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(heightStickWidth, "heightStickWidth", 0);
+ capsule.write(heightStickLength, "heightStickLength", 0);
+ capsule.write(heightScale, "heightScale", 0);
+ capsule.write(minHeight, "minHeight", 0);
+ capsule.write(maxHeight, "maxHeight", 0);
+ capsule.write(upAxis, "upAxis", 1);
+ capsule.write(heightfieldData, "heightfieldData", new float[0]);
+ capsule.write(flipQuadEdges, "flipQuadEdges", false);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ heightStickWidth = capsule.readInt("heightStickWidth", 0);
+ heightStickLength = capsule.readInt("heightStickLength", 0);
+ heightScale = capsule.readFloat("heightScale", 0);
+ minHeight = capsule.readFloat("minHeight", 0);
+ maxHeight = capsule.readFloat("maxHeight", 0);
+ upAxis = capsule.readInt("upAxis", 1);
+ heightfieldData = capsule.readFloatArray("heightfieldData", new float[0]);
+ flipQuadEdges = capsule.readBoolean("flipQuadEdges", false);
+ createShape();
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/HullCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/HullCollisionShape.java
new file mode 100644
index 000000000..3f27150ba
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/HullCollisionShape.java
@@ -0,0 +1,98 @@
+package com.jme3.bullet.collision.shapes;
+
+import java.nio.FloatBuffer;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.VertexBuffer.Type;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class HullCollisionShape extends CollisionShape {
+
+ private float[] points;
+// protected FloatBuffer fbuf;
+
+ public HullCollisionShape() {
+ }
+
+ public HullCollisionShape(Mesh mesh) {
+ this.points = getPoints(mesh);
+ createShape();
+ }
+
+ public HullCollisionShape(float[] points) {
+ this.points = points;
+ createShape();
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(points, "points", null);
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+
+ // for backwards compatability
+ Mesh mesh = (Mesh) capsule.readSavable("hullMesh", null);
+ if (mesh != null) {
+ this.points = getPoints(mesh);
+ } else {
+ this.points = capsule.readFloatArray("points", null);
+
+ }
+// fbuf = ByteBuffer.allocateDirect(points.length * 4).asFloatBuffer();
+// fbuf.put(points);
+// fbuf = FloatBuffer.wrap(points).order(ByteOrder.nativeOrder()).asFloatBuffer();
+ createShape();
+ }
+
+ protected void createShape() {
+// ObjectArrayList pointList = new ObjectArrayList();
+// for (int i = 0; i < points.length; i += 3) {
+// pointList.add(new Vector3f(points[i], points[i + 1], points[i + 2]));
+// }
+// objectId = new ConvexHullShape(pointList);
+// objectId.setLocalScaling(Converter.convert(getScale()));
+// objectId.setMargin(margin);
+ ByteBuffer bbuf=ByteBuffer.allocateDirect(points.length * 4).order(ByteOrder.nativeOrder());
+// fbuf = bbuf.asFloatBuffer();
+// fbuf.rewind();
+// fbuf.put(points);
+ for (int i = 0; i < points.length; i++) {
+ float f = points[i];
+ bbuf.putFloat(f);
+ }
+ bbuf.rewind();
+ objectId = createShape(bbuf);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(ByteBuffer points);
+
+ protected float[] getPoints(Mesh mesh) {
+ FloatBuffer vertices = mesh.getFloatBuffer(Type.Position);
+ vertices.rewind();
+ int components = mesh.getVertexCount() * 3;
+ float[] pointsArray = new float[components];
+ for (int i = 0; i < components; i += 3) {
+ pointsArray[i] = vertices.get();
+ pointsArray[i + 1] = vertices.get();
+ pointsArray[i + 2] = vertices.get();
+ }
+ return pointsArray;
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/MeshCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/MeshCollisionShape.java
new file mode 100644
index 000000000..b7813a650
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/MeshCollisionShape.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.bullet.util.NativeMeshUtil;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.scene.Mesh;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import com.jme3.scene.VertexBuffer.Type;
+import com.jme3.scene.mesh.IndexBuffer;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Basic mesh collision shape
+ * @author normenhansen
+ */
+public class MeshCollisionShape extends CollisionShape {
+
+ protected int numVertices, numTriangles, vertexStride, triangleIndexStride;
+ protected ByteBuffer triangleIndexBase, vertexBase;
+ protected long meshId = 0;
+
+ public MeshCollisionShape() {
+ }
+
+ /**
+ * creates a collision shape from the given TriMesh
+ * @param mesh the TriMesh to use
+ */
+ public MeshCollisionShape(Mesh mesh) {
+ createCollisionMesh(mesh);
+ }
+
+ private void createCollisionMesh(Mesh mesh) {
+ triangleIndexBase = ByteBuffer.allocateDirect(mesh.getTriangleCount() * 3 * 4).order(ByteOrder.nativeOrder());
+ vertexBase = ByteBuffer.allocateDirect(mesh.getVertexCount() * 3 * 4).order(ByteOrder.nativeOrder());
+ numVertices = mesh.getVertexCount();
+ vertexStride = 12; //3 verts * 4 bytes per.
+ numTriangles = mesh.getTriangleCount();
+ triangleIndexStride = 12; //3 index entries * 4 bytes each.
+
+ IndexBuffer indices = mesh.getIndexBuffer();
+ FloatBuffer vertices = mesh.getFloatBuffer(Type.Position);
+ vertices.rewind();
+
+ int verticesLength = mesh.getVertexCount() * 3;
+ for (int i = 0; i < verticesLength; i++) {
+ float tempFloat = vertices.get();
+ vertexBase.putFloat(tempFloat);
+ }
+
+ int indicesLength = mesh.getTriangleCount() * 3;
+ for (int i = 0; i < indicesLength; i++) {
+ triangleIndexBase.putInt(indices.get(i));
+ }
+ vertices.rewind();
+ vertices.clear();
+
+ createShape();
+ }
+
+ /**
+ * creates a jme mesh from the collision shape, only needed for debugging
+ */
+// public Mesh createJmeMesh(){
+// return Converter.convert(bulletMesh);
+// }
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(numVertices, "numVertices", 0);
+ capsule.write(numTriangles, "numTriangles", 0);
+ capsule.write(vertexStride, "vertexStride", 0);
+ capsule.write(triangleIndexStride, "triangleIndexStride", 0);
+
+ capsule.write(triangleIndexBase.array(), "triangleIndexBase", new byte[0]);
+ capsule.write(vertexBase.array(), "vertexBase", new byte[0]);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ numVertices = capsule.readInt("numVertices", 0);
+ numTriangles = capsule.readInt("numTriangles", 0);
+ vertexStride = capsule.readInt("vertexStride", 0);
+ triangleIndexStride = capsule.readInt("triangleIndexStride", 0);
+
+ triangleIndexBase = ByteBuffer.wrap(capsule.readByteArray("triangleIndexBase", new byte[0]));
+ vertexBase = ByteBuffer.wrap(capsule.readByteArray("vertexBase", new byte[0])).order(ByteOrder.nativeOrder());
+ createShape();
+ }
+
+ protected void createShape() {
+// bulletMesh = new IndexedMesh();
+// bulletMesh.numVertices = numVertices;
+// bulletMesh.numTriangles = numTriangles;
+// bulletMesh.vertexStride = vertexStride;
+// bulletMesh.triangleIndexStride = triangleIndexStride;
+// bulletMesh.triangleIndexBase = triangleIndexBase;
+// bulletMesh.vertexBase = vertexBase;
+// bulletMesh.triangleIndexBase = triangleIndexBase;
+// TriangleIndexVertexArray tiv = new TriangleIndexVertexArray(numTriangles, triangleIndexBase, triangleIndexStride, numVertices, vertexBase, vertexStride);
+// objectId = new BvhTriangleMeshShape(tiv, true);
+// objectId.setLocalScaling(Converter.convert(getScale()));
+// objectId.setMargin(margin);
+ meshId = NativeMeshUtil.createTriangleIndexVertexArray(triangleIndexBase, vertexBase, numTriangles, numVertices, vertexStride, triangleIndexStride);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Mesh {0}", Long.toHexString(meshId));
+ objectId = createShape(meshId);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(long meshId);
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing Mesh {0}", Long.toHexString(meshId));
+ finalizeNative(meshId);
+ }
+
+ private native void finalizeNative(long objectId);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/PlaneCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/PlaneCollisionShape.java
new file mode 100644
index 000000000..3e949bd63
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/PlaneCollisionShape.java
@@ -0,0 +1,66 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.Plane;
+import com.jme3.math.Vector3f;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class PlaneCollisionShape extends CollisionShape{
+ private Plane plane;
+
+ public PlaneCollisionShape() {
+ }
+
+ /**
+ * Creates a plane Collision shape
+ * @param plane the plane that defines the shape
+ */
+ public PlaneCollisionShape(Plane plane) {
+ this.plane = plane;
+ createShape();
+ }
+
+ public final Plane getPlane() {
+ return plane;
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(plane, "collisionPlane", new Plane());
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ plane = (Plane) capsule.readSavable("collisionPlane", new Plane());
+ createShape();
+ }
+
+ protected void createShape() {
+ objectId = createShape(plane.getNormal(), plane.getConstant());
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+// objectId = new StaticPlaneShape(Converter.convert(plane.getNormal()),plane.getConstant());
+// objectId.setLocalScaling(Converter.convert(getScale()));
+// objectId.setMargin(margin);
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(Vector3f normal, float constant);
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/SimplexCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/SimplexCollisionShape.java
new file mode 100644
index 000000000..cef33d708
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/SimplexCollisionShape.java
@@ -0,0 +1,100 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.Vector3f;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * A simple point, line, triangle or quad collisionShape based on one to four points-
+ * @author normenhansen
+ */
+public class SimplexCollisionShape extends CollisionShape {
+
+ private Vector3f vector1, vector2, vector3, vector4;
+
+ public SimplexCollisionShape() {
+ }
+
+ public SimplexCollisionShape(Vector3f point1, Vector3f point2, Vector3f point3, Vector3f point4) {
+ vector1 = point1;
+ vector2 = point2;
+ vector3 = point3;
+ vector4 = point4;
+ createShape();
+ }
+
+ public SimplexCollisionShape(Vector3f point1, Vector3f point2, Vector3f point3) {
+ vector1 = point1;
+ vector2 = point2;
+ vector3 = point3;
+ createShape();
+ }
+
+ public SimplexCollisionShape(Vector3f point1, Vector3f point2) {
+ vector1 = point1;
+ vector2 = point2;
+ createShape();
+ }
+
+ public SimplexCollisionShape(Vector3f point1) {
+ vector1 = point1;
+ createShape();
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(vector1, "simplexPoint1", null);
+ capsule.write(vector2, "simplexPoint2", null);
+ capsule.write(vector3, "simplexPoint3", null);
+ capsule.write(vector4, "simplexPoint4", null);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ vector1 = (Vector3f) capsule.readSavable("simplexPoint1", null);
+ vector2 = (Vector3f) capsule.readSavable("simplexPoint2", null);
+ vector3 = (Vector3f) capsule.readSavable("simplexPoint3", null);
+ vector4 = (Vector3f) capsule.readSavable("simplexPoint4", null);
+ createShape();
+ }
+
+ protected void createShape() {
+ if (vector4 != null) {
+ objectId = createShape(vector1, vector2, vector3, vector4);
+// objectId = new BU_Simplex1to4(Converter.convert(vector1), Converter.convert(vector2), Converter.convert(vector3), Converter.convert(vector4));
+ } else if (vector3 != null) {
+ objectId = createShape(vector1, vector2, vector3);
+// objectId = new BU_Simplex1to4(Converter.convert(vector1), Converter.convert(vector2), Converter.convert(vector3));
+ } else if (vector2 != null) {
+ objectId = createShape(vector1, vector2);
+// objectId = new BU_Simplex1to4(Converter.convert(vector1), Converter.convert(vector2));
+ } else {
+ objectId = createShape(vector1);
+// objectId = new BU_Simplex1to4(Converter.convert(vector1));
+ }
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+// objectId.setLocalScaling(Converter.convert(getScale()));
+// objectId.setMargin(margin);
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(Vector3f vector1);
+
+ private native long createShape(Vector3f vector1, Vector3f vector2);
+
+ private native long createShape(Vector3f vector1, Vector3f vector2, Vector3f vector3);
+
+ private native long createShape(Vector3f vector1, Vector3f vector2, Vector3f vector3, Vector3f vector4);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/SphereCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/SphereCollisionShape.java
new file mode 100644
index 000000000..2ccd81678
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/SphereCollisionShape.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.collision.shapes;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Basic sphere collision shape
+ * @author normenhansen
+ */
+public class SphereCollisionShape extends CollisionShape {
+
+ protected float radius;
+
+ public SphereCollisionShape() {
+ }
+
+ /**
+ * creates a SphereCollisionShape with the given radius
+ * @param radius
+ */
+ public SphereCollisionShape(float radius) {
+ this.radius = radius;
+ createShape();
+ }
+
+ public float getRadius() {
+ return radius;
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(radius, "radius", 0.5f);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ radius = capsule.readFloat("radius", 0.5f);
+ createShape();
+ }
+
+ protected void createShape() {
+ objectId = createShape(radius);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId));
+// new SphereShape(radius);
+// objectId.setLocalScaling(Converter.convert(getScale()));
+// objectId.setMargin(margin);
+ setScale(scale);
+ setMargin(margin);
+ }
+
+ private native long createShape(float radius);
+
+}
diff --git a/engine/src/bullet/com/jme3/bullet/collision/shapes/infos/ChildCollisionShape.java b/engine/src/bullet/com/jme3/bullet/collision/shapes/infos/ChildCollisionShape.java
new file mode 100644
index 000000000..cc721d0f1
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/collision/shapes/infos/ChildCollisionShape.java
@@ -0,0 +1,50 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.collision.shapes.infos;
+
+import com.jme3.bullet.collision.shapes.BoxCollisionShape;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.export.Savable;
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Vector3f;
+import java.io.IOException;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class ChildCollisionShape implements Savable {
+
+ public Vector3f location;
+ public Matrix3f rotation;
+ public CollisionShape shape;
+
+ public ChildCollisionShape() {
+ }
+
+ public ChildCollisionShape(Vector3f location, Matrix3f rotation, CollisionShape shape) {
+ this.location = location;
+ this.rotation = rotation;
+ this.shape = shape;
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(location, "location", new Vector3f());
+ capsule.write(rotation, "rotation", new Matrix3f());
+ capsule.write(shape, "shape", new BoxCollisionShape(new Vector3f(1, 1, 1)));
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ InputCapsule capsule = im.getCapsule(this);
+ location = (Vector3f) capsule.readSavable("location", new Vector3f());
+ rotation = (Matrix3f) capsule.readSavable("rotation", new Matrix3f());
+ shape = (CollisionShape) capsule.readSavable("shape", new BoxCollisionShape(new Vector3f(1, 1, 1)));
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/control/CharacterControl.java b/engine/src/bullet/com/jme3/bullet/control/CharacterControl.java
new file mode 100644
index 000000000..2acac5316
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/control/CharacterControl.java
@@ -0,0 +1,208 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.control;
+
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.objects.PhysicsCharacter;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.Control;
+import java.io.IOException;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class CharacterControl extends PhysicsCharacter implements PhysicsControl {
+
+ protected Spatial spatial;
+ protected boolean enabled = true;
+ protected boolean added = false;
+ protected PhysicsSpace space = null;
+ protected Vector3f viewDirection = new Vector3f(Vector3f.UNIT_Z);
+ protected boolean useViewDirection = true;
+ protected boolean applyLocal = false;
+
+ public CharacterControl() {
+ }
+
+ public CharacterControl(CollisionShape shape, float stepHeight) {
+ super(shape, stepHeight);
+ }
+
+ public boolean isApplyPhysicsLocal() {
+ return applyLocal;
+ }
+
+ /**
+ * When set to true, the physics coordinates will be applied to the local
+ * translation of the Spatial
+ * @param applyPhysicsLocal
+ */
+ public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
+ applyLocal = applyPhysicsLocal;
+ }
+
+ private Vector3f getSpatialTranslation() {
+ if (applyLocal) {
+ return spatial.getLocalTranslation();
+ }
+ return spatial.getWorldTranslation();
+ }
+
+ public Control cloneForSpatial(Spatial spatial) {
+ CharacterControl control = new CharacterControl(collisionShape, stepHeight);
+ control.setCcdMotionThreshold(getCcdMotionThreshold());
+ control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
+ control.setCollideWithGroups(getCollideWithGroups());
+ control.setCollisionGroup(getCollisionGroup());
+ control.setFallSpeed(getFallSpeed());
+ control.setGravity(getGravity());
+ control.setJumpSpeed(getJumpSpeed());
+ control.setMaxSlope(getMaxSlope());
+ control.setPhysicsLocation(getPhysicsLocation());
+ control.setUpAxis(getUpAxis());
+ control.setApplyPhysicsLocal(isApplyPhysicsLocal());
+
+ control.setSpatial(spatial);
+ return control;
+ }
+
+ public void setSpatial(Spatial spatial) {
+ if (getUserObject() == null || getUserObject() == this.spatial) {
+ setUserObject(spatial);
+ }
+ this.spatial = spatial;
+ if (spatial == null) {
+ if (getUserObject() == spatial) {
+ setUserObject(null);
+ }
+ return;
+ }
+ setPhysicsLocation(getSpatialTranslation());
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ if (space != null) {
+ if (enabled && !added) {
+ if (spatial != null) {
+ warp(getSpatialTranslation());
+ }
+ space.addCollisionObject(this);
+ added = true;
+ } else if (!enabled && added) {
+ space.removeCollisionObject(this);
+ added = false;
+ }
+ }
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setViewDirection(Vector3f vec) {
+ viewDirection.set(vec);
+ }
+
+ public Vector3f getViewDirection() {
+ return viewDirection;
+ }
+
+ public boolean isUseViewDirection() {
+ return useViewDirection;
+ }
+
+ public void setUseViewDirection(boolean viewDirectionEnabled) {
+ this.useViewDirection = viewDirectionEnabled;
+ }
+
+ public void update(float tpf) {
+ if (enabled && spatial != null) {
+ Quaternion localRotationQuat = spatial.getLocalRotation();
+ Vector3f localLocation = spatial.getLocalTranslation();
+ if (!applyLocal && spatial.getParent() != null) {
+ getPhysicsLocation(localLocation);
+ localLocation.subtractLocal(spatial.getParent().getWorldTranslation());
+ localLocation.divideLocal(spatial.getParent().getWorldScale());
+ tmp_inverseWorldRotation.set(spatial.getParent().getWorldRotation()).inverseLocal().multLocal(localLocation);
+ spatial.setLocalTranslation(localLocation);
+
+ if (useViewDirection) {
+ localRotationQuat.lookAt(viewDirection, Vector3f.UNIT_Y);
+ spatial.setLocalRotation(localRotationQuat);
+ }
+ } else {
+ spatial.setLocalTranslation(getPhysicsLocation());
+ localRotationQuat.lookAt(viewDirection, Vector3f.UNIT_Y);
+ spatial.setLocalRotation(localRotationQuat);
+ }
+ }
+ }
+
+ public void render(RenderManager rm, ViewPort vp) {
+ if (enabled && space != null && space.getDebugManager() != null) {
+ if (debugShape == null) {
+ attachDebugShape(space.getDebugManager());
+ }
+ debugShape.setLocalTranslation(getPhysicsLocation());
+ debugShape.updateLogicalState(0);
+ debugShape.updateGeometricState();
+ rm.renderScene(debugShape, vp);
+ }
+ }
+
+ public void setPhysicsSpace(PhysicsSpace space) {
+ if (space == null) {
+ if (this.space != null) {
+ this.space.removeCollisionObject(this);
+ added = false;
+ }
+ } else {
+ if (this.space == space) {
+ return;
+ }
+ space.addCollisionObject(this);
+ added = true;
+ }
+ this.space = space;
+ }
+
+ public PhysicsSpace getPhysicsSpace() {
+ return space;
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule oc = ex.getCapsule(this);
+ oc.write(enabled, "enabled", true);
+ oc.write(applyLocal, "applyLocalPhysics", false);
+ oc.write(useViewDirection, "viewDirectionEnabled", true);
+ oc.write(viewDirection, "viewDirection", new Vector3f(Vector3f.UNIT_Z));
+ oc.write(spatial, "spatial", null);
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule ic = im.getCapsule(this);
+ enabled = ic.readBoolean("enabled", true);
+ useViewDirection = ic.readBoolean("viewDirectionEnabled", true);
+ viewDirection = (Vector3f) ic.readSavable("viewDirection", new Vector3f(Vector3f.UNIT_Z));
+ applyLocal = ic.readBoolean("applyLocalPhysics", false);
+ spatial = (Spatial) ic.readSavable("spatial", null);
+ setUserObject(spatial);
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/control/GhostControl.java b/engine/src/bullet/com/jme3/bullet/control/GhostControl.java
new file mode 100644
index 000000000..99e598480
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/control/GhostControl.java
@@ -0,0 +1,178 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.control;
+
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.objects.PhysicsGhostObject;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.Control;
+import java.io.IOException;
+
+/**
+ * A GhostControl moves with the spatial it is attached to and can be used to check
+ * overlaps with other physics objects (e.g. aggro radius).
+ * @author normenhansen
+ */
+public class GhostControl extends PhysicsGhostObject implements PhysicsControl {
+
+ protected Spatial spatial;
+ protected boolean enabled = true;
+ protected boolean added = false;
+ protected PhysicsSpace space = null;
+ protected boolean applyLocal = false;
+
+ public GhostControl() {
+ }
+
+ public GhostControl(CollisionShape shape) {
+ super(shape);
+ }
+
+ public boolean isApplyPhysicsLocal() {
+ return applyLocal;
+ }
+
+ /**
+ * When set to true, the physics coordinates will be applied to the local
+ * translation of the Spatial
+ * @param applyPhysicsLocal
+ */
+ public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
+ applyLocal = applyPhysicsLocal;
+ }
+
+ private Vector3f getSpatialTranslation() {
+ if (applyLocal) {
+ return spatial.getLocalTranslation();
+ }
+ return spatial.getWorldTranslation();
+ }
+
+ private Quaternion getSpatialRotation() {
+ if (applyLocal) {
+ return spatial.getLocalRotation();
+ }
+ return spatial.getWorldRotation();
+ }
+
+ public Control cloneForSpatial(Spatial spatial) {
+ GhostControl control = new GhostControl(collisionShape);
+ control.setCcdMotionThreshold(getCcdMotionThreshold());
+ control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
+ control.setCollideWithGroups(getCollideWithGroups());
+ control.setCollisionGroup(getCollisionGroup());
+ control.setPhysicsLocation(getPhysicsLocation());
+ control.setPhysicsRotation(getPhysicsRotationMatrix());
+ control.setApplyPhysicsLocal(isApplyPhysicsLocal());
+
+ control.setSpatial(spatial);
+ return control;
+ }
+
+ public void setSpatial(Spatial spatial) {
+ if (getUserObject() == null || getUserObject() == this.spatial) {
+ setUserObject(spatial);
+ }
+ this.spatial = spatial;
+ if (spatial == null) {
+ if (getUserObject() == spatial) {
+ setUserObject(null);
+ }
+ return;
+ }
+ setPhysicsLocation(getSpatialTranslation());
+ setPhysicsRotation(getSpatialRotation());
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ if (space != null) {
+ if (enabled && !added) {
+ if (spatial != null) {
+ setPhysicsLocation(getSpatialTranslation());
+ setPhysicsRotation(getSpatialRotation());
+ }
+ space.addCollisionObject(this);
+ added = true;
+ } else if (!enabled && added) {
+ space.removeCollisionObject(this);
+ added = false;
+ }
+ }
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void update(float tpf) {
+ if (!enabled) {
+ return;
+ }
+ setPhysicsLocation(getSpatialTranslation());
+ setPhysicsRotation(getSpatialRotation());
+ }
+
+ public void render(RenderManager rm, ViewPort vp) {
+ if (enabled && space != null && space.getDebugManager() != null) {
+ if (debugShape == null) {
+ attachDebugShape(space.getDebugManager());
+ }
+ debugShape.setLocalTranslation(spatial.getWorldTranslation());
+ debugShape.setLocalRotation(spatial.getWorldRotation());
+ debugShape.updateLogicalState(0);
+ debugShape.updateGeometricState();
+ rm.renderScene(debugShape, vp);
+ }
+ }
+
+ public void setPhysicsSpace(PhysicsSpace space) {
+ if (space == null) {
+ if (this.space != null) {
+ this.space.removeCollisionObject(this);
+ added = false;
+ }
+ } else {
+ if (this.space == space) {
+ return;
+ }
+ space.addCollisionObject(this);
+ added = true;
+ }
+ this.space = space;
+ }
+
+ public PhysicsSpace getPhysicsSpace() {
+ return space;
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule oc = ex.getCapsule(this);
+ oc.write(enabled, "enabled", true);
+ oc.write(applyLocal, "applyLocalPhysics", false);
+ oc.write(spatial, "spatial", null);
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule ic = im.getCapsule(this);
+ enabled = ic.readBoolean("enabled", true);
+ spatial = (Spatial) ic.readSavable("spatial", null);
+ applyLocal = ic.readBoolean("applyLocalPhysics", false);
+ setUserObject(spatial);
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/control/KinematicRagdollControl.java b/engine/src/bullet/com/jme3/bullet/control/KinematicRagdollControl.java
new file mode 100644
index 000000000..e9783bafe
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/control/KinematicRagdollControl.java
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.control;
+
+import com.jme3.bullet.control.ragdoll.RagdollPreset;
+import com.jme3.bullet.control.ragdoll.HumanoidRagdollPreset;
+import com.jme3.animation.AnimControl;
+import com.jme3.animation.Bone;
+import com.jme3.animation.Skeleton;
+import com.jme3.animation.SkeletonControl;
+import com.jme3.asset.AssetManager;
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.collision.PhysicsCollisionEvent;
+import com.jme3.bullet.collision.PhysicsCollisionListener;
+import com.jme3.bullet.collision.PhysicsCollisionObject;
+import com.jme3.bullet.collision.RagdollCollisionListener;
+import com.jme3.bullet.collision.shapes.BoxCollisionShape;
+import com.jme3.bullet.collision.shapes.HullCollisionShape;
+import com.jme3.bullet.control.ragdoll.RagdollUtils;
+import com.jme3.bullet.joints.SixDofJoint;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.Control;
+import com.jme3.util.TempVars;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**This control is still a WIP, use it at your own risk
+ * To use this control you need a model with an AnimControl and a SkeletonControl.
+ * This should be the case if you imported an animated model from Ogre or blender.
+ * Note enabling/disabling the control add/removes it from the physic space
+ *
+ * This control creates collision shapes for each bones of the skeleton when you call spatial.addControl(ragdollControl).
+ *
+ * - The shape is HullCollision shape based on the vertices associated with each bone and based on a tweakable weight threshold (see setWeightThreshold)
+ * - If you don't want each bone to be a collision shape, you can specify what bone to use by using the addBoneName method
+ * By using this method, bone that are not used to create a shape, are "merged" to their parent to create the collision shape.
+ *
+ *
+ *
+ *
+ *There are 2 modes for this control :
+ *
+ * - The kinematic modes :
+ * this is the default behavior, this means that the collision shapes of the body are able to interact with physics enabled objects.
+ * in this mode physic shapes follow the moovements of the animated skeleton (for example animated by a key framed animation)
+ * this mode is enabled by calling setKinematicMode();
+ *
+ * - The ragdoll modes :
+ * To enable this behavior, you need to call setRagdollMode() method.
+ * In this mode the charater is entirely controled by physics, so it will fall under the gravity and move if any force is applied to it.
+ *
+ *
+ *
+ *
+ * @author Normen Hansen and Rémy Bouquet (Nehon)
+ */
+public class KinematicRagdollControl implements PhysicsControl, PhysicsCollisionListener {
+
+ protected static final Logger logger = Logger.getLogger(KinematicRagdollControl.class.getName());
+ protected Map boneLinks = new HashMap();
+ protected Skeleton skeleton;
+ protected PhysicsSpace space;
+ protected boolean enabled = true;
+ protected boolean debug = false;
+ protected PhysicsRigidBody baseRigidBody;
+ protected float weightThreshold = -1.0f;
+ protected Spatial targetModel;
+ protected Vector3f initScale;
+ protected Mode mode = Mode.Kinetmatic;
+ protected boolean blendedControl = false;
+ protected float blendTime = 1.0f;
+ protected float blendStart = 0.0f;
+ protected List listeners;
+ protected float eventDispatchImpulseThreshold = 10;
+ protected RagdollPreset preset = new HumanoidRagdollPreset();
+ protected Set boneList = new TreeSet();
+ protected Vector3f modelPosition = new Vector3f();
+ protected Quaternion modelRotation = new Quaternion();
+ protected float rootMass = 15;
+ protected float totalMass = 0;
+ protected boolean added = false;
+
+ public static enum Mode {
+
+ Kinetmatic,
+ Ragdoll
+ }
+
+ protected class PhysicsBoneLink {
+
+ protected Bone bone;
+ protected Quaternion initalWorldRotation;
+ protected SixDofJoint joint;
+ protected PhysicsRigidBody rigidBody;
+ protected Quaternion startBlendingRot = new Quaternion();
+ protected Vector3f startBlendingPos = new Vector3f();
+ }
+
+ /**
+ * contruct a KinematicRagdollControl
+ */
+ public KinematicRagdollControl() {
+ }
+
+ public KinematicRagdollControl(float weightThreshold) {
+ this.weightThreshold = weightThreshold;
+ }
+
+ public KinematicRagdollControl(RagdollPreset preset, float weightThreshold) {
+ this.preset = preset;
+ this.weightThreshold = weightThreshold;
+ }
+
+ public KinematicRagdollControl(RagdollPreset preset) {
+ this.preset = preset;
+ }
+
+ public void update(float tpf) {
+ if (!enabled) {
+ return;
+ }
+ TempVars vars = TempVars.get();
+ assert vars.lock();
+ Quaternion tmpRot1 = vars.quat1;
+ Quaternion tmpRot2 = vars.quat2;
+
+ //if the ragdoll has the control of the skeleton, we update each bone with its position in physic world space.
+ if (mode == mode.Ragdoll) {
+ for (PhysicsBoneLink link : boneLinks.values()) {
+
+ Vector3f position = vars.vect1;
+
+ //retrieving bone position in physic world space
+ Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
+ //transforming this position with inverse transforms of the model
+ targetModel.getWorldTransform().transformInverseVector(p, position);
+
+ //retrieving bone rotation in physic world space
+ Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat();
+
+ //multiplying this rotation by the initialWorld rotation of the bone,
+ //then transforming it with the inverse world rotation of the model
+ tmpRot1.set(q).multLocal(link.initalWorldRotation);
+ tmpRot2.set(targetModel.getWorldRotation()).inverseLocal().mult(tmpRot1, tmpRot1);
+ tmpRot1.normalizeLocal();
+
+ //if the bone is the root bone, we apply the physic's transform to the model, so its position and rotation are correctly updated
+ if (link.bone.getParent() == null) {
+ //offsetting the physic's position/rotation by the root bone inverse model space position/rotaion
+ modelPosition.set(p).subtractLocal(link.bone.getInitialPos());
+ modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getInitialRot()).inverseLocal());
+
+ //applying transforms to the model
+ targetModel.setLocalTranslation(modelPosition);
+ targetModel.setLocalRotation(modelRotation);
+
+ //Applying computed transforms to the bone
+ link.bone.setUserTransformsWorld(position, tmpRot1);
+
+ } else {
+ //if boneList is empty, this means that every bone in the ragdoll has a collision shape,
+ //so we just update the bone position
+ if (boneList.isEmpty()) {
+ link.bone.setUserTransformsWorld(position, tmpRot1);
+ } else {
+ //boneList is not empty, this means some bones of the skeleton might not be associated with a collision shape.
+ //So we update them recusively
+ RagdollUtils.setTransform(link.bone, position, tmpRot1, false, boneList);
+ }
+ }
+ }
+ } else {
+ //the ragdoll does not have the controll, so the keyframed animation updates the physic position of the physic bonces
+ for (PhysicsBoneLink link : boneLinks.values()) {
+
+ Vector3f position = vars.vect1;
+
+ //if blended control this means, keyframed animation is updating the skeleton,
+ //but to allow smooth transition, we blend this transformation with the saved position of the ragdoll
+ if (blendedControl) {
+ Vector3f position2 = vars.vect2;
+ //initializing tmp vars with the start position/rotation of the ragdoll
+ position.set(link.startBlendingPos);
+ tmpRot1.set(link.startBlendingRot);
+
+ //interpolating between ragdoll position/rotation and keyframed position/rotation
+ tmpRot2.set(tmpRot1).slerp(link.bone.getModelSpaceRotation(), blendStart / blendTime);
+ position2.set(position).interpolate(link.bone.getModelSpacePosition(), blendStart / blendTime);
+ tmpRot1.set(tmpRot2);
+ position.set(position2);
+
+ //updating bones transforms
+ if (boneList.isEmpty()) {
+ //we ensure we have the control to update the bone
+ link.bone.setUserControl(true);
+ link.bone.setUserTransformsWorld(position, tmpRot1);
+ //we give control back to the key framed animation.
+ link.bone.setUserControl(false);
+ } else {
+ RagdollUtils.setTransform(link.bone, position, tmpRot1, true, boneList);
+ }
+
+ }
+ //setting skeleton transforms to the ragdoll
+ matchPhysicObjectToBone(link, position, tmpRot1);
+
+ }
+
+ //time control for blending
+ if (blendedControl) {
+ blendStart += tpf;
+ if (blendStart > blendTime) {
+ blendedControl = false;
+ }
+ }
+ }
+ assert vars.unlock();
+
+ }
+
+ /**
+ * Set the transforms of a rigidBody to match the transforms of a bone.
+ * this is used to make the ragdoll follow the skeleton motion while in Kinematic mode
+ * @param link the link containing the bone and the rigidBody
+ * @param position just a temp vector for position
+ * @param tmpRot1 just a temp quaternion for rotation
+ */
+ private void matchPhysicObjectToBone(PhysicsBoneLink link, Vector3f position, Quaternion tmpRot1) {
+ //computing position from rotation and scale
+ targetModel.getWorldTransform().transformVector(link.bone.getModelSpacePosition(), position);
+
+ //computing rotation
+ tmpRot1.set(link.bone.getModelSpaceRotation()).multLocal(link.bone.getWorldBindInverseRotation());
+ targetModel.getWorldRotation().mult(tmpRot1, tmpRot1);
+ tmpRot1.normalizeLocal();
+
+ //updating physic location/rotation of the physic bone
+ link.rigidBody.setPhysicsLocation(position);
+ link.rigidBody.setPhysicsRotation(tmpRot1);
+
+ }
+
+ public Control cloneForSpatial(Spatial spatial) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ /**
+ * rebuild the ragdoll
+ * this is useful if you applied scale on the ragdoll after it's been initialized
+ */
+ public void reBuild() {
+ setSpatial(targetModel);
+ addToPhysicsSpace();
+ }
+
+ public void setSpatial(Spatial model) {
+ if (model == null) {
+ removeFromPhysicsSpace();
+ clearData();
+ return;
+ }
+ targetModel = model;
+ Node parent = model.getParent();
+
+
+ Vector3f initPosition = model.getLocalTranslation().clone();
+ Quaternion initRotation = model.getLocalRotation().clone();
+ initScale = model.getLocalScale().clone();
+
+ model.removeFromParent();
+ model.setLocalTranslation(Vector3f.ZERO);
+ model.setLocalRotation(Quaternion.IDENTITY);
+ model.setLocalScale(1);
+ //HACK ALERT change this
+ //I remove the skeletonControl and readd it to the spatial to make sure it's after the ragdollControl in the stack
+ //Find a proper way to order the controls.
+ SkeletonControl sc = model.getControl(SkeletonControl.class);
+ model.removeControl(sc);
+ model.addControl(sc);
+ //----
+
+ removeFromPhysicsSpace();
+ clearData();
+ // put into bind pose and compute bone transforms in model space
+ // maybe dont reset to ragdoll out of animations?
+ scanSpatial(model);
+
+
+ if (parent != null) {
+ parent.attachChild(model);
+
+ }
+ model.setLocalTranslation(initPosition);
+ model.setLocalRotation(initRotation);
+ model.setLocalScale(initScale);
+
+ logger.log(Level.INFO, "Created physics ragdoll for skeleton {0}", skeleton);
+ }
+
+ /**
+ * Add a bone name to this control
+ * Using this method you can specify which bones of the skeleton will be used to build the collision shapes.
+ * @param name
+ */
+ public void addBoneName(String name) {
+ boneList.add(name);
+ }
+
+ private void scanSpatial(Spatial model) {
+ AnimControl animControl = model.getControl(AnimControl.class);
+ Map> pointsMap = null;
+ if (weightThreshold == -1.0f) {
+ pointsMap = RagdollUtils.buildPointMap(model);
+ }
+
+ skeleton = animControl.getSkeleton();
+ skeleton.resetAndUpdate();
+ for (int i = 0; i < skeleton.getRoots().length; i++) {
+ Bone childBone = skeleton.getRoots()[i];
+ if (childBone.getParent() == null) {
+ logger.log(Level.INFO, "Found root bone in skeleton {0}", skeleton);
+ baseRigidBody = new PhysicsRigidBody(new BoxCollisionShape(Vector3f.UNIT_XYZ.mult(0.1f)), 1);
+ baseRigidBody.setKinematic(mode == Mode.Kinetmatic);
+ boneRecursion(model, childBone, baseRigidBody, 1, pointsMap);
+ }
+ }
+ }
+
+ private void boneRecursion(Spatial model, Bone bone, PhysicsRigidBody parent, int reccount, Map> pointsMap) {
+ PhysicsRigidBody parentShape = parent;
+ if (boneList.isEmpty() || boneList.contains(bone.getName())) {
+
+ PhysicsBoneLink link = new PhysicsBoneLink();
+ link.bone = bone;
+
+ //creating the collision shape
+ HullCollisionShape shape = null;
+ if (pointsMap != null) {
+ //build a shape for the bone, using the vertices that are most influenced by this bone
+ shape = RagdollUtils.makeShapeFromPointMap(pointsMap, RagdollUtils.getBoneIndices(link.bone, skeleton, boneList), initScale, link.bone.getModelSpacePosition());
+ } else {
+ //build a shape for the bone, using the vertices associated with this bone with a weight above the threshold
+ shape = RagdollUtils.makeShapeFromVerticeWeights(model, RagdollUtils.getBoneIndices(link.bone, skeleton, boneList), initScale, link.bone.getModelSpacePosition(), weightThreshold);
+ }
+
+ PhysicsRigidBody shapeNode = new PhysicsRigidBody(shape, rootMass / (float) reccount);
+ shapeNode.setKinematic(mode == Mode.Kinetmatic);
+ totalMass += rootMass / (float) reccount;
+
+ link.rigidBody = shapeNode;
+ link.initalWorldRotation = bone.getModelSpaceRotation().clone();
+
+ if (parent != null) {
+ //get joint position for parent
+ Vector3f posToParent = new Vector3f();
+ if (bone.getParent() != null) {
+ bone.getModelSpacePosition().subtract(bone.getParent().getModelSpacePosition(), posToParent).multLocal(initScale);
+ }
+
+ SixDofJoint joint = new SixDofJoint(parent, shapeNode, posToParent, new Vector3f(0, 0, 0f), true);
+ preset.setupJointForBone(bone.getName(), joint);
+
+ link.joint = joint;
+ joint.setCollisionBetweenLinkedBodys(false);
+ }
+ boneLinks.put(bone.getName(), link);
+ shapeNode.setUserObject(link);
+ parentShape = shapeNode;
+ }
+
+ for (Iterator it = bone.getChildren().iterator(); it.hasNext();) {
+ Bone childBone = it.next();
+ boneRecursion(model, childBone, parentShape, reccount + 1, pointsMap);
+ }
+ }
+
+ /**
+ * Set the joint limits for the joint between the given bone and its parent.
+ * This method can't work before attaching the control to a spatial
+ * @param boneName the name of the bone
+ * @param maxX the maximum rotation on the x axis (in radians)
+ * @param minX the minimum rotation on the x axis (in radians)
+ * @param maxY the maximum rotation on the y axis (in radians)
+ * @param minY the minimum rotation on the z axis (in radians)
+ * @param maxZ the maximum rotation on the z axis (in radians)
+ * @param minZ the minimum rotation on the z axis (in radians)
+ */
+ public void setJointLimit(String boneName, float maxX, float minX, float maxY, float minY, float maxZ, float minZ) {
+ PhysicsBoneLink link = boneLinks.get(boneName);
+ if (link != null) {
+ RagdollUtils.setJointLimit(link.joint, maxX, minX, maxY, minY, maxZ, minZ);
+ } else {
+ logger.log(Level.WARNING, "Not joint was found for bone {0}. make sure you call spatial.addControl(ragdoll) before setting joints limit", boneName);
+ }
+ }
+
+ /**
+ * Return the joint between the given bone and its parent.
+ * This return null if it's called before attaching the control to a spatial
+ * @param boneName the name of the bone
+ * @return the joint between the given bone and its parent
+ */
+ public SixDofJoint getJoint(String boneName) {
+ PhysicsBoneLink link = boneLinks.get(boneName);
+ if (link != null) {
+ return link.joint;
+ } else {
+ logger.log(Level.WARNING, "Not joint was found for bone {0}. make sure you call spatial.addControl(ragdoll) before setting joints limit", boneName);
+ return null;
+ }
+ }
+
+ private void clearData() {
+ boneLinks.clear();
+ baseRigidBody = null;
+ }
+
+ private void addToPhysicsSpace() {
+ if (space == null) {
+ return;
+ }
+ if (baseRigidBody != null) {
+ space.add(baseRigidBody);
+ added = true;
+ }
+ for (Iterator it = boneLinks.values().iterator(); it.hasNext();) {
+ PhysicsBoneLink physicsBoneLink = it.next();
+ if (physicsBoneLink.rigidBody != null) {
+ space.add(physicsBoneLink.rigidBody);
+ if (physicsBoneLink.joint != null) {
+ space.add(physicsBoneLink.joint);
+
+ }
+ added = true;
+ }
+ }
+ }
+
+ protected void removeFromPhysicsSpace() {
+ if (space == null) {
+ return;
+ }
+ if (baseRigidBody != null) {
+ space.remove(baseRigidBody);
+ }
+ for (Iterator it = boneLinks.values().iterator(); it.hasNext();) {
+ PhysicsBoneLink physicsBoneLink = it.next();
+ if (physicsBoneLink.joint != null) {
+ space.remove(physicsBoneLink.joint);
+ if (physicsBoneLink.rigidBody != null) {
+ space.remove(physicsBoneLink.rigidBody);
+ }
+ }
+ }
+ added = false;
+ }
+
+ /**
+ * enable or disable the control
+ * note that if enabled is true and that the physic space has been set on the ragdoll, the ragdoll is added to the physic space
+ * if enabled is false the ragdoll is removed from physic space.
+ * @param enabled
+ */
+ public void setEnabled(boolean enabled) {
+ if (this.enabled == enabled) {
+ return;
+ }
+ this.enabled = enabled;
+ if (!enabled && space != null) {
+ removeFromPhysicsSpace();
+ } else if (enabled && space != null) {
+ addToPhysicsSpace();
+ }
+ }
+
+ /**
+ * returns true if the control is enabled
+ * @return
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ protected void attachDebugShape(AssetManager manager) {
+ for (Iterator it = boneLinks.values().iterator(); it.hasNext();) {
+ PhysicsBoneLink physicsBoneLink = it.next();
+ physicsBoneLink.rigidBody.createDebugShape(manager);
+ }
+ debug = true;
+ }
+
+ protected void detachDebugShape() {
+ for (Iterator it = boneLinks.values().iterator(); it.hasNext();) {
+ PhysicsBoneLink physicsBoneLink = it.next();
+ physicsBoneLink.rigidBody.detachDebugShape();
+ }
+ debug = false;
+ }
+
+ /**
+ * For internal use only
+ * specific render for the ragdoll(if debugging)
+ * @param rm
+ * @param vp
+ */
+ public void render(RenderManager rm, ViewPort vp) {
+ if (enabled && space != null && space.getDebugManager() != null) {
+ if (!debug) {
+ attachDebugShape(space.getDebugManager());
+ }
+ for (Iterator it = boneLinks.values().iterator(); it.hasNext();) {
+ PhysicsBoneLink physicsBoneLink = it.next();
+ Spatial debugShape = physicsBoneLink.rigidBody.debugShape();
+ if (debugShape != null) {
+ debugShape.setLocalTranslation(physicsBoneLink.rigidBody.getMotionState().getWorldLocation());
+ debugShape.setLocalRotation(physicsBoneLink.rigidBody.getMotionState().getWorldRotationQuat());
+ debugShape.updateGeometricState();
+ rm.renderScene(debugShape, vp);
+ }
+ }
+ }
+ }
+
+ /**
+ * set the physic space to this ragdoll
+ * @param space
+ */
+ public void setPhysicsSpace(PhysicsSpace space) {
+ if (space == null) {
+ removeFromPhysicsSpace();
+ this.space = space;
+ } else {
+ if (this.space == space) {
+ return;
+ }
+ this.space = space;
+ addToPhysicsSpace();
+ }
+ this.space.addCollisionListener(this);
+ }
+
+ /**
+ * returns the physic space
+ * @return
+ */
+ public PhysicsSpace getPhysicsSpace() {
+ return space;
+ }
+
+ /**
+ * serialize this control
+ * @param ex
+ * @throws IOException
+ */
+ public void write(JmeExporter ex) throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ /**
+ * de-serialize this control
+ * @param im
+ * @throws IOException
+ */
+ public void read(JmeImporter im) throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ /**
+ * For internal use only
+ * callback for collisionevent
+ * @param event
+ */
+ public void collision(PhysicsCollisionEvent event) {
+ PhysicsCollisionObject objA = event.getObjectA();
+ PhysicsCollisionObject objB = event.getObjectB();
+
+ //excluding collisions that involve 2 parts of the ragdoll
+ if (event.getNodeA() == null && event.getNodeB() == null) {
+ return;
+ }
+
+ //discarding low impulse collision
+ if (event.getAppliedImpulse() < eventDispatchImpulseThreshold) {
+ return;
+ }
+
+ boolean hit = false;
+ Bone hitBone = null;
+ PhysicsCollisionObject hitObject = null;
+
+ //Computing which bone has been hit
+ if (objA.getUserObject() instanceof PhysicsBoneLink) {
+ PhysicsBoneLink link = (PhysicsBoneLink) objA.getUserObject();
+ if (link != null) {
+ hit = true;
+ hitBone = link.bone;
+ hitObject = objB;
+ }
+ }
+
+ if (objB.getUserObject() instanceof PhysicsBoneLink) {
+ PhysicsBoneLink link = (PhysicsBoneLink) objB.getUserObject();
+ if (link != null) {
+ hit = true;
+ hitBone = link.bone;
+ hitObject = objA;
+
+ }
+ }
+
+ //dispatching the event if the ragdoll has been hit
+ if (hit) {
+ for (RagdollCollisionListener listener : listeners) {
+ listener.collide(hitBone, hitObject, event);
+ }
+ }
+
+ }
+
+ /**
+ * Enable or disable the ragdoll behaviour.
+ * if ragdollEnabled is true, the character motion will only be powerd by physics
+ * else, the characted will be animated by the keyframe animation,
+ * but will be able to physically interact with its physic environnement
+ * @param ragdollEnabled
+ */
+ protected void setMode(Mode mode) {
+ this.mode = mode;
+ AnimControl animControl = targetModel.getControl(AnimControl.class);
+ animControl.setEnabled(mode == Mode.Kinetmatic);
+
+ baseRigidBody.setKinematic(mode == Mode.Kinetmatic);
+ TempVars vars = TempVars.get();
+ assert vars.lock();
+ for (PhysicsBoneLink link : boneLinks.values()) {
+ link.rigidBody.setKinematic(mode == Mode.Kinetmatic);
+ if (mode == Mode.Ragdoll) {
+ Quaternion tmpRot1 = vars.quat1;
+ Vector3f position = vars.vect1;
+ //making sure that the ragdoll is at the correct place.
+ matchPhysicObjectToBone(link, position, tmpRot1);
+ }
+
+ }
+ assert vars.unlock();
+
+ for (Bone bone : skeleton.getRoots()) {
+ RagdollUtils.setUserControl(bone, mode == Mode.Ragdoll);
+ }
+ }
+
+ /**
+ * Smoothly blend from Ragdoll mode to Kinematic mode
+ * This is useful to blend ragdoll actual position to a keyframe animation for example
+ * @param blendTime the blending time between ragdoll to anim.
+ */
+ public void blendToKinematicMode(float blendTime) {
+ if (mode == Mode.Kinetmatic) {
+ return;
+ }
+ blendedControl = true;
+ this.blendTime = blendTime;
+ mode = Mode.Kinetmatic;
+ AnimControl animControl = targetModel.getControl(AnimControl.class);
+ animControl.setEnabled(true);
+
+
+
+ TempVars vars = TempVars.get();
+ assert vars.lock();
+ for (PhysicsBoneLink link : boneLinks.values()) {
+
+ Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
+ Vector3f position = vars.vect1;
+
+ targetModel.getWorldTransform().transformInverseVector(p, position);
+
+ Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat();
+ Quaternion q2 = vars.quat1;
+ Quaternion q3 = vars.quat2;
+
+ q2.set(q).multLocal(link.initalWorldRotation).normalizeLocal();
+ q3.set(targetModel.getWorldRotation()).inverseLocal().mult(q2, q2);
+ q2.normalizeLocal();
+ link.startBlendingPos.set(position);
+ link.startBlendingRot.set(q2);
+ link.rigidBody.setKinematic(true);
+ }
+ assert vars.unlock();
+
+ for (Bone bone : skeleton.getRoots()) {
+ RagdollUtils.setUserControl(bone, false);
+ }
+
+ blendStart = 0;
+ }
+
+ /**
+ * Set the control into Kinematic mode
+ * In theis mode, the collision shapes follow the movements of the skeleton,
+ * and can interact with physical environement
+ */
+ public void setKinematicMode() {
+ if (mode != Mode.Kinetmatic) {
+ setMode(Mode.Kinetmatic);
+ }
+ }
+
+ /**
+ * Sets the control into Ragdoll mode
+ * The skeleton is entirely controlled by physics.
+ */
+ public void setRagdollMode() {
+ if (mode != Mode.Ragdoll) {
+ setMode(Mode.Ragdoll);
+ }
+ }
+
+ /**
+ * retruns the mode of this control
+ * @return
+ */
+ public Mode getMode() {
+ return mode;
+ }
+
+ /**
+ * add a
+ * @param listener
+ */
+ public void addCollisionListener(RagdollCollisionListener listener) {
+ if (listeners == null) {
+ listeners = new ArrayList();
+ }
+ listeners.add(listener);
+ }
+
+ public void setRootMass(float rootMass) {
+ this.rootMass = rootMass;
+ }
+
+ public float getTotalMass() {
+ return totalMass;
+ }
+
+ public float getWeightThreshold() {
+ return weightThreshold;
+ }
+
+ public void setWeightThreshold(float weightThreshold) {
+ this.weightThreshold = weightThreshold;
+ }
+
+ public float getEventDispatchImpulseThreshold() {
+ return eventDispatchImpulseThreshold;
+ }
+
+ public void setEventDispatchImpulseThreshold(float eventDispatchImpulseThreshold) {
+ this.eventDispatchImpulseThreshold = eventDispatchImpulseThreshold;
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/control/PhysicsControl.java b/engine/src/bullet/com/jme3/bullet/control/PhysicsControl.java
new file mode 100644
index 000000000..ba6515789
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/control/PhysicsControl.java
@@ -0,0 +1,28 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.control;
+
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.scene.control.Control;
+
+/**
+ *
+ * @author normenhansen
+ */
+public interface PhysicsControl extends Control {
+
+ public void setPhysicsSpace(PhysicsSpace space);
+
+ public PhysicsSpace getPhysicsSpace();
+
+ /**
+ * The physics object is removed from the physics space when the control
+ * is disabled. When the control is enabled again the physics object is
+ * moved to the current location of the spatial and then added to the physics
+ * space. This allows disabling/enabling physics to move the spatial freely.
+ * @param state
+ */
+ public void setEnabled(boolean state);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/control/RigidBodyControl.java b/engine/src/bullet/com/jme3/bullet/control/RigidBodyControl.java
new file mode 100644
index 000000000..be40b58c3
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/control/RigidBodyControl.java
@@ -0,0 +1,266 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.control;
+
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.collision.shapes.BoxCollisionShape;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.collision.shapes.SphereCollisionShape;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.bullet.util.CollisionShapeFactory;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.Control;
+import com.jme3.scene.shape.Box;
+import com.jme3.scene.shape.Sphere;
+import java.io.IOException;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl {
+
+ protected Spatial spatial;
+ protected boolean enabled = true;
+ protected boolean added = false;
+ protected PhysicsSpace space = null;
+ protected boolean kinematicSpatial = true;
+
+ public RigidBodyControl() {
+ }
+
+ /**
+ * When using this constructor, the CollisionShape for the RigidBody is generated
+ * automatically when the Control is added to a Spatial.
+ * @param mass When not 0, a HullCollisionShape is generated, otherwise a MeshCollisionShape is used. For geometries with box or sphere meshes the proper box or sphere collision shape is used.
+ */
+ public RigidBodyControl(float mass) {
+ this.mass = mass;
+ }
+
+ /**
+ * Creates a new PhysicsNode with the supplied collision shape and mass 1
+ * @param child
+ * @param shape
+ */
+ public RigidBodyControl(CollisionShape shape) {
+ super(shape);
+ }
+
+ public RigidBodyControl(CollisionShape shape, float mass) {
+ super(shape, mass);
+ }
+
+ public Control cloneForSpatial(Spatial spatial) {
+ RigidBodyControl control = new RigidBodyControl(collisionShape, mass);
+ control.setAngularFactor(getAngularFactor());
+ control.setAngularSleepingThreshold(getAngularSleepingThreshold());
+ control.setCcdMotionThreshold(getCcdMotionThreshold());
+ control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
+ control.setCollideWithGroups(getCollideWithGroups());
+ control.setCollisionGroup(getCollisionGroup());
+ control.setDamping(getLinearDamping(), getAngularDamping());
+ control.setFriction(getFriction());
+ control.setGravity(getGravity());
+ control.setKinematic(isKinematic());
+ control.setKinematicSpatial(isKinematicSpatial());
+ control.setLinearSleepingThreshold(getLinearSleepingThreshold());
+ control.setPhysicsLocation(getPhysicsLocation(null));
+ control.setPhysicsRotation(getPhysicsRotationMatrix(null));
+ control.setRestitution(getRestitution());
+
+ if (mass > 0) {
+ control.setAngularVelocity(getAngularVelocity());
+ control.setLinearVelocity(getLinearVelocity());
+ }
+ control.setApplyPhysicsLocal(isApplyPhysicsLocal());
+
+ control.setSpatial(spatial);
+ return control;
+ }
+
+ public void setSpatial(Spatial spatial) {
+ if (getUserObject() == null || getUserObject() == this.spatial) {
+ setUserObject(spatial);
+ }
+ this.spatial = spatial;
+ if (spatial == null) {
+ if (getUserObject() == spatial) {
+ setUserObject(null);
+ }
+ spatial = null;
+ collisionShape = null;
+ return;
+ }
+ if (collisionShape == null) {
+ createCollisionShape();
+ rebuildRigidBody();
+ }
+ setPhysicsLocation(getSpatialTranslation());
+ setPhysicsRotation(getSpatialRotation());
+ }
+
+ protected void createCollisionShape() {
+ if (spatial == null) {
+ return;
+ }
+ if (spatial instanceof Geometry) {
+ Geometry geom = (Geometry) spatial;
+ Mesh mesh = geom.getMesh();
+ if (mesh instanceof Sphere) {
+ collisionShape = new SphereCollisionShape(((Sphere) mesh).getRadius());
+ return;
+ } else if (mesh instanceof Box) {
+ collisionShape = new BoxCollisionShape(new Vector3f(((Box) mesh).getXExtent(), ((Box) mesh).getYExtent(), ((Box) mesh).getZExtent()));
+ return;
+ }
+ }
+ if (mass > 0) {
+ collisionShape = CollisionShapeFactory.createDynamicMeshShape(spatial);
+ } else {
+ collisionShape = CollisionShapeFactory.createMeshShape(spatial);
+ }
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ if (space != null) {
+ if (enabled && !added) {
+ if (spatial != null) {
+ setPhysicsLocation(getSpatialTranslation());
+ setPhysicsRotation(getSpatialRotation());
+ }
+ space.addCollisionObject(this);
+ added = true;
+ } else if (!enabled && added) {
+ space.removeCollisionObject(this);
+ added = false;
+ }
+ }
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Checks if this control is in kinematic spatial mode.
+ * @return true if the spatial location is applied to this kinematic rigidbody
+ */
+ public boolean isKinematicSpatial() {
+ return kinematicSpatial;
+ }
+
+ /**
+ * Sets this control to kinematic spatial mode so that the spatials transform will
+ * be applied to the rigidbody in kinematic mode, defaults to true.
+ * @param kinematicSpatial
+ */
+ public void setKinematicSpatial(boolean kinematicSpatial) {
+ this.kinematicSpatial = kinematicSpatial;
+ }
+
+ public boolean isApplyPhysicsLocal() {
+ return motionState.isApplyPhysicsLocal();
+ }
+
+ /**
+ * When set to true, the physics coordinates will be applied to the local
+ * translation of the Spatial instead of the world traslation.
+ * @param applyPhysicsLocal
+ */
+ public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
+ motionState.setApplyPhysicsLocal(applyPhysicsLocal);
+ }
+
+ private Vector3f getSpatialTranslation(){
+ if(motionState.isApplyPhysicsLocal()){
+ return spatial.getLocalTranslation();
+ }
+ return spatial.getWorldTranslation();
+ }
+
+ private Quaternion getSpatialRotation(){
+ if(motionState.isApplyPhysicsLocal()){
+ return spatial.getLocalRotation();
+ }
+ return spatial.getWorldRotation();
+ }
+
+ public void update(float tpf) {
+ if (enabled && spatial != null) {
+ if (isKinematic() && kinematicSpatial) {
+ super.setPhysicsLocation(getSpatialTranslation());
+ super.setPhysicsRotation(getSpatialRotation());
+ } else {
+ getMotionState().applyTransform(spatial);
+ }
+ }
+ }
+
+ public void render(RenderManager rm, ViewPort vp) {
+ if (enabled && space != null && space.getDebugManager() != null) {
+ if (debugShape == null) {
+ attachDebugShape(space.getDebugManager());
+ }
+ //TODO: using spatial traslation/rotation..
+ debugShape.setLocalTranslation(spatial.getWorldTranslation());
+ debugShape.setLocalRotation(spatial.getWorldRotation());
+ debugShape.updateLogicalState(0);
+ debugShape.updateGeometricState();
+ rm.renderScene(debugShape, vp);
+ }
+ }
+
+ public void setPhysicsSpace(PhysicsSpace space) {
+ if (space == null) {
+ if (this.space != null) {
+ this.space.removeCollisionObject(this);
+ added = false;
+ }
+ } else {
+ if(this.space==space) return;
+ space.addCollisionObject(this);
+ added = true;
+ }
+ this.space = space;
+ }
+
+ public PhysicsSpace getPhysicsSpace() {
+ return space;
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule oc = ex.getCapsule(this);
+ oc.write(enabled, "enabled", true);
+ oc.write(motionState.isApplyPhysicsLocal(), "applyLocalPhysics", false);
+ oc.write(kinematicSpatial, "kinematicSpatial", true);
+ oc.write(spatial, "spatial", null);
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule ic = im.getCapsule(this);
+ enabled = ic.readBoolean("enabled", true);
+ kinematicSpatial = ic.readBoolean("kinematicSpatial", true);
+ spatial = (Spatial) ic.readSavable("spatial", null);
+ motionState.setApplyPhysicsLocal(ic.readBoolean("applyLocalPhysics", false));
+ setUserObject(spatial);
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/control/VehicleControl.java b/engine/src/bullet/com/jme3/bullet/control/VehicleControl.java
new file mode 100644
index 000000000..4e6f416e4
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/control/VehicleControl.java
@@ -0,0 +1,270 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.control;
+
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.joints.PhysicsJoint;
+import com.jme3.bullet.objects.PhysicsVehicle;
+import com.jme3.bullet.objects.VehicleWheel;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.Control;
+import com.jme3.scene.debug.Arrow;
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class VehicleControl extends PhysicsVehicle implements PhysicsControl {
+
+ protected Spatial spatial;
+ protected boolean enabled = true;
+ protected PhysicsSpace space = null;
+ protected boolean added = false;
+
+ public VehicleControl() {
+ }
+
+ /**
+ * Creates a new PhysicsNode with the supplied collision shape
+ * @param child
+ * @param shape
+ */
+ public VehicleControl(CollisionShape shape) {
+ super(shape);
+ }
+
+ public VehicleControl(CollisionShape shape, float mass) {
+ super(shape, mass);
+ }
+
+ public boolean isApplyPhysicsLocal() {
+ return motionState.isApplyPhysicsLocal();
+ }
+
+ /**
+ * When set to true, the physics coordinates will be applied to the local
+ * translation of the Spatial
+ * @param applyPhysicsLocal
+ */
+ public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
+ motionState.setApplyPhysicsLocal(applyPhysicsLocal);
+ for (Iterator it = wheels.iterator(); it.hasNext();) {
+ VehicleWheel vehicleWheel = it.next();
+ vehicleWheel.setApplyLocal(applyPhysicsLocal);
+ }
+ }
+
+ private Vector3f getSpatialTranslation(){
+ if(motionState.isApplyPhysicsLocal()){
+ return spatial.getLocalTranslation();
+ }
+ return spatial.getWorldTranslation();
+ }
+
+ private Quaternion getSpatialRotation(){
+ if(motionState.isApplyPhysicsLocal()){
+ return spatial.getLocalRotation();
+ }
+ return spatial.getWorldRotation();
+ }
+
+ public Control cloneForSpatial(Spatial spatial) {
+ VehicleControl control = new VehicleControl(collisionShape, mass);
+ control.setAngularFactor(getAngularFactor());
+ control.setAngularSleepingThreshold(getAngularSleepingThreshold());
+ control.setAngularVelocity(getAngularVelocity());
+ control.setCcdMotionThreshold(getCcdMotionThreshold());
+ control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
+ control.setCollideWithGroups(getCollideWithGroups());
+ control.setCollisionGroup(getCollisionGroup());
+ control.setDamping(getLinearDamping(), getAngularDamping());
+ control.setFriction(getFriction());
+ control.setGravity(getGravity());
+ control.setKinematic(isKinematic());
+ control.setLinearSleepingThreshold(getLinearSleepingThreshold());
+ control.setLinearVelocity(getLinearVelocity());
+ control.setPhysicsLocation(getPhysicsLocation());
+ control.setPhysicsRotation(getPhysicsRotationMatrix());
+ control.setRestitution(getRestitution());
+
+ control.setFrictionSlip(getFrictionSlip());
+ control.setMaxSuspensionTravelCm(getMaxSuspensionTravelCm());
+ control.setSuspensionStiffness(getSuspensionStiffness());
+ control.setSuspensionCompression(tuning.suspensionCompression);
+ control.setSuspensionDamping(tuning.suspensionDamping);
+ control.setMaxSuspensionForce(getMaxSuspensionForce());
+
+ for (Iterator it = wheels.iterator(); it.hasNext();) {
+ VehicleWheel wheel = it.next();
+ VehicleWheel newWheel = control.addWheel(wheel.getLocation(), wheel.getDirection(), wheel.getAxle(), wheel.getRestLength(), wheel.getRadius(), wheel.isFrontWheel());
+ newWheel.setFrictionSlip(wheel.getFrictionSlip());
+ newWheel.setMaxSuspensionTravelCm(wheel.getMaxSuspensionTravelCm());
+ newWheel.setSuspensionStiffness(wheel.getSuspensionStiffness());
+ newWheel.setWheelsDampingCompression(wheel.getWheelsDampingCompression());
+ newWheel.setWheelsDampingRelaxation(wheel.getWheelsDampingRelaxation());
+ newWheel.setMaxSuspensionForce(wheel.getMaxSuspensionForce());
+
+ //TODO: bad way finding children!
+ if (spatial instanceof Node) {
+ Node node = (Node) spatial;
+ Spatial wheelSpat = node.getChild(wheel.getWheelSpatial().getName());
+ if (wheelSpat != null) {
+ newWheel.setWheelSpatial(wheelSpat);
+ }
+ }
+ }
+ control.setApplyPhysicsLocal(isApplyPhysicsLocal());
+
+ control.setSpatial(spatial);
+ return control;
+ }
+
+ public void setSpatial(Spatial spatial) {
+ if (getUserObject() == null || getUserObject() == this.spatial) {
+ setUserObject(spatial);
+ }
+ this.spatial = spatial;
+ if (spatial == null) {
+ if (getUserObject() == spatial) {
+ setUserObject(null);
+ }
+ this.spatial = null;
+ this.collisionShape = null;
+ return;
+ }
+ setPhysicsLocation(getSpatialTranslation());
+ setPhysicsRotation(getSpatialRotation());
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ if (space != null) {
+ if (enabled && !added) {
+ if(spatial!=null){
+ setPhysicsLocation(getSpatialTranslation());
+ setPhysicsRotation(getSpatialRotation());
+ }
+ space.addCollisionObject(this);
+ added = true;
+ } else if (!enabled && added) {
+ space.removeCollisionObject(this);
+ added = false;
+ }
+ }
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void update(float tpf) {
+ if (enabled && spatial != null) {
+ if (getMotionState().applyTransform(spatial)) {
+ spatial.getWorldTransform();
+ applyWheelTransforms();
+ }
+ } else if (enabled) {
+ applyWheelTransforms();
+ }
+ }
+
+ @Override
+ protected Spatial getDebugShape() {
+ return super.getDebugShape();
+ }
+
+ public void render(RenderManager rm, ViewPort vp) {
+ if (enabled && space != null && space.getDebugManager() != null) {
+ if (debugShape == null) {
+ attachDebugShape(space.getDebugManager());
+ }
+ Node debugNode = (Node) debugShape;
+ debugShape.setLocalTranslation(spatial.getWorldTranslation());
+ debugShape.setLocalRotation(spatial.getWorldRotation());
+ int i = 0;
+ for (Iterator it = wheels.iterator(); it.hasNext();) {
+ VehicleWheel physicsVehicleWheel = it.next();
+ Vector3f location = physicsVehicleWheel.getLocation().clone();
+ Vector3f direction = physicsVehicleWheel.getDirection().clone();
+ Vector3f axle = physicsVehicleWheel.getAxle().clone();
+ float restLength = physicsVehicleWheel.getRestLength();
+ float radius = physicsVehicleWheel.getRadius();
+
+ Geometry locGeom = (Geometry) debugNode.getChild("WheelLocationDebugShape" + i);
+ Geometry dirGeom = (Geometry) debugNode.getChild("WheelDirectionDebugShape" + i);
+ Geometry axleGeom = (Geometry) debugNode.getChild("WheelAxleDebugShape" + i);
+ Geometry wheelGeom = (Geometry) debugNode.getChild("WheelRadiusDebugShape" + i);
+
+ Arrow locArrow = (Arrow) locGeom.getMesh();
+ locArrow.setArrowExtent(location);
+ Arrow axleArrow = (Arrow) axleGeom.getMesh();
+ axleArrow.setArrowExtent(axle.normalizeLocal().multLocal(0.3f));
+ Arrow wheelArrow = (Arrow) wheelGeom.getMesh();
+ wheelArrow.setArrowExtent(direction.normalizeLocal().multLocal(radius));
+ Arrow dirArrow = (Arrow) dirGeom.getMesh();
+ dirArrow.setArrowExtent(direction.normalizeLocal().multLocal(restLength));
+
+ dirGeom.setLocalTranslation(location);
+ axleGeom.setLocalTranslation(location.addLocal(direction));
+ wheelGeom.setLocalTranslation(location);
+ i++;
+ }
+ debugShape.updateLogicalState(0);
+ debugShape.updateGeometricState();
+ rm.renderScene(debugShape, vp);
+ }
+ }
+
+ public void setPhysicsSpace(PhysicsSpace space) {
+ createVehicle(space);
+ if (space == null) {
+ if (this.space != null) {
+ this.space.removeCollisionObject(this);
+ added = false;
+ }
+ } else {
+ if(this.space==space) return;
+ space.addCollisionObject(this);
+ added = true;
+ }
+ this.space = space;
+ }
+
+ public PhysicsSpace getPhysicsSpace() {
+ return space;
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule oc = ex.getCapsule(this);
+ oc.write(enabled, "enabled", true);
+ oc.write(motionState.isApplyPhysicsLocal(), "applyLocalPhysics", false);
+ oc.write(spatial, "spatial", null);
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule ic = im.getCapsule(this);
+ enabled = ic.readBoolean("enabled", true);
+ spatial = (Spatial) ic.readSavable("spatial", null);
+ motionState.setApplyPhysicsLocal(ic.readBoolean("applyLocalPhysics", false));
+ setUserObject(spatial);
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/control/ragdoll/HumanoidRagdollPreset.java b/engine/src/bullet/com/jme3/bullet/control/ragdoll/HumanoidRagdollPreset.java
new file mode 100644
index 000000000..06eeab052
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/control/ragdoll/HumanoidRagdollPreset.java
@@ -0,0 +1,99 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.control.ragdoll;
+
+import com.jme3.math.FastMath;
+
+/**
+ *
+ * @author Nehon
+ */
+public class HumanoidRagdollPreset extends RagdollPreset {
+
+ @Override
+ protected void initBoneMap() {
+ boneMap.put("head", new JointPreset(FastMath.QUARTER_PI, -FastMath.QUARTER_PI, FastMath.QUARTER_PI, -FastMath.QUARTER_PI, FastMath.QUARTER_PI, -FastMath.QUARTER_PI));
+
+ boneMap.put("torso", new JointPreset(FastMath.QUARTER_PI, -FastMath.QUARTER_PI, 0, 0, FastMath.QUARTER_PI, -FastMath.QUARTER_PI));
+
+ boneMap.put("upperleg", new JointPreset(FastMath.PI, -FastMath.QUARTER_PI, FastMath.QUARTER_PI/2, -FastMath.QUARTER_PI/2, FastMath.QUARTER_PI, -FastMath.QUARTER_PI));
+
+ boneMap.put("lowerleg", new JointPreset(0, -FastMath.PI, 0, 0, 0, 0));
+
+ boneMap.put("foot", new JointPreset(0, -FastMath.QUARTER_PI, FastMath.QUARTER_PI, -FastMath.QUARTER_PI, FastMath.QUARTER_PI, -FastMath.QUARTER_PI));
+
+ boneMap.put("upperarm", new JointPreset(FastMath.HALF_PI, -FastMath.QUARTER_PI, 0, 0, FastMath.HALF_PI, -FastMath.QUARTER_PI));
+
+ boneMap.put("lowerarm", new JointPreset(FastMath.HALF_PI, 0, 0, 0, 0, 0));
+
+ boneMap.put("hand", new JointPreset(FastMath.QUARTER_PI, -FastMath.QUARTER_PI, FastMath.QUARTER_PI, -FastMath.QUARTER_PI, FastMath.QUARTER_PI, -FastMath.QUARTER_PI));
+
+ }
+
+ @Override
+ protected void initLexicon() {
+ LexiconEntry entry = new LexiconEntry();
+ entry.addSynonym("head", 100);
+ lexicon.put("head", entry);
+
+ entry = new LexiconEntry();
+ entry.addSynonym("torso", 100);
+ entry.addSynonym("chest", 100);
+ entry.addSynonym("spine", 45);
+ entry.addSynonym("high", 25);
+ lexicon.put("torso", entry);
+
+ entry = new LexiconEntry();
+ entry.addSynonym("upperleg", 100);
+ entry.addSynonym("thigh", 100);
+ entry.addSynonym("hip", 75);
+ entry.addSynonym("leg", 40);
+ entry.addSynonym("high", 10);
+ entry.addSynonym("up", 15);
+ entry.addSynonym("upper", 15);
+ lexicon.put("upperleg", entry);
+
+ entry = new LexiconEntry();
+ entry.addSynonym("lowerleg", 100);
+ entry.addSynonym("calf", 100);
+ entry.addSynonym("knee", 75);
+ entry.addSynonym("leg", 50);
+ entry.addSynonym("low", 10);
+ entry.addSynonym("lower", 10);
+ lexicon.put("lowerleg", entry);
+
+ entry = new LexiconEntry();
+ entry.addSynonym("foot", 100);
+ entry.addSynonym("ankle", 75);
+ lexicon.put("foot", entry);
+
+
+ entry = new LexiconEntry();
+ entry.addSynonym("upperarm", 100);
+ entry.addSynonym("humerus", 100);
+ entry.addSynonym("shoulder", 50);
+ entry.addSynonym("arm", 40);
+ entry.addSynonym("high", 10);
+ entry.addSynonym("up", 15);
+ entry.addSynonym("upper", 15);
+ lexicon.put("upperarm", entry);
+
+ entry = new LexiconEntry();
+ entry.addSynonym("lowerarm", 100);
+ entry.addSynonym("ulna", 100);
+ entry.addSynonym("elbow", 75);
+ entry.addSynonym("arm", 50);
+ entry.addSynonym("low", 10);
+ entry.addSynonym("lower", 10);
+ lexicon.put("lowerarm", entry);
+
+ entry = new LexiconEntry();
+ entry.addSynonym("hand", 100);
+ entry.addSynonym("fist", 100);
+ entry.addSynonym("wrist", 75);
+ lexicon.put("hand", entry);
+
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/control/ragdoll/RagdollPreset.java b/engine/src/bullet/com/jme3/bullet/control/ragdoll/RagdollPreset.java
new file mode 100644
index 000000000..51bf4babf
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/control/ragdoll/RagdollPreset.java
@@ -0,0 +1,106 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.control.ragdoll;
+
+import com.jme3.bullet.joints.SixDofJoint;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Nehon
+ */
+public abstract class RagdollPreset {
+
+ protected static final Logger logger = Logger.getLogger(RagdollPreset.class.getName());
+ protected Map boneMap = new HashMap();
+ protected Map lexicon = new HashMap();
+
+ protected abstract void initBoneMap();
+
+ protected abstract void initLexicon();
+
+ public void setupJointForBone(String boneName, SixDofJoint joint) {
+
+ if (boneMap.isEmpty()) {
+ initBoneMap();
+ }
+ if (lexicon.isEmpty()) {
+ initLexicon();
+ }
+ String resultName = "";
+ int resultScore = 0;
+
+ for (String key : lexicon.keySet()) {
+
+ int score = lexicon.get(key).getScore(boneName);
+ if (score > resultScore) {
+ resultScore = score;
+ resultName = key;
+ }
+
+ }
+
+ JointPreset preset = boneMap.get(resultName);
+
+ if (preset != null && resultScore >= 50) {
+ logger.log(Level.INFO, "Found matching joint for bone {0} : {1} with score {2}", new Object[]{boneName, resultName, resultScore});
+ preset.setupJoint(joint);
+ } else {
+ logger.log(Level.INFO, "No joint match found for bone {0}", boneName);
+ if (resultScore > 0) {
+ logger.log(Level.INFO, "Best match found is {0} with score {1}", new Object[]{resultName, resultScore});
+ }
+ new JointPreset().setupJoint(joint);
+ }
+
+ }
+
+ protected class JointPreset {
+
+ private float maxX, minX, maxY, minY, maxZ, minZ;
+
+ public JointPreset() {
+ }
+
+ public JointPreset(float maxX, float minX, float maxY, float minY, float maxZ, float minZ) {
+ this.maxX = maxX;
+ this.minX = minX;
+ this.maxY = maxY;
+ this.minY = minY;
+ this.maxZ = maxZ;
+ this.minZ = minZ;
+ }
+
+ public void setupJoint(SixDofJoint joint) {
+ joint.getRotationalLimitMotor(0).setHiLimit(maxX);
+ joint.getRotationalLimitMotor(0).setLoLimit(minX);
+ joint.getRotationalLimitMotor(1).setHiLimit(maxY);
+ joint.getRotationalLimitMotor(1).setLoLimit(minY);
+ joint.getRotationalLimitMotor(2).setHiLimit(maxZ);
+ joint.getRotationalLimitMotor(2).setLoLimit(minZ);
+ }
+ }
+
+ protected class LexiconEntry extends HashMap {
+
+ public void addSynonym(String word, int score) {
+ put(word.toLowerCase(), score);
+ }
+
+ public int getScore(String word) {
+ int score = 0;
+ String searchWord = word.toLowerCase();
+ for (String key : this.keySet()) {
+ if (searchWord.indexOf(key) >= 0) {
+ score += get(key);
+ }
+ }
+ return score;
+ }
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/control/ragdoll/RagdollUtils.java b/engine/src/bullet/com/jme3/bullet/control/ragdoll/RagdollUtils.java
new file mode 100644
index 000000000..7aeb3a901
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/control/ragdoll/RagdollUtils.java
@@ -0,0 +1,273 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.bullet.control.ragdoll;
+
+import com.jme3.animation.Bone;
+import com.jme3.animation.Skeleton;
+import com.jme3.bullet.collision.shapes.HullCollisionShape;
+import com.jme3.bullet.joints.SixDofJoint;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.VertexBuffer.Type;
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Nehon
+ */
+public class RagdollUtils {
+
+ public static void setJointLimit(SixDofJoint joint, float maxX, float minX, float maxY, float minY, float maxZ, float minZ) {
+
+ joint.getRotationalLimitMotor(0).setHiLimit(maxX);
+ joint.getRotationalLimitMotor(0).setLoLimit(minX);
+ joint.getRotationalLimitMotor(1).setHiLimit(maxY);
+ joint.getRotationalLimitMotor(1).setLoLimit(minY);
+ joint.getRotationalLimitMotor(2).setHiLimit(maxZ);
+ joint.getRotationalLimitMotor(2).setLoLimit(minZ);
+ }
+
+ public static Map> buildPointMap(Spatial model) {
+
+
+ Map> map = new HashMap>();
+ if (model instanceof Geometry) {
+ Geometry g = (Geometry) model;
+ buildPointMapForMesh(g.getMesh(), map);
+ } else if (model instanceof Node) {
+ Node node = (Node) model;
+ for (Spatial s : node.getChildren()) {
+ if (s instanceof Geometry) {
+ Geometry g = (Geometry) s;
+ buildPointMapForMesh(g.getMesh(), map);
+ }
+ }
+ }
+ return map;
+ }
+
+ private static Map> buildPointMapForMesh(Mesh mesh, Map> map) {
+
+ FloatBuffer vertices = mesh.getFloatBuffer(Type.Position);
+ ByteBuffer boneIndices = (ByteBuffer) mesh.getBuffer(Type.BoneIndex).getData();
+ FloatBuffer boneWeight = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();
+
+ vertices.rewind();
+ boneIndices.rewind();
+ boneWeight.rewind();
+
+ int vertexComponents = mesh.getVertexCount() * 3;
+ int k, start, index;
+ float maxWeight = 0;
+
+ for (int i = 0; i < vertexComponents; i += 3) {
+
+
+ start = i / 3 * 4;
+ index = 0;
+ maxWeight = -1;
+ for (k = start; k < start + 4; k++) {
+ float weight = boneWeight.get(k);
+ if (weight > maxWeight) {
+ maxWeight = weight;
+ index = boneIndices.get(k);
+ }
+ }
+ List points = map.get(index);
+ if (points == null) {
+ points = new ArrayList();
+ map.put(index, points);
+ }
+ points.add(vertices.get(i));
+ points.add(vertices.get(i + 1));
+ points.add(vertices.get(i + 2));
+ }
+ return map;
+ }
+
+ /**
+ * Create a hull collision shape from linked vertices to this bone.
+ * Vertices have to be previoulsly gathered in a map using buildPointMap method
+ * @param link
+ * @param model
+ * @return
+ */
+ public static HullCollisionShape makeShapeFromPointMap(Map> pointsMap, List boneIndices, Vector3f initialScale, Vector3f initialPosition) {
+
+ ArrayList points = new ArrayList();
+ for (Integer index : boneIndices) {
+ List l = pointsMap.get(index);
+ if (l != null) {
+
+ for (int i = 0; i < l.size(); i += 3) {
+ Vector3f pos = new Vector3f();
+ pos.x = l.get(i);
+ pos.y = l.get(i + 1);
+ pos.z = l.get(i + 2);
+ pos.subtractLocal(initialPosition).multLocal(initialScale);
+ points.add(pos.x);
+ points.add(pos.y);
+ points.add(pos.z);
+ }
+ }
+ }
+
+ float[] p = new float[points.size()];
+ for (int i = 0; i < points.size(); i++) {
+ p[i] = points.get(i);
+ }
+
+
+ return new HullCollisionShape(p);
+ }
+
+ //retruns the list of bone indices of the given bone and its child(if they are not in the boneList)
+ public static List getBoneIndices(Bone bone, Skeleton skeleton, Set boneList) {
+ List list = new LinkedList();
+ if (boneList.isEmpty()) {
+ list.add(skeleton.getBoneIndex(bone));
+ } else {
+ list.add(skeleton.getBoneIndex(bone));
+ for (Bone chilBone : bone.getChildren()) {
+ if (!boneList.contains(chilBone.getName())) {
+ list.addAll(getBoneIndices(chilBone, skeleton, boneList));
+ }
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Create a hull collision shape from linked vertices to this bone.
+ *
+ * @param link
+ * @param model
+ * @return
+ */
+ public static HullCollisionShape makeShapeFromVerticeWeights(Spatial model, List boneIndices, Vector3f initialScale, Vector3f initialPosition, float weightThreshold) {
+
+ ArrayList points = new ArrayList();
+ if (model instanceof Geometry) {
+ Geometry g = (Geometry) model;
+ for (Integer index : boneIndices) {
+ points.addAll(getPoints(g.getMesh(), index, initialScale, initialPosition, weightThreshold));
+ }
+ } else if (model instanceof Node) {
+ Node node = (Node) model;
+ for (Spatial s : node.getChildren()) {
+ if (s instanceof Geometry) {
+ Geometry g = (Geometry) s;
+ for (Integer index : boneIndices) {
+ points.addAll(getPoints(g.getMesh(), index, initialScale, initialPosition, weightThreshold));
+ }
+
+ }
+ }
+ }
+ float[] p = new float[points.size()];
+ for (int i = 0; i < points.size(); i++) {
+ p[i] = points.get(i);
+ }
+
+
+ return new HullCollisionShape(p);
+ }
+
+ /**
+ * returns a list of points for the given bone
+ * @param mesh
+ * @param boneIndex
+ * @param offset
+ * @param link
+ * @return
+ */
+ private static List getPoints(Mesh mesh, int boneIndex, Vector3f initialScale, Vector3f offset, float weightThreshold) {
+
+ FloatBuffer vertices = mesh.getFloatBuffer(Type.Position);
+ ByteBuffer boneIndices = (ByteBuffer) mesh.getBuffer(Type.BoneIndex).getData();
+ FloatBuffer boneWeight = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();
+
+ vertices.rewind();
+ boneIndices.rewind();
+ boneWeight.rewind();
+
+ ArrayList results = new ArrayList();
+
+ int vertexComponents = mesh.getVertexCount() * 3;
+
+ for (int i = 0; i < vertexComponents; i += 3) {
+ int k;
+ boolean add = false;
+ int start = i / 3 * 4;
+ for (k = start; k < start + 4; k++) {
+ if (boneIndices.get(k) == boneIndex && boneWeight.get(k) >= weightThreshold) {
+ add = true;
+ break;
+ }
+ }
+ if (add) {
+
+ Vector3f pos = new Vector3f();
+ pos.x = vertices.get(i);
+ pos.y = vertices.get(i + 1);
+ pos.z = vertices.get(i + 2);
+ pos.subtractLocal(offset).multLocal(initialScale);
+ results.add(pos.x);
+ results.add(pos.y);
+ results.add(pos.z);
+
+ }
+ }
+
+ return results;
+ }
+
+ /**
+ * Updates a bone position and rotation.
+ * if the child bones are not in the bone list this means, they are not associated with a physic shape.
+ * So they have to be updated
+ * @param bone the bone
+ * @param pos the position
+ * @param rot the rotation
+ */
+ public static void setTransform(Bone bone, Vector3f pos, Quaternion rot, boolean restoreBoneControl, Set boneList) {
+ //we ensure that we have the control
+ if (restoreBoneControl) {
+ bone.setUserControl(true);
+ }
+ //we set te user transforms of the bone
+ bone.setUserTransformsWorld(pos, rot);
+ for (Bone childBone : bone.getChildren()) {
+ //each child bone that is not in the list is updated
+ if (!boneList.contains(childBone.getName())) {
+ Transform t = childBone.getCombinedTransform(pos, rot);
+ setTransform(childBone, t.getTranslation(), t.getRotation(), restoreBoneControl, boneList);
+ }
+ }
+ //we give back the control to the keyframed animation
+ if (restoreBoneControl) {
+ bone.setUserControl(false);
+ }
+ }
+
+ public static void setUserControl(Bone bone, boolean bool) {
+ bone.setUserControl(bool);
+ for (Bone child : bone.getChildren()) {
+ setUserControl(child, bool);
+ }
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/joints/ConeJoint.java b/engine/src/bullet/com/jme3/bullet/joints/ConeJoint.java
new file mode 100644
index 000000000..cddcbac53
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/joints/ConeJoint.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.joints;
+
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Vector3f;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * From bullet manual:
+ * To create ragdolls, the conve twist constraint is very useful for limbs like the upper arm.
+ * It is a special point to point constraint that adds cone and twist axis limits.
+ * The x-axis serves as twist axis.
+ * @author normenhansen
+ */
+public class ConeJoint extends PhysicsJoint {
+
+ protected Matrix3f rotA, rotB;
+ protected float swingSpan1 = 1e30f;
+ protected float swingSpan2 = 1e30f;
+ protected float twistSpan = 1e30f;
+ protected boolean angularOnly = false;
+
+ public ConeJoint() {
+ }
+
+ /**
+ * @param pivotA local translation of the joint connection point in node A
+ * @param pivotB local translation of the joint connection point in node B
+ */
+ public ConeJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB) {
+ super(nodeA, nodeB, pivotA, pivotB);
+ this.rotA = new Matrix3f();
+ this.rotB = new Matrix3f();
+ createJoint();
+ }
+
+ /**
+ * @param pivotA local translation of the joint connection point in node A
+ * @param pivotB local translation of the joint connection point in node B
+ */
+ public ConeJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB, Matrix3f rotA, Matrix3f rotB) {
+ super(nodeA, nodeB, pivotA, pivotB);
+ this.rotA = rotA;
+ this.rotB = rotB;
+ createJoint();
+ }
+
+ public void setLimit(float swingSpan1, float swingSpan2, float twistSpan) {
+ this.swingSpan1 = swingSpan1;
+ this.swingSpan2 = swingSpan2;
+ this.twistSpan = twistSpan;
+ setLimit(objectId, swingSpan1, swingSpan2, twistSpan);
+ }
+
+ private native void setLimit(long objectId, float swingSpan1, float swingSpan2, float twistSpan);
+
+ public void setAngularOnly(boolean value) {
+ angularOnly = value;
+ setAngularOnly(objectId, value);
+ }
+
+ private native void setAngularOnly(long objectId, boolean value);
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(rotA, "rotA", new Matrix3f());
+ capsule.write(rotB, "rotB", new Matrix3f());
+
+ capsule.write(angularOnly, "angularOnly", false);
+ capsule.write(swingSpan1, "swingSpan1", 1e30f);
+ capsule.write(swingSpan2, "swingSpan2", 1e30f);
+ capsule.write(twistSpan, "twistSpan", 1e30f);
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ this.rotA = (Matrix3f) capsule.readSavable("rotA", new Matrix3f());
+ this.rotB = (Matrix3f) capsule.readSavable("rotB", new Matrix3f());
+
+ this.angularOnly = capsule.readBoolean("angularOnly", false);
+ this.swingSpan1 = capsule.readFloat("swingSpan1", 1e30f);
+ this.swingSpan2 = capsule.readFloat("swingSpan2", 1e30f);
+ this.twistSpan = capsule.readFloat("twistSpan", 1e30f);
+ createJoint();
+ }
+
+ protected void createJoint() {
+ objectId = createJoint(nodeA.getObjectId(), nodeB.getObjectId(), pivotA, rotA, pivotB, rotB);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Joint {0}", Long.toHexString(objectId));
+ setLimit(objectId, swingSpan1, swingSpan2, twistSpan);
+ setAngularOnly(objectId, angularOnly);
+ }
+
+ private native long createJoint(long objectIdA, long objectIdB, Vector3f pivotA, Matrix3f rotA, Vector3f pivotB, Matrix3f rotB);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/joints/HingeJoint.java b/engine/src/bullet/com/jme3/bullet/joints/HingeJoint.java
new file mode 100644
index 000000000..b8ac7d3b2
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/joints/HingeJoint.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.joints;
+
+import com.jme3.math.Vector3f;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * From bullet manual:
+ * Hinge constraint, or revolute joint restricts two additional angular degrees of freedom,
+ * so the body can only rotate around one axis, the hinge axis.
+ * This can be useful to represent doors or wheels rotating around one axis.
+ * The user can specify limits and motor for the hinge.
+ * @author normenhansen
+ */
+public class HingeJoint extends PhysicsJoint {
+
+ protected Vector3f axisA;
+ protected Vector3f axisB;
+ protected boolean angularOnly = false;
+ protected float biasFactor = 0.3f;
+ protected float relaxationFactor = 1.0f;
+ protected float limitSoftness = 0.9f;
+
+ public HingeJoint() {
+ }
+
+ /**
+ * Creates a new HingeJoint
+ * @param pivotA local translation of the joint connection point in node A
+ * @param pivotB local translation of the joint connection point in node B
+ */
+ public HingeJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB, Vector3f axisA, Vector3f axisB) {
+ super(nodeA, nodeB, pivotA, pivotB);
+ this.axisA = axisA;
+ this.axisB = axisB;
+ createJoint();
+ }
+
+ public void enableMotor(boolean enable, float targetVelocity, float maxMotorImpulse) {
+ enableMotor(objectId, enable, targetVelocity, maxMotorImpulse);
+ }
+
+ private native void enableMotor(long objectId, boolean enable, float targetVelocity, float maxMotorImpulse);
+
+ public boolean getEnableMotor() {
+ return getEnableAngularMotor(objectId);
+ }
+
+ private native boolean getEnableAngularMotor(long objectId);
+
+ public float getMotorTargetVelocity() {
+ return getMotorTargetVelocity(objectId);
+ }
+
+ private native float getMotorTargetVelocity(long objectId);
+
+ public float getMaxMotorImpulse() {
+ return getMaxMotorImpulse(objectId);
+ }
+
+ private native float getMaxMotorImpulse(long objectId);
+
+ public void setLimit(float low, float high) {
+ setLimit(objectId, low, high);
+ }
+
+ private native void setLimit(long objectId, float low, float high);
+
+ public void setLimit(float low, float high, float _softness, float _biasFactor, float _relaxationFactor) {
+ biasFactor = _biasFactor;
+ relaxationFactor = _relaxationFactor;
+ limitSoftness = _softness;
+ setLimit(objectId, low, high, _softness, _biasFactor, _relaxationFactor);
+ }
+
+ private native void setLimit(long objectId, float low, float high, float _softness, float _biasFactor, float _relaxationFactor);
+
+ public float getUpperLimit() {
+ return getUpperLimit(objectId);
+ }
+
+ private native float getUpperLimit(long objectId);
+
+ public float getLowerLimit() {
+ return getLowerLimit(objectId);
+ }
+
+ private native float getLowerLimit(long objectId);
+
+ public void setAngularOnly(boolean angularOnly) {
+ this.angularOnly = angularOnly;
+ setAngularOnly(objectId, angularOnly);
+ }
+
+ private native void setAngularOnly(long objectId, boolean angularOnly);
+
+ public float getHingeAngle() {
+ return getHingeAngle(objectId);
+ }
+
+ private native float getHingeAngle(long objectId);
+
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(axisA, "axisA", new Vector3f());
+ capsule.write(axisB, "axisB", new Vector3f());
+
+ capsule.write(angularOnly, "angularOnly", false);
+
+ capsule.write(getLowerLimit(), "lowerLimit", 1e30f);
+ capsule.write(getUpperLimit(), "upperLimit", -1e30f);
+
+ capsule.write(biasFactor, "biasFactor", 0.3f);
+ capsule.write(relaxationFactor, "relaxationFactor", 1f);
+ capsule.write(limitSoftness, "limitSoftness", 0.9f);
+
+ capsule.write(getEnableMotor(), "enableAngularMotor", false);
+ capsule.write(getMotorTargetVelocity(), "targetVelocity", 0.0f);
+ capsule.write(getMaxMotorImpulse(), "maxMotorImpulse", 0.0f);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ this.axisA = (Vector3f) capsule.readSavable("axisA", new Vector3f());
+ this.axisB = (Vector3f) capsule.readSavable("axisB", new Vector3f());
+
+ this.angularOnly = capsule.readBoolean("angularOnly", false);
+ float lowerLimit = capsule.readFloat("lowerLimit", 1e30f);
+ float upperLimit = capsule.readFloat("upperLimit", -1e30f);
+
+ this.biasFactor = capsule.readFloat("biasFactor", 0.3f);
+ this.relaxationFactor = capsule.readFloat("relaxationFactor", 1f);
+ this.limitSoftness = capsule.readFloat("limitSoftness", 0.9f);
+
+ boolean enableAngularMotor = capsule.readBoolean("enableAngularMotor", false);
+ float targetVelocity = capsule.readFloat("targetVelocity", 0.0f);
+ float maxMotorImpulse = capsule.readFloat("maxMotorImpulse", 0.0f);
+
+ createJoint();
+ enableMotor(enableAngularMotor, targetVelocity, maxMotorImpulse);
+ setLimit(lowerLimit, upperLimit, limitSoftness, biasFactor, relaxationFactor);
+ }
+
+ protected void createJoint() {
+ objectId = createJoint(nodeA.getObjectId(), nodeB.getObjectId(), pivotA, axisA, pivotB, axisB);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Joint {0}", Long.toHexString(objectId));
+ }
+
+ private native long createJoint(long objectIdA, long objectIdB, Vector3f pivotA, Vector3f axisA, Vector3f pivotB, Vector3f axisB);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/joints/PhysicsJoint.java b/engine/src/bullet/com/jme3/bullet/joints/PhysicsJoint.java
new file mode 100644
index 000000000..53164ef76
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/joints/PhysicsJoint.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.joints;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.Vector3f;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import com.jme3.export.Savable;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * PhysicsJoint - Basic Phyiscs Joint
+ * @author normenhansen
+ */
+public abstract class PhysicsJoint implements Savable {
+
+ protected long objectId = 0;
+ protected PhysicsRigidBody nodeA;
+ protected PhysicsRigidBody nodeB;
+ protected Vector3f pivotA;
+ protected Vector3f pivotB;
+ protected boolean collisionBetweenLinkedBodys = true;
+
+ public PhysicsJoint() {
+ }
+
+ /**
+ * @param pivotA local translation of the joint connection point in node A
+ * @param pivotB local translation of the joint connection point in node B
+ */
+ public PhysicsJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB) {
+ this.nodeA = nodeA;
+ this.nodeB = nodeB;
+ this.pivotA = pivotA;
+ this.pivotB = pivotB;
+ nodeA.addJoint(this);
+ nodeB.addJoint(this);
+ }
+
+ public float getAppliedImpulse() {
+ return getAppliedImpulse(objectId);
+ }
+
+ private native float getAppliedImpulse(long objectId);
+
+ /**
+ * @return the constraint
+ */
+ public long getObjectId() {
+ return objectId;
+ }
+
+ /**
+ * @return the collisionBetweenLinkedBodys
+ */
+ public boolean isCollisionBetweenLinkedBodys() {
+ return collisionBetweenLinkedBodys;
+ }
+
+ /**
+ * toggles collisions between linked bodys
+ * joint has to be removed from and added to PhyiscsSpace to apply this.
+ * @param collisionBetweenLinkedBodys set to false to have no collisions between linked bodys
+ */
+ public void setCollisionBetweenLinkedBodys(boolean collisionBetweenLinkedBodys) {
+ this.collisionBetweenLinkedBodys = collisionBetweenLinkedBodys;
+ }
+
+ public PhysicsRigidBody getBodyA() {
+ return nodeA;
+ }
+
+ public PhysicsRigidBody getBodyB() {
+ return nodeB;
+ }
+
+ public Vector3f getPivotA() {
+ return pivotA;
+ }
+
+ public Vector3f getPivotB() {
+ return pivotB;
+ }
+
+ /**
+ * destroys this joint and removes it from its connected PhysicsRigidBodys joint lists
+ */
+ public void destroy() {
+ getBodyA().removeJoint(this);
+ getBodyB().removeJoint(this);
+ }
+
+ public void write(JmeExporter ex) throws IOException {
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(nodeA, "nodeA", null);
+ capsule.write(nodeB, "nodeB", null);
+ capsule.write(pivotA, "pivotA", null);
+ capsule.write(pivotB, "pivotB", null);
+ }
+
+ public void read(JmeImporter im) throws IOException {
+ InputCapsule capsule = im.getCapsule(this);
+ this.nodeA = ((PhysicsRigidBody) capsule.readSavable("nodeA", new PhysicsRigidBody()));
+ this.nodeB = (PhysicsRigidBody) capsule.readSavable("nodeB", new PhysicsRigidBody());
+ this.pivotA = (Vector3f) capsule.readSavable("pivotA", new Vector3f());
+ this.pivotB = (Vector3f) capsule.readSavable("pivotB", new Vector3f());
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing Joint {0}", Long.toHexString(objectId));
+ finalizeNative(objectId);
+ }
+
+ private native void finalizeNative(long objectId);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/joints/Point2PointJoint.java b/engine/src/bullet/com/jme3/bullet/joints/Point2PointJoint.java
new file mode 100644
index 000000000..c19039005
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/joints/Point2PointJoint.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.joints;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.Vector3f;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * From bullet manual:
+ * Point to point constraint, also known as ball socket joint limits the translation
+ * so that the local pivot points of 2 rigidbodies match in worldspace.
+ * A chain of rigidbodies can be connected using this constraint.
+ * @author normenhansen
+ */
+public class Point2PointJoint extends PhysicsJoint {
+
+ public Point2PointJoint() {
+ }
+
+ /**
+ * @param pivotA local translation of the joint connection point in node A
+ * @param pivotB local translation of the joint connection point in node B
+ */
+ public Point2PointJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB) {
+ super(nodeA, nodeB, pivotA, pivotB);
+ createJoint();
+ }
+
+ public void setDamping(float value) {
+ setDamping(objectId, value);
+ }
+
+ private native void setDamping(long objectId, float value);
+
+ public void setImpulseClamp(float value) {
+ setImpulseClamp(objectId, value);
+ }
+
+ private native void setImpulseClamp(long objectId, float value);
+
+ public void setTau(float value) {
+ setTau(objectId, value);
+ }
+
+ private native void setTau(long objectId, float value);
+
+ public float getDamping() {
+ return getDamping(objectId);
+ }
+
+ private native float getDamping(long objectId);
+
+ public float getImpulseClamp() {
+ return getImpulseClamp(objectId);
+ }
+
+ private native float getImpulseClamp(long objectId);
+
+ public float getTau() {
+ return getTau(objectId);
+ }
+
+ private native float getTau(long objectId);
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule cap = ex.getCapsule(this);
+ cap.write(getDamping(), "damping", 1.0f);
+ cap.write(getTau(), "tau", 0.3f);
+ cap.write(getImpulseClamp(), "impulseClamp", 0f);
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ createJoint();
+ InputCapsule cap = im.getCapsule(this);
+ setDamping(cap.readFloat("damping", 1.0f));
+ setDamping(cap.readFloat("tau", 0.3f));
+ setDamping(cap.readFloat("impulseClamp", 0f));
+ }
+
+ protected void createJoint() {
+ objectId = createJoint(nodeA.getObjectId(), nodeB.getObjectId(), pivotA, pivotB);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Joint {0}", Long.toHexString(objectId));
+ }
+
+ private native long createJoint(long objectIdA, long objectIdB, Vector3f pivotA, Vector3f pivotB);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/joints/SixDofJoint.java b/engine/src/bullet/com/jme3/bullet/joints/SixDofJoint.java
new file mode 100644
index 000000000..6bed78f25
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/joints/SixDofJoint.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.joints;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Vector3f;
+import com.jme3.bullet.joints.motors.RotationalLimitMotor;
+import com.jme3.bullet.joints.motors.TranslationalLimitMotor;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * From bullet manual:
+ * This generic constraint can emulate a variety of standard constraints,
+ * by configuring each of the 6 degrees of freedom (dof).
+ * The first 3 dof axis are linear axis, which represent translation of rigidbodies,
+ * and the latter 3 dof axis represent the angular motion. Each axis can be either locked,
+ * free or limited. On construction of a new btGeneric6DofConstraint, all axis are locked.
+ * Afterwards the axis can be reconfigured. Note that several combinations that
+ * include free and/or limited angular degrees of freedom are undefined.
+ * @author normenhansen
+ */
+public class SixDofJoint extends PhysicsJoint {
+
+ private Matrix3f rotA, rotB;
+ private boolean useLinearReferenceFrameA;
+ private LinkedList rotationalMotors = new LinkedList();
+ private TranslationalLimitMotor translationalMotor;
+ private Vector3f angularUpperLimit = new Vector3f(Vector3f.POSITIVE_INFINITY);
+ private Vector3f angularLowerLimit = new Vector3f(Vector3f.NEGATIVE_INFINITY);
+ private Vector3f linearUpperLimit = new Vector3f(Vector3f.POSITIVE_INFINITY);
+ private Vector3f linearLowerLimit = new Vector3f(Vector3f.NEGATIVE_INFINITY);
+
+ public SixDofJoint() {
+ }
+
+ /**
+ * @param pivotA local translation of the joint connection point in node A
+ * @param pivotB local translation of the joint connection point in node B
+ */
+ public SixDofJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB, Matrix3f rotA, Matrix3f rotB, boolean useLinearReferenceFrameA) {
+ super(nodeA, nodeB, pivotA, pivotB);
+ this.useLinearReferenceFrameA = useLinearReferenceFrameA;
+ this.rotA = rotA;
+ this.rotB = rotB;
+
+ objectId = createJoint(nodeA.getObjectId(), nodeB.getObjectId(), pivotA, rotA, pivotB, rotB, useLinearReferenceFrameA);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Joint {0}", Long.toHexString(objectId));
+ gatherMotors();
+ }
+
+ /**
+ * @param pivotA local translation of the joint connection point in node A
+ * @param pivotB local translation of the joint connection point in node B
+ */
+ public SixDofJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB, boolean useLinearReferenceFrameA) {
+ super(nodeA, nodeB, pivotA, pivotB);
+ this.useLinearReferenceFrameA = useLinearReferenceFrameA;
+ rotA = new Matrix3f();
+ rotB = new Matrix3f();
+
+ objectId = createJoint(nodeA.getObjectId(), nodeB.getObjectId(), pivotA, rotA, pivotB, rotB, useLinearReferenceFrameA);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Joint {0}", Long.toHexString(objectId));
+ gatherMotors();
+ }
+
+ private void gatherMotors() {
+ for (int i = 0; i < 3; i++) {
+ RotationalLimitMotor rmot = new RotationalLimitMotor(getRotationalLimitMotor(objectId, i));
+ rotationalMotors.add(rmot);
+ }
+ translationalMotor = new TranslationalLimitMotor(getTranslationalLimitMotor(objectId));
+ }
+
+ private native long getRotationalLimitMotor(long objectId, int index);
+
+ private native long getTranslationalLimitMotor(long objectId);
+
+ /**
+ * returns the TranslationalLimitMotor of this 6DofJoint which allows
+ * manipulating the translational axis
+ * @return the TranslationalLimitMotor
+ */
+ public TranslationalLimitMotor getTranslationalLimitMotor() {
+ return translationalMotor;
+ }
+
+ /**
+ * returns one of the three RotationalLimitMotors of this 6DofJoint which
+ * allow manipulating the rotational axes
+ * @param index the index of the RotationalLimitMotor
+ * @return the RotationalLimitMotor at the given index
+ */
+ public RotationalLimitMotor getRotationalLimitMotor(int index) {
+ return rotationalMotors.get(index);
+ }
+
+ public void setLinearUpperLimit(Vector3f vector) {
+ linearUpperLimit.set(vector);
+ setLinearUpperLimit(objectId, vector);
+ }
+
+ private native void setLinearUpperLimit(long objctId, Vector3f vector);
+
+ public void setLinearLowerLimit(Vector3f vector) {
+ linearLowerLimit.set(vector);
+ setLinearLowerLimit(objectId, vector);
+ }
+
+ private native void setLinearLowerLimit(long objctId, Vector3f vector);
+
+ public void setAngularUpperLimit(Vector3f vector) {
+ angularUpperLimit.set(vector);
+ setAngularUpperLimit(objectId, vector);
+ }
+
+ private native void setAngularUpperLimit(long objctId, Vector3f vector);
+
+ public void setAngularLowerLimit(Vector3f vector) {
+ angularLowerLimit.set(vector);
+ setAngularLowerLimit(objectId, vector);
+ }
+
+ private native void setAngularLowerLimit(long objctId, Vector3f vector);
+
+ private native long createJoint(long objectIdA, long objectIdB, Vector3f pivotA, Matrix3f rotA, Vector3f pivotB, Matrix3f rotB, boolean useLinearReferenceFrameA);
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+
+ objectId = createJoint(nodeA.getObjectId(), nodeB.getObjectId(), pivotA, rotA, pivotB, rotB, useLinearReferenceFrameA);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Joint {0}", Long.toHexString(objectId));
+ gatherMotors();
+
+ setAngularUpperLimit((Vector3f) capsule.readSavable("angularUpperLimit", new Vector3f(Vector3f.POSITIVE_INFINITY)));
+ setAngularLowerLimit((Vector3f) capsule.readSavable("angularLowerLimit", new Vector3f(Vector3f.NEGATIVE_INFINITY)));
+ setLinearUpperLimit((Vector3f) capsule.readSavable("linearUpperLimit", new Vector3f(Vector3f.POSITIVE_INFINITY)));
+ setLinearLowerLimit((Vector3f) capsule.readSavable("linearLowerLimit", new Vector3f(Vector3f.NEGATIVE_INFINITY)));
+
+ for (int i = 0; i < 3; i++) {
+ RotationalLimitMotor rotationalLimitMotor = getRotationalLimitMotor(i);
+ rotationalLimitMotor.setBounce(capsule.readFloat("rotMotor" + i + "_Bounce", 0.0f));
+ rotationalLimitMotor.setDamping(capsule.readFloat("rotMotor" + i + "_Damping", 1.0f));
+ rotationalLimitMotor.setERP(capsule.readFloat("rotMotor" + i + "_ERP", 0.5f));
+ rotationalLimitMotor.setHiLimit(capsule.readFloat("rotMotor" + i + "_HiLimit", Float.POSITIVE_INFINITY));
+ rotationalLimitMotor.setLimitSoftness(capsule.readFloat("rotMotor" + i + "_LimitSoftness", 0.5f));
+ rotationalLimitMotor.setLoLimit(capsule.readFloat("rotMotor" + i + "_LoLimit", Float.NEGATIVE_INFINITY));
+ rotationalLimitMotor.setMaxLimitForce(capsule.readFloat("rotMotor" + i + "_MaxLimitForce", 300.0f));
+ rotationalLimitMotor.setMaxMotorForce(capsule.readFloat("rotMotor" + i + "_MaxMotorForce", 0.1f));
+ rotationalLimitMotor.setTargetVelocity(capsule.readFloat("rotMotor" + i + "_TargetVelocity", 0));
+ rotationalLimitMotor.setEnableMotor(capsule.readBoolean("rotMotor" + i + "_EnableMotor", false));
+ }
+ getTranslationalLimitMotor().setAccumulatedImpulse((Vector3f) capsule.readSavable("transMotor_AccumulatedImpulse", Vector3f.ZERO));
+ getTranslationalLimitMotor().setDamping(capsule.readFloat("transMotor_Damping", 1.0f));
+ getTranslationalLimitMotor().setLimitSoftness(capsule.readFloat("transMotor_LimitSoftness", 0.7f));
+ getTranslationalLimitMotor().setLowerLimit((Vector3f) capsule.readSavable("transMotor_LowerLimit", Vector3f.ZERO));
+ getTranslationalLimitMotor().setRestitution(capsule.readFloat("transMotor_Restitution", 0.5f));
+ getTranslationalLimitMotor().setUpperLimit((Vector3f) capsule.readSavable("transMotor_UpperLimit", Vector3f.ZERO));
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(angularUpperLimit, "angularUpperLimit", new Vector3f(Vector3f.POSITIVE_INFINITY));
+ capsule.write(angularLowerLimit, "angularLowerLimit", new Vector3f(Vector3f.NEGATIVE_INFINITY));
+ capsule.write(linearUpperLimit, "linearUpperLimit", new Vector3f(Vector3f.POSITIVE_INFINITY));
+ capsule.write(linearLowerLimit, "linearLowerLimit", new Vector3f(Vector3f.NEGATIVE_INFINITY));
+ int i = 0;
+ for (Iterator it = rotationalMotors.iterator(); it.hasNext();) {
+ RotationalLimitMotor rotationalLimitMotor = it.next();
+ capsule.write(rotationalLimitMotor.getBounce(), "rotMotor" + i + "_Bounce", 0.0f);
+ capsule.write(rotationalLimitMotor.getDamping(), "rotMotor" + i + "_Damping", 1.0f);
+ capsule.write(rotationalLimitMotor.getERP(), "rotMotor" + i + "_ERP", 0.5f);
+ capsule.write(rotationalLimitMotor.getHiLimit(), "rotMotor" + i + "_HiLimit", Float.POSITIVE_INFINITY);
+ capsule.write(rotationalLimitMotor.getLimitSoftness(), "rotMotor" + i + "_LimitSoftness", 0.5f);
+ capsule.write(rotationalLimitMotor.getLoLimit(), "rotMotor" + i + "_LoLimit", Float.NEGATIVE_INFINITY);
+ capsule.write(rotationalLimitMotor.getMaxLimitForce(), "rotMotor" + i + "_MaxLimitForce", 300.0f);
+ capsule.write(rotationalLimitMotor.getMaxMotorForce(), "rotMotor" + i + "_MaxMotorForce", 0.1f);
+ capsule.write(rotationalLimitMotor.getTargetVelocity(), "rotMotor" + i + "_TargetVelocity", 0);
+ capsule.write(rotationalLimitMotor.isEnableMotor(), "rotMotor" + i + "_EnableMotor", false);
+ i++;
+ }
+ capsule.write(getTranslationalLimitMotor().getAccumulatedImpulse(), "transMotor_AccumulatedImpulse", Vector3f.ZERO);
+ capsule.write(getTranslationalLimitMotor().getDamping(), "transMotor_Damping", 1.0f);
+ capsule.write(getTranslationalLimitMotor().getLimitSoftness(), "transMotor_LimitSoftness", 0.7f);
+ capsule.write(getTranslationalLimitMotor().getLowerLimit(), "transMotor_LowerLimit", Vector3f.ZERO);
+ capsule.write(getTranslationalLimitMotor().getRestitution(), "transMotor_Restitution", 0.5f);
+ capsule.write(getTranslationalLimitMotor().getUpperLimit(), "transMotor_UpperLimit", Vector3f.ZERO);
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/joints/SliderJoint.java b/engine/src/bullet/com/jme3/bullet/joints/SliderJoint.java
new file mode 100644
index 000000000..f979a3149
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/joints/SliderJoint.java
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.joints;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Vector3f;
+import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.bullet.util.Converter;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * From bullet manual:
+ * The slider constraint allows the body to rotate around one axis and translate along this axis.
+ * @author normenhansen
+ */
+public class SliderJoint extends PhysicsJoint {
+
+ protected Matrix3f rotA, rotB;
+ protected boolean useLinearReferenceFrameA;
+
+ public SliderJoint() {
+ }
+
+ /**
+ * @param pivotA local translation of the joint connection point in node A
+ * @param pivotB local translation of the joint connection point in node B
+ */
+ public SliderJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB, Matrix3f rotA, Matrix3f rotB, boolean useLinearReferenceFrameA) {
+ super(nodeA, nodeB, pivotA, pivotB);
+ this.rotA = rotA;
+ this.rotB = rotB;
+ this.useLinearReferenceFrameA = useLinearReferenceFrameA;
+ createJoint();
+ }
+
+ /**
+ * @param pivotA local translation of the joint connection point in node A
+ * @param pivotB local translation of the joint connection point in node B
+ */
+ public SliderJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB, boolean useLinearReferenceFrameA) {
+ super(nodeA, nodeB, pivotA, pivotB);
+ this.rotA = new Matrix3f();
+ this.rotB = new Matrix3f();
+ this.useLinearReferenceFrameA = useLinearReferenceFrameA;
+ createJoint();
+ }
+
+ public float getLowerLinLimit() {
+ return getLowerLinLimit(objectId);
+ }
+
+ private native float getLowerLinLimit(long objectId);
+
+ public void setLowerLinLimit(float lowerLinLimit) {
+ setLowerLinLimit(objectId, lowerLinLimit);
+ }
+
+ private native void setLowerLinLimit(long objectId, float value);
+
+ public float getUpperLinLimit() {
+ return getUpperLinLimit(objectId);
+ }
+
+ private native float getUpperLinLimit(long objectId);
+
+ public void setUpperLinLimit(float upperLinLimit) {
+ setUpperLinLimit(objectId, upperLinLimit);
+ }
+
+ private native void setUpperLinLimit(long objectId, float value);
+
+ public float getLowerAngLimit() {
+ return getLowerAngLimit(objectId);
+ }
+
+ private native float getLowerAngLimit(long objectId);
+
+ public void setLowerAngLimit(float lowerAngLimit) {
+ setLowerAngLimit(objectId, lowerAngLimit);
+ }
+
+ private native void setLowerAngLimit(long objectId, float value);
+
+ public float getUpperAngLimit() {
+ return getUpperAngLimit(objectId);
+ }
+
+ private native float getUpperAngLimit(long objectId);
+
+ public void setUpperAngLimit(float upperAngLimit) {
+ setUpperAngLimit(objectId, upperAngLimit);
+ }
+
+ private native void setUpperAngLimit(long objectId, float value);
+
+ public float getSoftnessDirLin() {
+ return getSoftnessDirLin(objectId);
+ }
+
+ private native float getSoftnessDirLin(long objectId);
+
+ public void setSoftnessDirLin(float softnessDirLin) {
+ setSoftnessDirLin(objectId, softnessDirLin);
+ }
+
+ private native void setSoftnessDirLin(long objectId, float value);
+
+ public float getRestitutionDirLin() {
+ return getRestitutionDirLin(objectId);
+ }
+
+ private native float getRestitutionDirLin(long objectId);
+
+ public void setRestitutionDirLin(float restitutionDirLin) {
+ setRestitutionDirLin(objectId, restitutionDirLin);
+ }
+
+ private native void setRestitutionDirLin(long objectId, float value);
+
+ public float getDampingDirLin() {
+ return getDampingDirLin(objectId);
+ }
+
+ private native float getDampingDirLin(long objectId);
+
+ public void setDampingDirLin(float dampingDirLin) {
+ setDampingDirLin(objectId, dampingDirLin);
+ }
+
+ private native void setDampingDirLin(long objectId, float value);
+
+ public float getSoftnessDirAng() {
+ return getSoftnessDirAng(objectId);
+ }
+
+ private native float getSoftnessDirAng(long objectId);
+
+ public void setSoftnessDirAng(float softnessDirAng) {
+ setSoftnessDirAng(objectId, softnessDirAng);
+ }
+
+ private native void setSoftnessDirAng(long objectId, float value);
+
+ public float getRestitutionDirAng() {
+ return getRestitutionDirAng(objectId);
+ }
+
+ private native float getRestitutionDirAng(long objectId);
+
+ public void setRestitutionDirAng(float restitutionDirAng) {
+ setRestitutionDirAng(objectId, restitutionDirAng);
+ }
+
+ private native void setRestitutionDirAng(long objectId, float value);
+
+ public float getDampingDirAng() {
+ return getDampingDirAng(objectId);
+ }
+
+ private native float getDampingDirAng(long objectId);
+
+ public void setDampingDirAng(float dampingDirAng) {
+ setDampingDirAng(objectId, dampingDirAng);
+ }
+
+ private native void setDampingDirAng(long objectId, float value);
+
+ public float getSoftnessLimLin() {
+ return getSoftnessLimLin(objectId);
+ }
+
+ private native float getSoftnessLimLin(long objectId);
+
+ public void setSoftnessLimLin(float softnessLimLin) {
+ setSoftnessLimLin(objectId, softnessLimLin);
+ }
+
+ private native void setSoftnessLimLin(long objectId, float value);
+
+ public float getRestitutionLimLin() {
+ return getRestitutionLimLin(objectId);
+ }
+
+ private native float getRestitutionLimLin(long objectId);
+
+ public void setRestitutionLimLin(float restitutionLimLin) {
+ setRestitutionLimLin(objectId, restitutionLimLin);
+ }
+
+ private native void setRestitutionLimLin(long objectId, float value);
+
+ public float getDampingLimLin() {
+ return getDampingLimLin(objectId);
+ }
+
+ private native float getDampingLimLin(long objectId);
+
+ public void setDampingLimLin(float dampingLimLin) {
+ setDampingLimLin(objectId, dampingLimLin);
+ }
+
+ private native void setDampingLimLin(long objectId, float value);
+
+ public float getSoftnessLimAng() {
+ return getSoftnessLimAng(objectId);
+ }
+
+ private native float getSoftnessLimAng(long objectId);
+
+ public void setSoftnessLimAng(float softnessLimAng) {
+ setSoftnessLimAng(objectId, softnessLimAng);
+ }
+
+ private native void setSoftnessLimAng(long objectId, float value);
+
+ public float getRestitutionLimAng() {
+ return getRestitutionLimAng(objectId);
+ }
+
+ private native float getRestitutionLimAng(long objectId);
+
+ public void setRestitutionLimAng(float restitutionLimAng) {
+ setRestitutionLimAng(objectId, restitutionLimAng);
+ }
+
+ private native void setRestitutionLimAng(long objectId, float value);
+
+ public float getDampingLimAng() {
+ return getDampingLimAng(objectId);
+ }
+
+ private native float getDampingLimAng(long objectId);
+
+ public void setDampingLimAng(float dampingLimAng) {
+ setDampingLimAng(objectId, dampingLimAng);
+ }
+
+ private native void setDampingLimAng(long objectId, float value);
+
+ public float getSoftnessOrthoLin() {
+ return getSoftnessOrthoLin(objectId);
+ }
+
+ private native float getSoftnessOrthoLin(long objectId);
+
+ public void setSoftnessOrthoLin(float softnessOrthoLin) {
+ setSoftnessOrthoLin(objectId, softnessOrthoLin);
+ }
+
+ private native void setSoftnessOrthoLin(long objectId, float value);
+
+ public float getRestitutionOrthoLin() {
+ return getRestitutionOrthoLin(objectId);
+ }
+
+ private native float getRestitutionOrthoLin(long objectId);
+
+ public void setRestitutionOrthoLin(float restitutionOrthoLin) {
+ setDampingOrthoLin(objectId, restitutionOrthoLin);
+ }
+
+ private native void setRestitutionOrthoLin(long objectId, float value);
+
+ public float getDampingOrthoLin() {
+ return getDampingOrthoLin(objectId);
+ }
+
+ private native float getDampingOrthoLin(long objectId);
+
+ public void setDampingOrthoLin(float dampingOrthoLin) {
+ setDampingOrthoLin(objectId, dampingOrthoLin);
+ }
+
+ private native void setDampingOrthoLin(long objectId, float value);
+
+ public float getSoftnessOrthoAng() {
+ return getSoftnessOrthoAng(objectId);
+ }
+
+ private native float getSoftnessOrthoAng(long objectId);
+
+ public void setSoftnessOrthoAng(float softnessOrthoAng) {
+ setSoftnessOrthoAng(objectId, softnessOrthoAng);
+ }
+
+ private native void setSoftnessOrthoAng(long objectId, float value);
+
+ public float getRestitutionOrthoAng() {
+ return getRestitutionOrthoAng(objectId);
+ }
+
+ private native float getRestitutionOrthoAng(long objectId);
+
+ public void setRestitutionOrthoAng(float restitutionOrthoAng) {
+ setRestitutionOrthoAng(objectId, restitutionOrthoAng);
+ }
+
+ private native void setRestitutionOrthoAng(long objectId, float value);
+
+ public float getDampingOrthoAng() {
+ return getDampingOrthoAng(objectId);
+ }
+
+ private native float getDampingOrthoAng(long objectId);
+
+ public void setDampingOrthoAng(float dampingOrthoAng) {
+ setDampingOrthoAng(objectId, dampingOrthoAng);
+ }
+
+ private native void setDampingOrthoAng(long objectId, float value);
+
+ public boolean isPoweredLinMotor() {
+ return isPoweredLinMotor(objectId);
+ }
+
+ private native boolean isPoweredLinMotor(long objectId);
+
+ public void setPoweredLinMotor(boolean poweredLinMotor) {
+ setPoweredLinMotor(objectId, poweredLinMotor);
+ }
+
+ private native void setPoweredLinMotor(long objectId, boolean value);
+
+ public float getTargetLinMotorVelocity() {
+ return getTargetLinMotorVelocity(objectId);
+ }
+
+ private native float getTargetLinMotorVelocity(long objectId);
+
+ public void setTargetLinMotorVelocity(float targetLinMotorVelocity) {
+ setTargetLinMotorVelocity(objectId, targetLinMotorVelocity);
+ }
+
+ private native void setTargetLinMotorVelocity(long objectId, float value);
+
+ public float getMaxLinMotorForce() {
+ return getMaxLinMotorForce(objectId);
+ }
+
+ private native float getMaxLinMotorForce(long objectId);
+
+ public void setMaxLinMotorForce(float maxLinMotorForce) {
+ setMaxLinMotorForce(objectId, maxLinMotorForce);
+ }
+
+ private native void setMaxLinMotorForce(long objectId, float value);
+
+ public boolean isPoweredAngMotor() {
+ return isPoweredAngMotor(objectId);
+ }
+
+ private native boolean isPoweredAngMotor(long objectId);
+
+ public void setPoweredAngMotor(boolean poweredAngMotor) {
+ setPoweredAngMotor(objectId, poweredAngMotor);
+ }
+
+ private native void setPoweredAngMotor(long objectId, boolean value);
+
+ public float getTargetAngMotorVelocity() {
+ return getTargetAngMotorVelocity(objectId);
+ }
+
+ private native float getTargetAngMotorVelocity(long objectId);
+
+ public void setTargetAngMotorVelocity(float targetAngMotorVelocity) {
+ setTargetAngMotorVelocity(objectId, targetAngMotorVelocity);
+ }
+
+ private native void setTargetAngMotorVelocity(long objectId, float value);
+
+ public float getMaxAngMotorForce() {
+ return getMaxAngMotorForce(objectId);
+ }
+
+ private native float getMaxAngMotorForce(long objectId);
+
+ public void setMaxAngMotorForce(float maxAngMotorForce) {
+ setMaxAngMotorForce(objectId, maxAngMotorForce);
+ }
+
+ private native void setMaxAngMotorForce(long objectId, float value);
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule capsule = ex.getCapsule(this);
+ //TODO: standard values..
+ capsule.write(getDampingDirAng(), "dampingDirAng", 0f);
+ capsule.write(getDampingDirLin(), "dampingDirLin", 0f);
+ capsule.write(getDampingLimAng(), "dampingLimAng", 0f);
+ capsule.write(getDampingLimLin(), "dampingLimLin", 0f);
+ capsule.write(getDampingOrthoAng(), "dampingOrthoAng", 0f);
+ capsule.write(getDampingOrthoLin(), "dampingOrthoLin", 0f);
+ capsule.write(getLowerAngLimit(), "lowerAngLimit", 0f);
+ capsule.write(getLowerLinLimit(), "lowerLinLimit", 0f);
+ capsule.write(getMaxAngMotorForce(), "maxAngMotorForce", 0f);
+ capsule.write(getMaxLinMotorForce(), "maxLinMotorForce", 0f);
+ capsule.write(isPoweredAngMotor(), "poweredAngMotor", false);
+ capsule.write(isPoweredLinMotor(), "poweredLinMotor", false);
+ capsule.write(getRestitutionDirAng(), "restitutionDirAng", 0f);
+ capsule.write(getRestitutionDirLin(), "restitutionDirLin", 0f);
+ capsule.write(getRestitutionLimAng(), "restitutionLimAng", 0f);
+ capsule.write(getRestitutionLimLin(), "restitutionLimLin", 0f);
+ capsule.write(getRestitutionOrthoAng(), "restitutionOrthoAng", 0f);
+ capsule.write(getRestitutionOrthoLin(), "restitutionOrthoLin", 0f);
+
+ capsule.write(getSoftnessDirAng(), "softnessDirAng", 0f);
+ capsule.write(getSoftnessDirLin(), "softnessDirLin", 0f);
+ capsule.write(getSoftnessLimAng(), "softnessLimAng", 0f);
+ capsule.write(getSoftnessLimLin(), "softnessLimLin", 0f);
+ capsule.write(getSoftnessOrthoAng(), "softnessOrthoAng", 0f);
+ capsule.write(getSoftnessOrthoLin(), "softnessOrthoLin", 0f);
+
+ capsule.write(getTargetAngMotorVelocity(), "targetAngMotorVelicoty", 0f);
+ capsule.write(getTargetLinMotorVelocity(), "targetLinMotorVelicoty", 0f);
+
+ capsule.write(getUpperAngLimit(), "upperAngLimit", 0f);
+ capsule.write(getUpperLinLimit(), "upperLinLimit", 0f);
+
+ capsule.write(useLinearReferenceFrameA, "useLinearReferenceFrameA", false);
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule capsule = im.getCapsule(this);
+ float dampingDirAng = capsule.readFloat("dampingDirAng", 0f);
+ float dampingDirLin = capsule.readFloat("dampingDirLin", 0f);
+ float dampingLimAng = capsule.readFloat("dampingLimAng", 0f);
+ float dampingLimLin = capsule.readFloat("dampingLimLin", 0f);
+ float dampingOrthoAng = capsule.readFloat("dampingOrthoAng", 0f);
+ float dampingOrthoLin = capsule.readFloat("dampingOrthoLin", 0f);
+ float lowerAngLimit = capsule.readFloat("lowerAngLimit", 0f);
+ float lowerLinLimit = capsule.readFloat("lowerLinLimit", 0f);
+ float maxAngMotorForce = capsule.readFloat("maxAngMotorForce", 0f);
+ float maxLinMotorForce = capsule.readFloat("maxLinMotorForce", 0f);
+ boolean poweredAngMotor = capsule.readBoolean("poweredAngMotor", false);
+ boolean poweredLinMotor = capsule.readBoolean("poweredLinMotor", false);
+ float restitutionDirAng = capsule.readFloat("restitutionDirAng", 0f);
+ float restitutionDirLin = capsule.readFloat("restitutionDirLin", 0f);
+ float restitutionLimAng = capsule.readFloat("restitutionLimAng", 0f);
+ float restitutionLimLin = capsule.readFloat("restitutionLimLin", 0f);
+ float restitutionOrthoAng = capsule.readFloat("restitutionOrthoAng", 0f);
+ float restitutionOrthoLin = capsule.readFloat("restitutionOrthoLin", 0f);
+
+ float softnessDirAng = capsule.readFloat("softnessDirAng", 0f);
+ float softnessDirLin = capsule.readFloat("softnessDirLin", 0f);
+ float softnessLimAng = capsule.readFloat("softnessLimAng", 0f);
+ float softnessLimLin = capsule.readFloat("softnessLimLin", 0f);
+ float softnessOrthoAng = capsule.readFloat("softnessOrthoAng", 0f);
+ float softnessOrthoLin = capsule.readFloat("softnessOrthoLin", 0f);
+
+ float targetAngMotorVelicoty = capsule.readFloat("targetAngMotorVelicoty", 0f);
+ float targetLinMotorVelicoty = capsule.readFloat("targetLinMotorVelicoty", 0f);
+
+ float upperAngLimit = capsule.readFloat("upperAngLimit", 0f);
+ float upperLinLimit = capsule.readFloat("upperLinLimit", 0f);
+
+ useLinearReferenceFrameA = capsule.readBoolean("useLinearReferenceFrameA", false);
+
+ createJoint();
+
+ setDampingDirAng(dampingDirAng);
+ setDampingDirLin(dampingDirLin);
+ setDampingLimAng(dampingLimAng);
+ setDampingLimLin(dampingLimLin);
+ setDampingOrthoAng(dampingOrthoAng);
+ setDampingOrthoLin(dampingOrthoLin);
+ setLowerAngLimit(lowerAngLimit);
+ setLowerLinLimit(lowerLinLimit);
+ setMaxAngMotorForce(maxAngMotorForce);
+ setMaxLinMotorForce(maxLinMotorForce);
+ setPoweredAngMotor(poweredAngMotor);
+ setPoweredLinMotor(poweredLinMotor);
+ setRestitutionDirAng(restitutionDirAng);
+ setRestitutionDirLin(restitutionDirLin);
+ setRestitutionLimAng(restitutionLimAng);
+ setRestitutionLimLin(restitutionLimLin);
+ setRestitutionOrthoAng(restitutionOrthoAng);
+ setRestitutionOrthoLin(restitutionOrthoLin);
+
+ setSoftnessDirAng(softnessDirAng);
+ setSoftnessDirLin(softnessDirLin);
+ setSoftnessLimAng(softnessLimAng);
+ setSoftnessLimLin(softnessLimLin);
+ setSoftnessOrthoAng(softnessOrthoAng);
+ setSoftnessOrthoLin(softnessOrthoLin);
+
+ setTargetAngMotorVelocity(targetAngMotorVelicoty);
+ setTargetLinMotorVelocity(targetLinMotorVelicoty);
+
+ setUpperAngLimit(upperAngLimit);
+ setUpperLinLimit(upperLinLimit);
+ }
+
+ protected void createJoint() {
+ objectId = createJoint(nodeA.getObjectId(), nodeB.getObjectId(), pivotA, rotA, pivotB, rotB, useLinearReferenceFrameA);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Joint {0}", Long.toHexString(objectId));
+ // = new SliderConstraint(nodeA.getObjectId(), nodeB.getObjectId(), transA, transB, useLinearReferenceFrameA);
+ }
+
+ private native long createJoint(long objectIdA, long objectIdB, Vector3f pivotA, Matrix3f rotA, Vector3f pivotB, Matrix3f rotB, boolean useLinearReferenceFrameA);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/joints/motors/RotationalLimitMotor.java b/engine/src/bullet/com/jme3/bullet/joints/motors/RotationalLimitMotor.java
new file mode 100644
index 000000000..83b397bf5
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/joints/motors/RotationalLimitMotor.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.joints.motors;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class RotationalLimitMotor {
+
+ private long motorId = 0;
+
+ public RotationalLimitMotor(long motor) {
+ this.motorId = motor;
+ }
+
+ public long getMotor() {
+ return motorId;
+ }
+
+ public float getLoLimit() {
+ return getLoLimit(motorId);
+ }
+
+ private native float getLoLimit(long motorId);
+
+ public void setLoLimit(float loLimit) {
+ setLoLimit(motorId, loLimit);
+ }
+
+ private native void setLoLimit(long motorId, float loLimit);
+
+ public float getHiLimit() {
+ return getHiLimit(motorId);
+ }
+
+ private native float getHiLimit(long motorId);
+
+ public void setHiLimit(float hiLimit) {
+ setHiLimit(motorId, hiLimit);
+ }
+
+ private native void setHiLimit(long motorId, float hiLimit);
+
+ public float getTargetVelocity() {
+ return getTargetVelocity(motorId);
+ }
+
+ private native float getTargetVelocity(long motorId);
+
+ public void setTargetVelocity(float targetVelocity) {
+ setTargetVelocity(motorId, targetVelocity);
+ }
+
+ private native void setTargetVelocity(long motorId, float targetVelocity);
+
+ public float getMaxMotorForce() {
+ return getMaxMotorForce(motorId);
+ }
+
+ private native float getMaxMotorForce(long motorId);
+
+ public void setMaxMotorForce(float maxMotorForce) {
+ setMaxMotorForce(motorId, maxMotorForce);
+ }
+
+ private native void setMaxMotorForce(long motorId, float maxMotorForce);
+
+ public float getMaxLimitForce() {
+ return getMaxLimitForce(motorId);
+ }
+
+ private native float getMaxLimitForce(long motorId);
+
+ public void setMaxLimitForce(float maxLimitForce) {
+ setMaxLimitForce(motorId, maxLimitForce);
+ }
+
+ private native void setMaxLimitForce(long motorId, float maxLimitForce);
+
+ public float getDamping() {
+ return getDamping(motorId);
+ }
+
+ private native float getDamping(long motorId);
+
+ public void setDamping(float damping) {
+ setDamping(motorId, damping);
+ }
+
+ private native void setDamping(long motorId, float damping);
+
+ public float getLimitSoftness() {
+ return getLimitSoftness(motorId);
+ }
+
+ private native float getLimitSoftness(long motorId);
+
+ public void setLimitSoftness(float limitSoftness) {
+ setLimitSoftness(motorId, limitSoftness);
+ }
+
+ private native void setLimitSoftness(long motorId, float limitSoftness);
+
+ public float getERP() {
+ return getERP(motorId);
+ }
+
+ private native float getERP(long motorId);
+
+ public void setERP(float ERP) {
+ setERP(motorId, ERP);
+ }
+
+ private native void setERP(long motorId, float ERP);
+
+ public float getBounce() {
+ return getBounce(motorId);
+ }
+
+ private native float getBounce(long motorId);
+
+ public void setBounce(float bounce) {
+ setBounce(motorId, bounce);
+ }
+
+ private native void setBounce(long motorId, float limitSoftness);
+
+ public boolean isEnableMotor() {
+ return isEnableMotor(motorId);
+ }
+
+ private native boolean isEnableMotor(long motorId);
+
+ public void setEnableMotor(boolean enableMotor) {
+ setEnableMotor(motorId, enableMotor);
+ }
+
+ private native void setEnableMotor(long motorId, boolean enableMotor);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/joints/motors/TranslationalLimitMotor.java b/engine/src/bullet/com/jme3/bullet/joints/motors/TranslationalLimitMotor.java
new file mode 100644
index 000000000..2e3910c02
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/joints/motors/TranslationalLimitMotor.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.joints.motors;
+
+import com.jme3.math.Vector3f;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class TranslationalLimitMotor {
+
+ private long motorId = 0;
+
+ public TranslationalLimitMotor(long motor) {
+ this.motorId = motor;
+ }
+
+ public long getMotor() {
+ return motorId;
+ }
+
+ public Vector3f getLowerLimit() {
+ Vector3f vec = new Vector3f();
+ getLowerLimit(motorId, vec);
+ return vec;
+ }
+
+ private native void getLowerLimit(long motorId, Vector3f vector);
+
+ public void setLowerLimit(Vector3f lowerLimit) {
+ setLowerLimit(motorId, lowerLimit);
+ }
+
+ private native void setLowerLimit(long motorId, Vector3f vector);
+
+ public Vector3f getUpperLimit() {
+ Vector3f vec = new Vector3f();
+ getUpperLimit(motorId, vec);
+ return vec;
+ }
+
+ private native void getUpperLimit(long motorId, Vector3f vector);
+
+ public void setUpperLimit(Vector3f upperLimit) {
+ setUpperLimit(motorId, upperLimit);
+ }
+
+ private native void setUpperLimit(long motorId, Vector3f vector);
+
+ public Vector3f getAccumulatedImpulse() {
+ Vector3f vec = new Vector3f();
+ getAccumulatedImpulse(motorId, vec);
+ return vec;
+ }
+
+ private native void getAccumulatedImpulse(long motorId, Vector3f vector);
+
+ public void setAccumulatedImpulse(Vector3f accumulatedImpulse) {
+ setAccumulatedImpulse(motorId, accumulatedImpulse);
+ }
+
+ private native void setAccumulatedImpulse(long motorId, Vector3f vector);
+
+ public float getLimitSoftness() {
+ return getLimitSoftness(motorId);
+ }
+
+ private native float getLimitSoftness(long motorId);
+
+ public void setLimitSoftness(float limitSoftness) {
+ setLimitSoftness(motorId, limitSoftness);
+ }
+
+ private native void setLimitSoftness(long motorId, float limitSoftness);
+
+ public float getDamping() {
+ return getDamping(motorId);
+ }
+
+ private native float getDamping(long motorId);
+
+ public void setDamping(float damping) {
+ setDamping(motorId, damping);
+ }
+
+ private native void setDamping(long motorId, float damping);
+
+ public float getRestitution() {
+ return getRestitution(motorId);
+ }
+
+ private native float getRestitution(long motorId);
+
+ public void setRestitution(float restitution) {
+ setRestitution(motorId, restitution);
+ }
+
+ private native void setRestitution(long motorId, float restitution);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/objects/PhysicsCharacter.java b/engine/src/bullet/com/jme3/bullet/objects/PhysicsCharacter.java
new file mode 100644
index 000000000..3be267f94
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/objects/PhysicsCharacter.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.objects;
+
+import com.jme3.bullet.collision.PhysicsCollisionObject;
+import com.jme3.math.Vector3f;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.Quaternion;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Basic Bullet Character
+ * @author normenhansen
+ */
+public class PhysicsCharacter extends PhysicsCollisionObject {
+
+ protected long characterId = 0;
+ protected float stepHeight;
+ protected Vector3f walkDirection = new Vector3f();
+ protected float fallSpeed = 55.0f;
+ protected float jumpSpeed = 10.0f;
+ protected int upAxis = 1;
+ protected boolean locationDirty = false;
+ //TEMP VARIABLES
+ protected final Quaternion tmp_inverseWorldRotation = new Quaternion();
+
+ public PhysicsCharacter() {
+ }
+
+ /**
+ * @param shape The CollisionShape (no Mesh or CompoundCollisionShapes)
+ * @param stepHeight The quantization size for vertical movement
+ */
+ public PhysicsCharacter(CollisionShape shape, float stepHeight) {
+ this.collisionShape = shape;
+// if (shape instanceof MeshCollisionShape ||Â shape instanceof CompoundCollisionShape) {
+// throw (new UnsupportedOperationException("Kinematic character nodes cannot have mesh or compound collision shapes"));
+// }
+ this.stepHeight = stepHeight;
+ buildObject();
+ }
+
+ protected void buildObject() {
+ if (objectId == 0) {
+ objectId = createGhostObject();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Creating GhostObject {0}", Long.toHexString(objectId));
+ }
+ setCharacterFlags(objectId);
+ attachCollisionShape(objectId, collisionShape.getObjectId());
+ if (characterId != 0) {
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Clearing Character {0}", Long.toHexString(objectId));
+ finalizeNativeCharacter(characterId);
+ }
+ characterId = createCharacterObject(objectId, collisionShape.getObjectId(), stepHeight);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Creating Character {0}", Long.toHexString(characterId));
+ }
+
+ private native long createGhostObject();
+
+ private native void setCharacterFlags(long objectId);
+
+ private native long createCharacterObject(long objectId, long shapeId, float stepHeight);
+
+ /**
+ * Sets the location of this physics character
+ * @param location
+ */
+ public void warp(Vector3f location) {
+ warp(characterId, location);
+ }
+
+ private native void warp(long characterId, Vector3f location);
+
+ /**
+ * Set the walk direction, works continuously.
+ * This should probably be called setPositionIncrementPerSimulatorStep.
+ * This is neither a direction nor a velocity, but the amount to
+ * increment the position each physics tick. So vector length = accuracy*speed in m/s
+ * @param vec the walk direction to set
+ */
+ public void setWalkDirection(Vector3f vec) {
+ walkDirection.set(vec);
+ setWalkDirection(characterId, vec);
+ }
+
+ private native void setWalkDirection(long characterId, Vector3f vec);
+
+ /**
+ * @return the currently set walkDirection
+ */
+ public Vector3f getWalkDirection() {
+ return walkDirection;
+ }
+
+ public void setUpAxis(int axis) {
+ upAxis = axis;
+ setUpAxis(characterId, axis);
+ }
+
+ private native void setUpAxis(long characterId, int axis);
+
+ public int getUpAxis() {
+ return upAxis;
+ }
+
+ public void setFallSpeed(float fallSpeed) {
+ this.fallSpeed = fallSpeed;
+ setFallSpeed(characterId, fallSpeed);
+ }
+
+ private native void setFallSpeed(long characterId, float fallSpeed);
+
+ public float getFallSpeed() {
+ return fallSpeed;
+ }
+
+ public void setJumpSpeed(float jumpSpeed) {
+ this.jumpSpeed = fallSpeed;
+ setJumpSpeed(characterId, jumpSpeed);
+ }
+
+ private native void setJumpSpeed(long characterId, float jumpSpeed);
+
+ public float getJumpSpeed() {
+ return jumpSpeed;
+ }
+
+ public void setGravity(float value) {
+ setGravity(characterId, value);
+ }
+
+ private native void setGravity(long characterId, float gravity);
+
+ public float getGravity() {
+ return getGravity(characterId);
+ }
+
+ private native float getGravity(long characterId);
+
+ public void setMaxSlope(float slopeRadians) {
+ setMaxSlope(characterId, slopeRadians);
+ }
+
+ private native void setMaxSlope(long characterId, float slopeRadians);
+
+ public float getMaxSlope() {
+ return getMaxSlope(characterId);
+ }
+
+ private native float getMaxSlope(long characterId);
+
+ public boolean onGround() {
+ return onGround(characterId);
+ }
+
+ private native boolean onGround(long characterId);
+
+ public void jump() {
+ jump(characterId);
+ }
+
+ private native void jump(long characterId);
+
+ @Override
+ public void setCollisionShape(CollisionShape collisionShape) {
+// if (!(collisionShape.getObjectId() instanceof ConvexShape)) {
+// throw (new UnsupportedOperationException("Kinematic character nodes cannot have mesh collision shapes"));
+// }
+ super.setCollisionShape(collisionShape);
+ if (objectId == 0) {
+ buildObject();
+ } else {
+ attachCollisionShape(objectId, collisionShape.getObjectId());
+ }
+ }
+
+ /**
+ * Set the physics location (same as warp())
+ * @param location the location of the actual physics object
+ */
+ public void setPhysicsLocation(Vector3f location) {
+ warp(location);
+ }
+
+ /**
+ * @return the physicsLocation
+ */
+ public Vector3f getPhysicsLocation(Vector3f trans) {
+ if (trans == null) {
+ trans = new Vector3f();
+ }
+ getPhysicsLocation(objectId, trans);
+ return trans;
+ }
+
+ private native void getPhysicsLocation(long objectId, Vector3f vec);
+
+ /**
+ * @return the physicsLocation
+ */
+ public Vector3f getPhysicsLocation() {
+ return getPhysicsLocation(null);
+ }
+
+ public void setCcdSweptSphereRadius(float radius) {
+ setCcdSweptSphereRadius(objectId, radius);
+ }
+
+ private native void setCcdSweptSphereRadius(long objectId, float radius);
+
+ public void setCcdMotionThreshold(float threshold) {
+ setCcdMotionThreshold(objectId, threshold);
+ }
+
+ private native void setCcdMotionThreshold(long objectId, float threshold);
+
+ public float getCcdSweptSphereRadius() {
+ return getCcdSweptSphereRadius(objectId);
+ }
+
+ private native float getCcdSweptSphereRadius(long objectId);
+
+ public float getCcdMotionThreshold() {
+ return getCcdMotionThreshold(objectId);
+ }
+
+ private native float getCcdMotionThreshold(long objectId);
+
+ public float getCcdSquareMotionThreshold() {
+ return getCcdSquareMotionThreshold(objectId);
+ }
+
+ private native float getCcdSquareMotionThreshold(long objectId);
+
+ /**
+ * used internally
+ */
+ public long getControllerId() {
+ return characterId;
+ }
+
+ public void destroy() {
+ }
+
+ @Override
+ public void write(JmeExporter e) throws IOException {
+ super.write(e);
+ OutputCapsule capsule = e.getCapsule(this);
+ capsule.write(stepHeight, "stepHeight", 1.0f);
+ capsule.write(getGravity(), "gravity", 9.8f * 3);
+ capsule.write(getMaxSlope(), "maxSlope", 1.0f);
+ capsule.write(fallSpeed, "fallSpeed", 55.0f);
+ capsule.write(jumpSpeed, "jumpSpeed", 10.0f);
+ capsule.write(upAxis, "upAxis", 1);
+ capsule.write(getCcdMotionThreshold(), "ccdMotionThreshold", 0);
+ capsule.write(getCcdSweptSphereRadius(), "ccdSweptSphereRadius", 0);
+ capsule.write(getPhysicsLocation(new Vector3f()), "physicsLocation", new Vector3f());
+ }
+
+ @Override
+ public void read(JmeImporter e) throws IOException {
+ super.read(e);
+ InputCapsule capsule = e.getCapsule(this);
+ stepHeight = capsule.readFloat("stepHeight", 1.0f);
+ buildObject();
+ setGravity(capsule.readFloat("gravity", 9.8f * 3));
+ setMaxSlope(capsule.readFloat("maxSlope", 1.0f));
+ setFallSpeed(capsule.readFloat("fallSpeed", 55.0f));
+ setJumpSpeed(capsule.readFloat("jumpSpeed", 10.0f));
+ setUpAxis(capsule.readInt("upAxis", 1));
+ setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0));
+ setCcdSweptSphereRadius(capsule.readFloat("ccdSweptSphereRadius", 0));
+ setPhysicsLocation((Vector3f) capsule.readSavable("physicsLocation", new Vector3f()));
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ finalizeNativeCharacter(characterId);
+ }
+
+ private native void finalizeNativeCharacter(long characterId);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/objects/PhysicsGhostObject.java b/engine/src/bullet/com/jme3/bullet/objects/PhysicsGhostObject.java
new file mode 100644
index 000000000..a037b00bd
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/objects/PhysicsGhostObject.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.objects;
+
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Quaternion;
+import com.jme3.scene.Spatial;
+import com.jme3.bullet.collision.PhysicsCollisionObject;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.Vector3f;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * From Bullet manual:
+ * GhostObject can keep track of all objects that are overlapping.
+ * By default, this overlap is based on the AABB.
+ * This is useful for creating a character controller,
+ * collision sensors/triggers, explosions etc.
+ * @author normenhansen
+ */
+public class PhysicsGhostObject extends PhysicsCollisionObject {
+
+ protected boolean locationDirty = false;
+ protected final Quaternion tmp_inverseWorldRotation = new Quaternion();
+ private List overlappingObjects = new LinkedList();
+
+ public PhysicsGhostObject() {
+ }
+
+ public PhysicsGhostObject(CollisionShape shape) {
+ collisionShape = shape;
+ buildObject();
+ }
+
+ public PhysicsGhostObject(Spatial child, CollisionShape shape) {
+ collisionShape = shape;
+ buildObject();
+ }
+
+ protected void buildObject() {
+ if (objectId == 0) {
+// gObject = new PairCachingGhostObject();
+ objectId = createGhostObject();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Ghost Object {0}", Long.toHexString(objectId));
+ setGhostFlags(objectId);
+ }
+// if (gObject == null) {
+// gObject = new PairCachingGhostObject();
+// gObject.setCollisionFlags(gObject.getCollisionFlags() | CollisionFlags.NO_CONTACT_RESPONSE);
+// }
+ attachCollisionShape(objectId, collisionShape.getObjectId());
+ }
+
+ private native long createGhostObject();
+
+ private native void setGhostFlags(long objectId);
+
+ @Override
+ public void setCollisionShape(CollisionShape collisionShape) {
+ super.setCollisionShape(collisionShape);
+ if (objectId == 0) {
+ buildObject();
+ }else{
+ attachCollisionShape(objectId, collisionShape.getObjectId());
+ }
+ }
+
+ /**
+ * Sets the physics object location
+ * @param location the location of the actual physics object
+ */
+ public void setPhysicsLocation(Vector3f location) {
+ setPhysicsLocation(objectId, location);
+ }
+
+ private native void setPhysicsLocation(long objectId, Vector3f location);
+
+ /**
+ * Sets the physics object rotation
+ * @param rotation the rotation of the actual physics object
+ */
+ public void setPhysicsRotation(Matrix3f rotation) {
+ setPhysicsRotation(objectId, rotation);
+ }
+
+ private native void setPhysicsRotation(long objectId, Matrix3f rotation);
+
+ /**
+ * Sets the physics object rotation
+ * @param rotation the rotation of the actual physics object
+ */
+ public void setPhysicsRotation(Quaternion rotation) {
+ setPhysicsRotation(objectId, rotation);
+ }
+
+ private native void setPhysicsRotation(long objectId, Quaternion rotation);
+
+ /**
+ * @return the physicsLocation
+ */
+ public Vector3f getPhysicsLocation(Vector3f trans) {
+ if (trans == null) {
+ trans = new Vector3f();
+ }
+ getPhysicsLocation(objectId, trans);
+ return trans;
+ }
+
+ private native void getPhysicsLocation(long objectId, Vector3f vector);
+
+ /**
+ * @return the physicsLocation
+ */
+ public Quaternion getPhysicsRotation(Quaternion rot) {
+ if (rot == null) {
+ rot = new Quaternion();
+ }
+ getPhysicsRotation(objectId, rot);
+ return rot;
+ }
+
+ private native void getPhysicsRotation(long objectId, Quaternion rot);
+
+ /**
+ * @return the physicsLocation
+ */
+ public Matrix3f getPhysicsRotationMatrix(Matrix3f rot) {
+ if (rot == null) {
+ rot = new Matrix3f();
+ }
+ getPhysicsRotationMatrix(objectId, rot);
+ return rot;
+ }
+
+ private native void getPhysicsRotationMatrix(long objectId, Matrix3f rot);
+
+ /**
+ * @return the physicsLocation
+ */
+ public Vector3f getPhysicsLocation() {
+ Vector3f vec = new Vector3f();
+ getPhysicsLocation(objectId, vec);
+ return vec;
+ }
+
+ /**
+ * @return the physicsLocation
+ */
+ public Quaternion getPhysicsRotation() {
+ Quaternion quat = new Quaternion();
+ getPhysicsRotation(objectId, quat);
+ return quat;
+ }
+
+ public Matrix3f getPhysicsRotationMatrix() {
+ Matrix3f mtx = new Matrix3f();
+ getPhysicsRotationMatrix(objectId, mtx);
+ return mtx;
+ }
+
+ /**
+ * used internally
+ */
+// public PairCachingGhostObject getObjectId() {
+// return gObject;
+// }
+
+ /**
+ * destroys this PhysicsGhostNode and removes it from memory
+ */
+ public void destroy() {
+ }
+
+ /**
+ * Another Object is overlapping with this GhostNode,
+ * if and if only there CollisionShapes overlaps.
+ * They could be both regular PhysicsRigidBodys or PhysicsGhostObjects.
+ * @return All CollisionObjects overlapping with this GhostNode.
+ */
+ public List getOverlappingObjects() {
+// overlappingObjects.clear();
+// for (com.bulletphysics.collision.dispatch.CollisionObject collObj : gObject.getOverlappingPairs()) {
+// overlappingObjects.add((PhysicsCollisionObject) collObj.getUserPointer());
+// }
+ return overlappingObjects;
+ }
+
+ /**
+ *
+ * @return With how many other CollisionObjects this GhostNode is currently overlapping.
+ */
+ public int getOverlappingCount() {
+ return getOverlappingCount(objectId);
+ }
+
+ private native int getOverlappingCount(long objectId);
+
+ /**
+ *
+ * @param index The index of the overlapping Node to retrieve.
+ * @return The Overlapping CollisionObject at the given index.
+ */
+ public PhysicsCollisionObject getOverlapping(int index) {
+ return overlappingObjects.get(index);
+ }
+
+ public void setCcdSweptSphereRadius(float radius) {
+ setCcdSweptSphereRadius(objectId, radius);
+ }
+
+ private native void setCcdSweptSphereRadius(long objectId, float radius);
+
+ public void setCcdMotionThreshold(float threshold) {
+ setCcdMotionThreshold(objectId, threshold);
+ }
+
+ private native void setCcdMotionThreshold(long objectId, float threshold);
+
+ public float getCcdSweptSphereRadius() {
+ return getCcdSweptSphereRadius(objectId);
+ }
+
+ private native float getCcdSweptSphereRadius(long objectId);
+
+ public float getCcdMotionThreshold() {
+ return getCcdMotionThreshold(objectId);
+ }
+
+ private native float getCcdMotionThreshold(long objectId);
+
+ public float getCcdSquareMotionThreshold() {
+ return getCcdSquareMotionThreshold(objectId);
+ }
+
+ private native float getCcdSquareMotionThreshold(long objectId);
+
+ @Override
+ public void write(JmeExporter e) throws IOException {
+ super.write(e);
+ OutputCapsule capsule = e.getCapsule(this);
+ capsule.write(getPhysicsLocation(new Vector3f()), "physicsLocation", new Vector3f());
+ capsule.write(getPhysicsRotationMatrix(new Matrix3f()), "physicsRotation", new Matrix3f());
+ capsule.write(getCcdMotionThreshold(), "ccdMotionThreshold", 0);
+ capsule.write(getCcdSweptSphereRadius(), "ccdSweptSphereRadius", 0);
+ }
+
+ @Override
+ public void read(JmeImporter e) throws IOException {
+ super.read(e);
+ InputCapsule capsule = e.getCapsule(this);
+ buildObject();
+ setPhysicsLocation((Vector3f) capsule.readSavable("physicsLocation", new Vector3f()));
+ setPhysicsRotation(((Matrix3f) capsule.readSavable("physicsRotation", new Matrix3f())));
+ setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0));
+ setCcdSweptSphereRadius(capsule.readFloat("ccdSweptSphereRadius", 0));
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/objects/PhysicsRigidBody.java b/engine/src/bullet/com/jme3/bullet/objects/PhysicsRigidBody.java
new file mode 100644
index 000000000..f9974f393
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/objects/PhysicsRigidBody.java
@@ -0,0 +1,749 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.objects;
+
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Spatial;
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.collision.PhysicsCollisionObject;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.collision.shapes.MeshCollisionShape;
+import com.jme3.bullet.joints.PhysicsJoint;
+import com.jme3.bullet.objects.infos.RigidBodyMotionState;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Quaternion;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.debug.Arrow;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * PhysicsRigidBody - Basic physics object
+ * @author normenhansen
+ */
+public class PhysicsRigidBody extends PhysicsCollisionObject {
+
+ protected RigidBodyMotionState motionState = new RigidBodyMotionState();
+ protected float mass = 1.0f;
+ protected boolean kinematic = false;
+ protected ArrayList joints = new ArrayList();
+
+ public PhysicsRigidBody() {
+ }
+
+ /**
+ * Creates a new PhysicsRigidBody with the supplied collision shape
+ * @param child
+ * @param shape
+ */
+ public PhysicsRigidBody(CollisionShape shape) {
+ collisionShape = shape;
+ rebuildRigidBody();
+ }
+
+ public PhysicsRigidBody(CollisionShape shape, float mass) {
+ collisionShape = shape;
+ this.mass = mass;
+ rebuildRigidBody();
+ }
+
+ /**
+ * Builds/rebuilds the phyiscs body when parameters have changed
+ */
+ protected void rebuildRigidBody() {
+ boolean removed = false;
+ if (collisionShape instanceof MeshCollisionShape && mass != 0) {
+ throw new IllegalStateException("Dynamic rigidbody can not have mesh collision shape!");
+ }
+ if (objectId != 0) {
+ if (isInWorld(objectId)) {
+ PhysicsSpace.getPhysicsSpace().remove(this);
+ removed = true;
+ }
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Clearing RigidBody {0}", Long.toHexString(objectId));
+ finalizeNative(objectId);
+ }
+ preRebuild();
+ objectId = createRigidBody(mass, motionState.getObjectId(), collisionShape.getObjectId());
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created RigidBody {0}", Long.toHexString(objectId));
+ postRebuild();
+ if (removed) {
+ PhysicsSpace.getPhysicsSpace().add(this);
+ }
+ }
+
+ protected void preRebuild() {
+ }
+
+ private native long createRigidBody(float mass, long motionStateId, long collisionShapeId);
+
+ protected void postRebuild() {
+ if (mass == 0.0f) {
+ setStatic(objectId, true);
+ } else {
+ setStatic(objectId, false);
+ }
+ }
+
+ /**
+ * @return the motionState
+ */
+ public RigidBodyMotionState getMotionState() {
+ return motionState;
+ }
+
+ public boolean isInWorld() {
+ return isInWorld(objectId);
+ }
+
+ private native boolean isInWorld(long objectId);
+
+ /**
+ * Sets the physics object location
+ * @param location the location of the actual physics object
+ */
+ public void setPhysicsLocation(Vector3f location) {
+ setPhysicsLocation(objectId, location);
+ }
+
+ private native void setPhysicsLocation(long objectId, Vector3f location);
+
+ /**
+ * Sets the physics object rotation
+ * @param rotation the rotation of the actual physics object
+ */
+ public void setPhysicsRotation(Matrix3f rotation) {
+ setPhysicsRotation(objectId, rotation);
+ }
+
+ private native void setPhysicsRotation(long objectId, Matrix3f rotation);
+
+ /**
+ * Sets the physics object rotation
+ * @param rotation the rotation of the actual physics object
+ */
+ public void setPhysicsRotation(Quaternion rotation) {
+ setPhysicsRotation(objectId, rotation);
+ }
+
+ private native void setPhysicsRotation(long objectId, Quaternion rotation);
+
+ /**
+ * @return the physicsLocation
+ */
+ public Vector3f getPhysicsLocation(Vector3f trans) {
+ if (trans == null) {
+ trans = new Vector3f();
+ }
+ getPhysicsLocation(objectId, trans);
+ return trans;
+ }
+
+ private native void getPhysicsLocation(long objectId, Vector3f vector);
+
+ /**
+ * @return the physicsLocation
+ */
+ public Quaternion getPhysicsRotation(Quaternion rot) {
+ if (rot == null) {
+ rot = new Quaternion();
+ }
+ getPhysicsRotation(objectId, rot);
+ return rot;
+ }
+
+ private native void getPhysicsRotation(long objectId, Quaternion rot);
+
+ /**
+ * @return the physicsLocation
+ */
+ public Matrix3f getPhysicsRotationMatrix(Matrix3f rot) {
+ if (rot == null) {
+ rot = new Matrix3f();
+ }
+ getPhysicsRotationMatrix(objectId, rot);
+ return rot;
+ }
+
+ private native void getPhysicsRotationMatrix(long objectId, Matrix3f rot);
+
+ /**
+ * @return the physicsLocation
+ */
+ public Vector3f getPhysicsLocation() {
+ Vector3f vec = new Vector3f();
+ getPhysicsLocation(objectId, vec);
+ return vec;
+ }
+
+ /**
+ * @return the physicsLocation
+ */
+ public Quaternion getPhysicsRotation() {
+ Quaternion quat = new Quaternion();
+ getPhysicsRotation(objectId, quat);
+ return quat;
+ }
+
+ public Matrix3f getPhysicsRotationMatrix() {
+ Matrix3f mtx = new Matrix3f();
+ getPhysicsRotationMatrix(objectId, mtx);
+ return mtx;
+ }
+
+// /**
+// * Gets the physics object location
+// * @param location the location of the actual physics object is stored in this Vector3f
+// */
+// public Vector3f getInterpolatedPhysicsLocation(Vector3f location) {
+// if (location == null) {
+// location = new Vector3f();
+// }
+// rBody.getInterpolationWorldTransform(tempTrans);
+// return Converter.convert(tempTrans.origin, location);
+// }
+//
+// /**
+// * Gets the physics object rotation
+// * @param rotation the rotation of the actual physics object is stored in this Matrix3f
+// */
+// public Matrix3f getInterpolatedPhysicsRotation(Matrix3f rotation) {
+// if (rotation == null) {
+// rotation = new Matrix3f();
+// }
+// rBody.getInterpolationWorldTransform(tempTrans);
+// return Converter.convert(tempTrans.basis, rotation);
+// }
+ /**
+ * Sets the node to kinematic mode. in this mode the node is not affected by physics
+ * but affects other physics objects. Iits kinetic force is calculated by the amount
+ * of movement it is exposed to and its weight.
+ * @param kinematic
+ */
+ public void setKinematic(boolean kinematic) {
+ this.kinematic = kinematic;
+ setKinematic(objectId, kinematic);
+ }
+
+ private native void setKinematic(long objectId, boolean kinematic);
+
+ public boolean isKinematic() {
+ return kinematic;
+ }
+
+ public void setCcdSweptSphereRadius(float radius) {
+ setCcdSweptSphereRadius(objectId, radius);
+ }
+
+ private native void setCcdSweptSphereRadius(long objectId, float radius);
+
+ /**
+ * Sets the amount of motion that has to happen in one physics tick to trigger the continuous motion detection
+ * This avoids the problem of fast objects moving through other objects, set to zero to disable (default)
+ * @param threshold
+ */
+ public void setCcdMotionThreshold(float threshold) {
+ setCcdMotionThreshold(objectId, threshold);
+ }
+
+ private native void setCcdMotionThreshold(long objectId, float threshold);
+
+ public float getCcdSweptSphereRadius() {
+ return getCcdSweptSphereRadius(objectId);
+ }
+
+ private native float getCcdSweptSphereRadius(long objectId);
+
+ public float getCcdMotionThreshold() {
+ return getCcdMotionThreshold(objectId);
+ }
+
+ private native float getCcdMotionThreshold(long objectId);
+
+ public float getCcdSquareMotionThreshold() {
+ return getCcdSquareMotionThreshold(objectId);
+ }
+
+ private native float getCcdSquareMotionThreshold(long objectId);
+
+ public float getMass() {
+ return mass;
+ }
+
+ /**
+ * Sets the mass of this PhysicsRigidBody, objects with mass=0 are static.
+ * @param mass
+ */
+ public void setMass(float mass) {
+ this.mass = mass;
+ if (collisionShape instanceof MeshCollisionShape && mass != 0) {
+ throw new IllegalStateException("Dynamic rigidbody can not have mesh collision shape!");
+ }
+ if (objectId != 0) {
+ if (collisionShape != null) {
+ updateMassProps(objectId, collisionShape.getObjectId(), mass);
+ }
+ if (mass == 0.0f) {
+ setStatic(objectId, true);
+ } else {
+ setStatic(objectId, false);
+ }
+ }
+ }
+
+ private native void setStatic(long objectId, boolean state);
+
+ private native long updateMassProps(long objectId, long collisionShapeId, float mass);
+
+ public Vector3f getGravity() {
+ return getGravity(null);
+ }
+
+ public Vector3f getGravity(Vector3f gravity) {
+ if (gravity == null) {
+ gravity = new Vector3f();
+ }
+ getGravity(gravity);
+ return gravity;
+ }
+
+ private native void getGravity(long objectId, Vector3f gravity);
+
+ /**
+ * Set the local gravity of this PhysicsRigidBody
+ * Set this after adding the node to the PhysicsSpace,
+ * the PhysicsSpace assigns its current gravity to the physics node when its added.
+ * @param gravity the gravity vector to set
+ */
+ public void setGravity(Vector3f gravity) {
+ setGravity(objectId, gravity);
+ }
+
+ private native void setGravity(long objectId, Vector3f gravity);
+
+ public float getFriction() {
+ return getFriction(objectId);
+ }
+
+ private native float getFriction(long objectId);
+
+ /**
+ * Sets the friction of this physics object
+ * @param friction the friction of this physics object
+ */
+ public void setFriction(float friction) {
+ setFriction(objectId, friction);
+ }
+
+ private native void setFriction(long objectId, float friction);
+
+ public void setDamping(float linearDamping, float angularDamping) {
+ setDamping(objectId, linearDamping, angularDamping);
+ }
+
+ private native void setDamping(long objectId, float linearDamping, float angularDamping);
+
+// private native void setRestitution(long objectId, float factor);
+//
+// public void setLinearDamping(float linearDamping) {
+// constructionInfo.linearDamping = linearDamping;
+// rBody.setDamping(linearDamping, constructionInfo.angularDamping);
+// }
+//
+// private native void setRestitution(long objectId, float factor);
+//
+// public void setAngularDamping(float angularDamping) {
+//// constructionInfo.angularDamping = angularDamping;
+//// rBody.setDamping(constructionInfo.linearDamping, angularDamping);
+//
+// }
+ private native void setAngularDamping(long objectId, float factor);
+
+ public float getLinearDamping() {
+ return getLinearDamping(objectId);
+ }
+
+ private native float getLinearDamping(long objectId);
+
+ public float getAngularDamping() {
+ return getAngularDamping(objectId);
+ }
+
+ private native float getAngularDamping(long objectId);
+
+ public float getRestitution() {
+ return getRestitution(objectId);
+ }
+
+ private native float getRestitution(long objectId);
+
+ /**
+ * The "bouncyness" of the PhysicsRigidBody, best performance if restitution=0
+ * @param restitution
+ */
+ public void setRestitution(float restitution) {
+ setRestitution(objectId, mass);
+ }
+
+ private native void setRestitution(long objectId, float factor);
+
+ /**
+ * Get the current angular velocity of this PhysicsRigidBody
+ * @return the current linear velocity
+ */
+ public Vector3f getAngularVelocity() {
+ Vector3f vec = new Vector3f();
+ getAngularVelocity(objectId, vec);
+ return vec;
+ }
+
+ private native void getAngularVelocity(long objectId, Vector3f vec);
+
+ /**
+ * Get the current angular velocity of this PhysicsRigidBody
+ * @param vec the vector to store the velocity in
+ */
+ public void getAngularVelocity(Vector3f vec) {
+ getAngularVelocity(objectId, vec);
+ }
+
+ /**
+ * Sets the angular velocity of this PhysicsRigidBody
+ * @param vec the angular velocity of this PhysicsRigidBody
+ */
+ public void setAngularVelocity(Vector3f vec) {
+ setAngularVelocity(objectId, vec);
+ activate();
+ }
+
+ private native void setAngularVelocity(long objectId, Vector3f vec);
+
+ /**
+ * Get the current linear velocity of this PhysicsRigidBody
+ * @return the current linear velocity
+ */
+ public Vector3f getLinearVelocity() {
+ Vector3f vec = new Vector3f();
+ getLinearVelocity(objectId, vec);
+ return vec;
+ }
+
+ private native void getLinearVelocity(long objectId, Vector3f vec);
+
+ /**
+ * Get the current linear velocity of this PhysicsRigidBody
+ * @param vec the vector to store the velocity in
+ */
+ public void getLinearVelocity(Vector3f vec) {
+ getLinearVelocity(objectId, vec);
+ }
+
+ /**
+ * Sets the linear velocity of this PhysicsRigidBody
+ * @param vec the linear velocity of this PhysicsRigidBody
+ */
+ public void setLinearVelocity(Vector3f vec) {
+ setLinearVelocity(objectId, vec);
+ activate();
+ }
+
+ private native void setLinearVelocity(long objectId, Vector3f vec);
+
+ /**
+ * Apply a force to the PhysicsRigidBody, only applies force if the next physics update call
+ * updates the physics space.
+ * To apply an impulse, use applyImpulse, use applyContinuousForce to apply continuous force.
+ * @param force the force
+ * @param location the location of the force
+ */
+ public void applyForce(Vector3f force, Vector3f location) {
+ applyForce(objectId, force, location);
+ activate();
+ }
+
+ private native void applyForce(long objectId, Vector3f force, Vector3f location);
+
+ /**
+ * Apply a force to the PhysicsRigidBody, only applies force if the next physics update call
+ * updates the physics space.
+ * To apply an impulse, use applyImpulse.
+ *
+ * @param force the force
+ */
+ public void applyCentralForce(Vector3f force) {
+ applyCentralForce(objectId, force);
+ activate();
+ }
+
+ private native void applyCentralForce(long objectId, Vector3f force);
+
+ /**
+ * Apply a force to the PhysicsRigidBody, only applies force if the next physics update call
+ * updates the physics space.
+ * To apply an impulse, use applyImpulse.
+ *
+ * @param torque the torque
+ */
+ public void applyTorque(Vector3f torque) {
+ applyTorque(objectId, torque);
+ activate();
+ }
+
+ private native void applyTorque(long objectId, Vector3f vec);
+
+ /**
+ * Apply an impulse to the PhysicsRigidBody in the next physics update.
+ * @param impulse applied impulse
+ * @param rel_pos location relative to object
+ */
+ public void applyImpulse(Vector3f impulse, Vector3f rel_pos) {
+ applyImpulse(objectId, impulse, rel_pos);
+ activate();
+ }
+
+ private native void applyImpulse(long objectId, Vector3f impulse, Vector3f rel_pos);
+
+ /**
+ * Apply a torque impulse to the PhysicsRigidBody in the next physics update.
+ * @param vec
+ */
+ public void applyTorqueImpulse(Vector3f vec) {
+ applyTorqueImpulse(objectId, vec);
+ activate();
+ }
+
+ private native void applyTorqueImpulse(long objectId, Vector3f vec);
+
+ /**
+ * Clear all forces from the PhysicsRigidBody
+ *
+ */
+ public void clearForces() {
+ clearForces(objectId);
+ }
+
+ private native void clearForces(long objectId);
+
+ public void setCollisionShape(CollisionShape collisionShape) {
+ super.setCollisionShape(collisionShape);
+ if (collisionShape instanceof MeshCollisionShape && mass != 0) {
+ throw new IllegalStateException("Dynamic rigidbody can not have mesh collision shape!");
+ }
+ if (objectId == 0) {
+ rebuildRigidBody();
+ } else {
+ setCollisionShape(objectId, collisionShape.getObjectId());
+ updateMassProps(objectId, collisionShape.getObjectId(), mass);
+ }
+ }
+
+ private native void setCollisionShape(long objectId, long collisionShapeId);
+
+ /**
+ * reactivates this PhysicsRigidBody when it has been deactivated because it was not moving
+ */
+ public void activate() {
+ activate(objectId);
+ }
+
+ private native void activate(long objectId);
+
+ public boolean isActive() {
+ return isActive(objectId);
+ }
+
+ private native boolean isActive(long objectId);
+
+ /**
+ * sets the sleeping thresholds, these define when the object gets deactivated
+ * to save ressources. Low values keep the object active when it barely moves
+ * @param linear the linear sleeping threshold
+ * @param angular the angular sleeping threshold
+ */
+ public void setSleepingThresholds(float linear, float angular) {
+ setSleepingThresholds(objectId, linear, angular);
+ }
+
+ private native void setSleepingThresholds(long objectId, float linear, float angular);
+
+ public void setLinearSleepingThreshold(float linearSleepingThreshold) {
+ setLinearSleepingThreshold(objectId, linearSleepingThreshold);
+ }
+
+ private native void setLinearSleepingThreshold(long objectId, float linearSleepingThreshold);
+
+ public void setAngularSleepingThreshold(float angularSleepingThreshold) {
+ setAngularSleepingThreshold(objectId, angularSleepingThreshold);
+ }
+
+ private native void setAngularSleepingThreshold(long objectId, float angularSleepingThreshold);
+
+ public float getLinearSleepingThreshold() {
+ return getLinearSleepingThreshold(objectId);
+ }
+
+ private native float getLinearSleepingThreshold(long objectId);
+
+ public float getAngularSleepingThreshold() {
+ return getAngularSleepingThreshold(objectId);
+ }
+
+ private native float getAngularSleepingThreshold(long objectId);
+
+ public float getAngularFactor() {
+ return getAngularFactor(objectId);
+ }
+
+ private native float getAngularFactor(long objectId);
+
+ public void setAngularFactor(float factor) {
+ setAngularFactor(objectId, factor);
+ }
+
+ private native void setAngularFactor(long objectId, float factor);
+
+ /**
+ * do not use manually, joints are added automatically
+ */
+ public void addJoint(PhysicsJoint joint) {
+ if (!joints.contains(joint)) {
+ joints.add(joint);
+ }
+ updateDebugShape();
+ }
+
+ /**
+ *
+ */
+ public void removeJoint(PhysicsJoint joint) {
+ joints.remove(joint);
+ }
+
+ /**
+ * Returns a list of connected joints. This list is only filled when
+ * the PhysicsRigidBody is actually added to the physics space or loaded from disk.
+ * @return list of active joints connected to this PhysicsRigidBody
+ */
+ public List getJoints() {
+ return joints;
+ }
+
+ @Override
+ protected Spatial getDebugShape() {
+ //add joints
+ Spatial shape = super.getDebugShape();
+ Node node = null;
+ if (shape instanceof Node) {
+ node = (Node) shape;
+ } else {
+ node = new Node("DebugShapeNode");
+ node.attachChild(shape);
+ }
+ int i = 0;
+ for (Iterator it = joints.iterator(); it.hasNext();) {
+ PhysicsJoint physicsJoint = it.next();
+ Vector3f pivot = null;
+ if (physicsJoint.getBodyA() == this) {
+ pivot = physicsJoint.getPivotA();
+ } else {
+ pivot = physicsJoint.getPivotB();
+ }
+ Arrow arrow = new Arrow(pivot);
+ Geometry geom = new Geometry("DebugBone" + i, arrow);
+ geom.setMaterial(debugMaterialGreen);
+ node.attachChild(geom);
+ i++;
+ }
+ return node;
+ }
+
+ @Override
+ public void write(JmeExporter e) throws IOException {
+ super.write(e);
+ OutputCapsule capsule = e.getCapsule(this);
+
+ capsule.write(getMass(), "mass", 1.0f);
+
+ capsule.write(getGravity(), "gravity", Vector3f.ZERO);
+ capsule.write(getFriction(), "friction", 0.5f);
+ capsule.write(getRestitution(), "restitution", 0);
+ capsule.write(getAngularFactor(), "angularFactor", 1);
+ capsule.write(kinematic, "kinematic", false);
+
+ capsule.write(getLinearDamping(), "linearDamping", 0);
+ capsule.write(getAngularDamping(), "angularDamping", 0);
+ capsule.write(getLinearSleepingThreshold(), "linearSleepingThreshold", 0.8f);
+ capsule.write(getAngularSleepingThreshold(), "angularSleepingThreshold", 1.0f);
+
+ capsule.write(getCcdMotionThreshold(), "ccdMotionThreshold", 0);
+ capsule.write(getCcdSweptSphereRadius(), "ccdSweptSphereRadius", 0);
+
+ capsule.write(getPhysicsLocation(new Vector3f()), "physicsLocation", new Vector3f());
+ capsule.write(getPhysicsRotationMatrix(new Matrix3f()), "physicsRotation", new Matrix3f());
+
+ capsule.writeSavableArrayList(joints, "joints", null);
+ }
+
+ @Override
+ public void read(JmeImporter e) throws IOException {
+ super.read(e);
+
+ InputCapsule capsule = e.getCapsule(this);
+ float mass = capsule.readFloat("mass", 1.0f);
+ this.mass = mass;
+ rebuildRigidBody();
+ setGravity((Vector3f) capsule.readSavable("gravity", Vector3f.ZERO.clone()));
+ setFriction(capsule.readFloat("friction", 0.5f));
+ setKinematic(capsule.readBoolean("kinematic", false));
+
+ setRestitution(capsule.readFloat("restitution", 0));
+ setAngularFactor(capsule.readFloat("angularFactor", 1));
+ setDamping(capsule.readFloat("linearDamping", 0), capsule.readFloat("angularDamping", 0));
+ setSleepingThresholds(capsule.readFloat("linearSleepingThreshold", 0.8f), capsule.readFloat("angularSleepingThreshold", 1.0f));
+ setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0));
+ setCcdSweptSphereRadius(capsule.readFloat("ccdSweptSphereRadius", 0));
+
+ setPhysicsLocation((Vector3f) capsule.readSavable("physicsLocation", new Vector3f()));
+ setPhysicsRotation((Matrix3f) capsule.readSavable("physicsRotation", new Matrix3f()));
+
+ joints = capsule.readSavableArrayList("joints", null);
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/objects/PhysicsVehicle.java b/engine/src/bullet/com/jme3/bullet/objects/PhysicsVehicle.java
new file mode 100644
index 000000000..6896769c7
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/objects/PhysicsVehicle.java
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.objects;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Spatial;
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.objects.infos.VehicleTuning;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.OutputCapsule;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.debug.Arrow;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * PhysicsVehicleNode - Special PhysicsNode that implements vehicle functions
+ *
+ * From bullet manual:
+ * For most vehicle simulations, it is recommended to use the simplified Bullet
+ * vehicle model as provided in btRaycastVehicle. Instead of simulation each wheel
+ * and chassis as separate rigid bodies, connected by constraints, it uses a simplified model.
+ * This simplified model has many benefits, and is widely used in commercial driving games.
+ * The entire vehicle is represented as a single rigidbody, the chassis.
+ * The collision detection of the wheels is approximated by ray casts,
+ * and the tire friction is a basic anisotropic friction model.
+ *
+ * @author normenhansen
+ */
+public class PhysicsVehicle extends PhysicsRigidBody {
+
+ protected long vehicleId = 0;
+ protected long rayCasterId = 0;
+ protected VehicleTuning tuning;
+ protected ArrayList wheels = new ArrayList();
+ protected PhysicsSpace physicsSpace;
+
+ public PhysicsVehicle() {
+ }
+
+ public PhysicsVehicle(CollisionShape shape) {
+ super(shape);
+ }
+
+ public PhysicsVehicle(CollisionShape shape, float mass) {
+ super(shape, mass);
+ }
+
+ /**
+ * used internally
+ */
+ public void updateWheels() {
+ if (vehicleId != 0) {
+ for (int i = 0; i < wheels.size(); i++) {
+ updateWheelTransform(vehicleId, i, true);
+ wheels.get(i).updatePhysicsState();
+ }
+ }
+ }
+
+ private native void updateWheelTransform(long vehicleId, int wheel, boolean interpolated);
+
+ /**
+ * used internally
+ */
+ public void applyWheelTransforms() {
+ if (wheels != null) {
+ for (int i = 0; i < wheels.size(); i++) {
+ wheels.get(i).applyWheelTransform();
+ }
+ }
+ }
+
+ @Override
+ protected void postRebuild() {
+ super.postRebuild();
+ if (tuning == null) {
+ tuning = new VehicleTuning();
+ }
+ motionState.setVehicle(this);
+// if (physicsSpace != null) {
+// createVehicle(physicsSpace);
+// }
+ }
+
+ /**
+ * Used internally, creates the actual vehicle constraint when vehicle is added to phyicsspace
+ */
+ public void createVehicle(PhysicsSpace space) {
+ physicsSpace = space;
+// try{
+// if(5==5)
+// throw new IllegalStateException("Who calls this!");
+// }catch(Exception e){
+// e.printStackTrace();
+// }
+ if (space == null) {
+ return;
+ }
+ if (space.getSpaceId() == 0) {
+ throw new IllegalStateException("Physics space is not initialized!");
+ }
+ if (rayCasterId != 0) {
+ space.removeCollisionObject(this);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Clearing RayCaster {0}", Long.toHexString(rayCasterId));
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Clearing Vehicle {0}", Long.toHexString(vehicleId));
+ finalizeNative(rayCasterId, vehicleId);
+ }
+ rayCasterId = createVehicleRaycaster(objectId, space.getSpaceId());
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created RayCaster {0}", Long.toHexString(rayCasterId));
+ vehicleId = createRaycastVehicle(objectId, rayCasterId);
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Vehicle {0}", Long.toHexString(vehicleId));
+ setCoordinateSystem(vehicleId, 0, 1, 2);
+ for (VehicleWheel wheel : wheels) {
+ wheel.setWheelId(addWheel(vehicleId, wheel.getLocation(), wheel.getDirection(), wheel.getAxle(), wheel.getRestLength(), wheel.getRadius(), tuning, wheel.isFrontWheel()));
+ }
+ }
+
+ private native long createVehicleRaycaster(long objectId, long physicsSpaceId);
+
+ private native long createRaycastVehicle(long objectId, long rayCasterId);
+
+ private native void setCoordinateSystem(long objectId, int a, int b, int c);
+
+ private native long addWheel(long objectId, Vector3f location, Vector3f direction, Vector3f axle, float restLength, float radius, VehicleTuning tuning, boolean frontWheel);
+
+ /**
+ * Add a wheel to this vehicle
+ * @param connectionPoint The starting point of the ray, where the suspension connects to the chassis (chassis space)
+ * @param direction the direction of the wheel (should be -Y / 0,-1,0 for a normal car)
+ * @param axle The axis of the wheel, pointing right in vehicle direction (should be -X / -1,0,0 for a normal car)
+ * @param suspensionRestLength The current length of the suspension (metres)
+ * @param wheelRadius the wheel radius
+ * @param isFrontWheel sets if this wheel is a front wheel (steering)
+ * @return the PhysicsVehicleWheel object to get/set infos on the wheel
+ */
+ public VehicleWheel addWheel(Vector3f connectionPoint, Vector3f direction, Vector3f axle, float suspensionRestLength, float wheelRadius, boolean isFrontWheel) {
+ return addWheel(null, connectionPoint, direction, axle, suspensionRestLength, wheelRadius, isFrontWheel);
+ }
+
+ /**
+ * Add a wheel to this vehicle
+ * @param spat the wheel Geometry
+ * @param connectionPoint The starting point of the ray, where the suspension connects to the chassis (chassis space)
+ * @param direction the direction of the wheel (should be -Y / 0,-1,0 for a normal car)
+ * @param axle The axis of the wheel, pointing right in vehicle direction (should be -X / -1,0,0 for a normal car)
+ * @param suspensionRestLength The current length of the suspension (metres)
+ * @param wheelRadius the wheel radius
+ * @param isFrontWheel sets if this wheel is a front wheel (steering)
+ * @return the PhysicsVehicleWheel object to get/set infos on the wheel
+ */
+ public VehicleWheel addWheel(Spatial spat, Vector3f connectionPoint, Vector3f direction, Vector3f axle, float suspensionRestLength, float wheelRadius, boolean isFrontWheel) {
+ VehicleWheel wheel = null;
+ if (spat == null) {
+ wheel = new VehicleWheel(connectionPoint, direction, axle, suspensionRestLength, wheelRadius, isFrontWheel);
+ } else {
+ wheel = new VehicleWheel(spat, connectionPoint, direction, axle, suspensionRestLength, wheelRadius, isFrontWheel);
+ }
+ if (vehicleId != 0) {
+ wheel.setWheelId(addWheel(vehicleId, wheel.getLocation(), wheel.getDirection(), wheel.getAxle(), wheel.getRestLength(), wheel.getRadius(), tuning, wheel.isFrontWheel()));
+ }
+ wheel.setFrictionSlip(tuning.frictionSlip);
+ wheel.setMaxSuspensionTravelCm(tuning.maxSuspensionTravelCm);
+ wheel.setSuspensionStiffness(tuning.suspensionStiffness);
+ wheel.setWheelsDampingCompression(tuning.suspensionCompression);
+ wheel.setWheelsDampingRelaxation(tuning.suspensionDamping);
+ wheel.setMaxSuspensionForce(tuning.maxSuspensionForce);
+ wheels.add(wheel);
+ if (debugShape != null) {
+ updateDebugShape();
+ }
+ return wheel;
+ }
+
+ /**
+ * This rebuilds the vehicle as there is no way in bullet to remove a wheel.
+ * @param wheel
+ */
+ public void removeWheel(int wheel) {
+ wheels.remove(wheel);
+ rebuildRigidBody();
+// updateDebugShape();
+ }
+
+ /**
+ * You can get access to the single wheels via this method.
+ * @param wheel the wheel index
+ * @return the WheelInfo of the selected wheel
+ */
+ public VehicleWheel getWheel(int wheel) {
+ return wheels.get(wheel);
+ }
+
+ public int getNumWheels() {
+ return wheels.size();
+ }
+
+ /**
+ * @return the frictionSlip
+ */
+ public float getFrictionSlip() {
+ return tuning.frictionSlip;
+ }
+
+ /**
+ * Use before adding wheels, this is the default used when adding wheels.
+ * After adding the wheel, use direct wheel access.
+ * The coefficient of friction between the tyre and the ground.
+ * Should be about 0.8 for realistic cars, but can increased for better handling.
+ * Set large (10000.0) for kart racers
+ * @param frictionSlip the frictionSlip to set
+ */
+ public void setFrictionSlip(float frictionSlip) {
+ tuning.frictionSlip = frictionSlip;
+ }
+
+ /**
+ * The coefficient of friction between the tyre and the ground.
+ * Should be about 0.8 for realistic cars, but can increased for better handling.
+ * Set large (10000.0) for kart racers
+ * @param wheel
+ * @param frictionSlip
+ */
+ public void setFrictionSlip(int wheel, float frictionSlip) {
+ wheels.get(wheel).setFrictionSlip(frictionSlip);
+ }
+
+ /**
+ * Reduces the rolling torque applied from the wheels that cause the vehicle to roll over.
+ * This is a bit of a hack, but it's quite effective. 0.0 = no roll, 1.0 = physical behaviour.
+ * If m_frictionSlip is too high, you'll need to reduce this to stop the vehicle rolling over.
+ * You should also try lowering the vehicle's centre of mass
+ */
+ public void setRollInfluence(int wheel, float rollInfluence) {
+ wheels.get(wheel).setRollInfluence(rollInfluence);
+ }
+
+ /**
+ * @return the maxSuspensionTravelCm
+ */
+ public float getMaxSuspensionTravelCm() {
+ return tuning.maxSuspensionTravelCm;
+ }
+
+ /**
+ * Use before adding wheels, this is the default used when adding wheels.
+ * After adding the wheel, use direct wheel access.
+ * The maximum distance the suspension can be compressed (centimetres)
+ * @param maxSuspensionTravelCm the maxSuspensionTravelCm to set
+ */
+ public void setMaxSuspensionTravelCm(float maxSuspensionTravelCm) {
+ tuning.maxSuspensionTravelCm = maxSuspensionTravelCm;
+ }
+
+ /**
+ * The maximum distance the suspension can be compressed (centimetres)
+ * @param wheel
+ * @param maxSuspensionTravelCm
+ */
+ public void setMaxSuspensionTravelCm(int wheel, float maxSuspensionTravelCm) {
+ wheels.get(wheel).setMaxSuspensionTravelCm(maxSuspensionTravelCm);
+ }
+
+ public float getMaxSuspensionForce() {
+ return tuning.maxSuspensionForce;
+ }
+
+ /**
+ * This vaue caps the maximum suspension force, raise this above the default 6000 if your suspension cannot
+ * handle the weight of your vehcile.
+ * @param maxSuspensionForce
+ */
+ public void setMaxSuspensionForce(float maxSuspensionForce) {
+ tuning.maxSuspensionForce = maxSuspensionForce;
+ }
+
+ /**
+ * This vaue caps the maximum suspension force, raise this above the default 6000 if your suspension cannot
+ * handle the weight of your vehcile.
+ * @param wheel
+ * @param maxSuspensionForce
+ */
+ public void setMaxSuspensionForce(int wheel, float maxSuspensionForce) {
+ wheels.get(wheel).setMaxSuspensionForce(maxSuspensionForce);
+ }
+
+ /**
+ * @return the suspensionCompression
+ */
+ public float getSuspensionCompression() {
+ return tuning.suspensionCompression;
+ }
+
+ /**
+ * Use before adding wheels, this is the default used when adding wheels.
+ * After adding the wheel, use direct wheel access.
+ * The damping coefficient for when the suspension is compressed.
+ * Set to k * 2.0 * FastMath.sqrt(m_suspensionStiffness) so k is proportional to critical damping.
+ * k = 0.0 undamped & bouncy, k = 1.0 critical damping
+ * 0.1 to 0.3 are good values
+ * @param suspensionCompression the suspensionCompression to set
+ */
+ public void setSuspensionCompression(float suspensionCompression) {
+ tuning.suspensionCompression = suspensionCompression;
+ }
+
+ /**
+ * The damping coefficient for when the suspension is compressed.
+ * Set to k * 2.0 * FastMath.sqrt(m_suspensionStiffness) so k is proportional to critical damping.
+ * k = 0.0 undamped & bouncy, k = 1.0 critical damping
+ * 0.1 to 0.3 are good values
+ * @param wheel
+ * @param suspensionCompression
+ */
+ public void setSuspensionCompression(int wheel, float suspensionCompression) {
+ wheels.get(wheel).setWheelsDampingCompression(suspensionCompression);
+ }
+
+ /**
+ * @return the suspensionDamping
+ */
+ public float getSuspensionDamping() {
+ return tuning.suspensionDamping;
+ }
+
+ /**
+ * Use before adding wheels, this is the default used when adding wheels.
+ * After adding the wheel, use direct wheel access.
+ * The damping coefficient for when the suspension is expanding.
+ * See the comments for setSuspensionCompression for how to set k.
+ * @param suspensionDamping the suspensionDamping to set
+ */
+ public void setSuspensionDamping(float suspensionDamping) {
+ tuning.suspensionDamping = suspensionDamping;
+ }
+
+ /**
+ * The damping coefficient for when the suspension is expanding.
+ * See the comments for setSuspensionCompression for how to set k.
+ * @param wheel
+ * @param suspensionDamping
+ */
+ public void setSuspensionDamping(int wheel, float suspensionDamping) {
+ wheels.get(wheel).setWheelsDampingRelaxation(suspensionDamping);
+ }
+
+ /**
+ * @return the suspensionStiffness
+ */
+ public float getSuspensionStiffness() {
+ return tuning.suspensionStiffness;
+ }
+
+ /**
+ * Use before adding wheels, this is the default used when adding wheels.
+ * After adding the wheel, use direct wheel access.
+ * The stiffness constant for the suspension. 10.0 - Offroad buggy, 50.0 - Sports car, 200.0 - F1 Car
+ * @param suspensionStiffness
+ */
+ public void setSuspensionStiffness(float suspensionStiffness) {
+ tuning.suspensionStiffness = suspensionStiffness;
+ }
+
+ /**
+ * The stiffness constant for the suspension. 10.0 - Offroad buggy, 50.0 - Sports car, 200.0 - F1 Car
+ * @param wheel
+ * @param suspensionStiffness
+ */
+ public void setSuspensionStiffness(int wheel, float suspensionStiffness) {
+ wheels.get(wheel).setSuspensionStiffness(suspensionStiffness);
+ }
+
+ /**
+ * Reset the suspension
+ */
+ public void resetSuspension() {
+ resetSuspension(vehicleId);
+ }
+
+ private native void resetSuspension(long vehicleId);
+
+ /**
+ * Apply the given engine force to all wheels, works continuously
+ * @param force the force
+ */
+ public void accelerate(float force) {
+ for (int i = 0; i < wheels.size(); i++) {
+ accelerate(i, force);
+ }
+ }
+
+ /**
+ * Apply the given engine force, works continuously
+ * @param wheel the wheel to apply the force on
+ * @param force the force
+ */
+ public void accelerate(int wheel, float force) {
+ applyEngineForce(vehicleId, wheel, force);
+
+ }
+
+ private native void applyEngineForce(long vehicleId, int wheel, float force);
+
+ /**
+ * Set the given steering value to all front wheels (0 = forward)
+ * @param value the steering angle of the front wheels (Pi = 360deg)
+ */
+ public void steer(float value) {
+ for (int i = 0; i < wheels.size(); i++) {
+ if (getWheel(i).isFrontWheel()) {
+ steer(i, value);
+ }
+ }
+ }
+
+ /**
+ * Set the given steering value to the given wheel (0 = forward)
+ * @param wheel the wheel to set the steering on
+ * @param value the steering angle of the front wheels (Pi = 360deg)
+ */
+ public void steer(int wheel, float value) {
+ steer(vehicleId, wheel, value);
+ }
+
+ private native void steer(long vehicleId, int wheel, float value);
+
+ /**
+ * Apply the given brake force to all wheels, works continuously
+ * @param force the force
+ */
+ public void brake(float force) {
+ for (int i = 0; i < wheels.size(); i++) {
+ brake(i, force);
+ }
+ }
+
+ /**
+ * Apply the given brake force, works continuously
+ * @param wheel the wheel to apply the force on
+ * @param force the force
+ */
+ public void brake(int wheel, float force) {
+ brake(vehicleId, wheel, force);
+ }
+
+ private native void brake(long vehicleId, int wheel, float force);
+
+ /**
+ * Get the current speed of the vehicle in km/h
+ * @return
+ */
+ public float getCurrentVehicleSpeedKmHour() {
+ return getCurrentVehicleSpeedKmHour(vehicleId);
+ }
+
+ private native float getCurrentVehicleSpeedKmHour(long vehicleId);
+
+ /**
+ * Get the current forward vector of the vehicle in world coordinates
+ * @param vector
+ * @return
+ */
+ public Vector3f getForwardVector(Vector3f vector) {
+ if (vector == null) {
+ vector = new Vector3f();
+ }
+ getForwardVector(vehicleId, vector);
+ return vector;
+ }
+
+ private native void getForwardVector(long objectId, Vector3f vector);
+
+ /**
+ * used internally
+ */
+ public long getVehicleId() {
+ return vehicleId;
+ }
+
+ @Override
+ protected Spatial getDebugShape() {
+ Spatial shape = super.getDebugShape();
+ Node node = null;
+ if (shape instanceof Node) {
+ node = (Node) shape;
+ } else {
+ node = new Node("DebugShapeNode");
+ node.attachChild(shape);
+ }
+ int i = 0;
+ for (Iterator it = wheels.iterator(); it.hasNext();) {
+ VehicleWheel physicsVehicleWheel = it.next();
+ Vector3f location = physicsVehicleWheel.getLocation().clone();
+ Vector3f direction = physicsVehicleWheel.getDirection().clone();
+ Vector3f axle = physicsVehicleWheel.getAxle().clone();
+ float restLength = physicsVehicleWheel.getRestLength();
+ float radius = physicsVehicleWheel.getRadius();
+
+ Arrow locArrow = new Arrow(location);
+ Arrow axleArrow = new Arrow(axle.normalizeLocal().multLocal(0.3f));
+ Arrow wheelArrow = new Arrow(direction.normalizeLocal().multLocal(radius));
+ Arrow dirArrow = new Arrow(direction.normalizeLocal().multLocal(restLength));
+ Geometry locGeom = new Geometry("WheelLocationDebugShape" + i, locArrow);
+ Geometry dirGeom = new Geometry("WheelDirectionDebugShape" + i, dirArrow);
+ Geometry axleGeom = new Geometry("WheelAxleDebugShape" + i, axleArrow);
+ Geometry wheelGeom = new Geometry("WheelRadiusDebugShape" + i, wheelArrow);
+ dirGeom.setLocalTranslation(location);
+ axleGeom.setLocalTranslation(location.add(direction));
+ wheelGeom.setLocalTranslation(location.add(direction));
+ locGeom.setMaterial(debugMaterialGreen);
+ dirGeom.setMaterial(debugMaterialGreen);
+ axleGeom.setMaterial(debugMaterialGreen);
+ wheelGeom.setMaterial(debugMaterialGreen);
+ node.attachChild(locGeom);
+ node.attachChild(dirGeom);
+ node.attachChild(axleGeom);
+ node.attachChild(wheelGeom);
+ i++;
+ }
+ return node;
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ InputCapsule capsule = im.getCapsule(this);
+ tuning = new VehicleTuning();
+ tuning.frictionSlip = capsule.readFloat("frictionSlip", 10.5f);
+ tuning.maxSuspensionTravelCm = capsule.readFloat("maxSuspensionTravelCm", 500f);
+ tuning.maxSuspensionForce = capsule.readFloat("maxSuspensionForce", 6000f);
+ tuning.suspensionCompression = capsule.readFloat("suspensionCompression", 0.83f);
+ tuning.suspensionDamping = capsule.readFloat("suspensionDamping", 0.88f);
+ tuning.suspensionStiffness = capsule.readFloat("suspensionStiffness", 5.88f);
+ wheels = capsule.readSavableArrayList("wheelsList", new ArrayList());
+ motionState.setVehicle(this);
+ super.read(im);
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(tuning.frictionSlip, "frictionSlip", 10.5f);
+ capsule.write(tuning.maxSuspensionTravelCm, "maxSuspensionTravelCm", 500f);
+ capsule.write(tuning.maxSuspensionForce, "maxSuspensionForce", 6000f);
+ capsule.write(tuning.suspensionCompression, "suspensionCompression", 0.83f);
+ capsule.write(tuning.suspensionDamping, "suspensionDamping", 0.88f);
+ capsule.write(tuning.suspensionStiffness, "suspensionStiffness", 5.88f);
+ capsule.writeSavableArrayList(wheels, "wheelsList", new ArrayList());
+ super.write(ex);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing RayCaster {0}", Long.toHexString(rayCasterId));
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing Vehicle {0}", Long.toHexString(vehicleId));
+ finalizeNative(rayCasterId, vehicleId);
+ }
+
+ private native void finalizeNative(long rayCaster, long vehicle);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/objects/VehicleWheel.java b/engine/src/bullet/com/jme3/bullet/objects/VehicleWheel.java
new file mode 100644
index 000000000..7b31f7b0b
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/objects/VehicleWheel.java
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.objects;
+
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Spatial;
+import com.jme3.bullet.collision.PhysicsCollisionObject;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.export.Savable;
+import com.jme3.math.Matrix3f;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Stores info about one wheel of a PhysicsVehicle
+ * @author normenhansen
+ */
+public class VehicleWheel implements Savable {
+
+ protected long wheelId = 0;
+ protected boolean frontWheel;
+ protected Vector3f location = new Vector3f();
+ protected Vector3f direction = new Vector3f();
+ protected Vector3f axle = new Vector3f();
+ protected float suspensionStiffness = 20.0f;
+ protected float wheelsDampingRelaxation = 2.3f;
+ protected float wheelsDampingCompression = 4.4f;
+ protected float frictionSlip = 10.5f;
+ protected float rollInfluence = 1.0f;
+ protected float maxSuspensionTravelCm = 500f;
+ protected float maxSuspensionForce = 6000f;
+ protected float radius = 0.5f;
+ protected float restLength = 1f;
+ protected Vector3f wheelWorldLocation = new Vector3f();
+ protected Quaternion wheelWorldRotation = new Quaternion();
+ protected Spatial wheelSpatial;
+ protected Matrix3f tmp_Matrix = new com.jme3.math.Matrix3f();
+ protected final Quaternion tmp_inverseWorldRotation = new Quaternion();
+ private boolean applyLocal = false;
+
+ public VehicleWheel() {
+ }
+
+ public VehicleWheel(Spatial spat, Vector3f location, Vector3f direction, Vector3f axle,
+ float restLength, float radius, boolean frontWheel) {
+ this(location, direction, axle, restLength, radius, frontWheel);
+ wheelSpatial = spat;
+ }
+
+ public VehicleWheel(Vector3f location, Vector3f direction, Vector3f axle,
+ float restLength, float radius, boolean frontWheel) {
+ this.location.set(location);
+ this.direction.set(direction);
+ this.axle.set(axle);
+ this.frontWheel = frontWheel;
+ this.restLength = restLength;
+ this.radius = radius;
+ }
+
+ public synchronized void updatePhysicsState() {
+ getWheelLocation(wheelId, wheelWorldLocation);
+ getWheelRotation(wheelId, tmp_Matrix);
+ wheelWorldRotation.fromRotationMatrix(tmp_Matrix);
+ }
+
+ private native void getWheelLocation(long wheelId, Vector3f location);
+
+ private native void getWheelRotation(long wheelId, Matrix3f location);
+
+ public synchronized void applyWheelTransform() {
+ if (wheelSpatial == null) {
+ return;
+ }
+ Quaternion localRotationQuat = wheelSpatial.getLocalRotation();
+ Vector3f localLocation = wheelSpatial.getLocalTranslation();
+ if (!applyLocal && wheelSpatial.getParent() != null) {
+ localLocation.set(wheelWorldLocation).subtractLocal(wheelSpatial.getParent().getWorldTranslation());
+ localLocation.divideLocal(wheelSpatial.getParent().getWorldScale());
+ tmp_inverseWorldRotation.set(wheelSpatial.getParent().getWorldRotation()).inverseLocal().multLocal(localLocation);
+
+ localRotationQuat.set(wheelWorldRotation);
+ tmp_inverseWorldRotation.set(wheelSpatial.getParent().getWorldRotation()).inverseLocal().mult(localRotationQuat, localRotationQuat);
+
+ wheelSpatial.setLocalTranslation(localLocation);
+ wheelSpatial.setLocalRotation(localRotationQuat);
+ } else {
+ wheelSpatial.setLocalTranslation(wheelWorldLocation);
+ wheelSpatial.setLocalRotation(wheelWorldRotation);
+ }
+ }
+
+ public long getWheelId() {
+ return wheelId;
+ }
+
+ public void setWheelId(long wheelInfo) {
+ this.wheelId = wheelInfo;
+ applyInfo();
+ }
+
+ public boolean isFrontWheel() {
+ return frontWheel;
+ }
+
+ public void setFrontWheel(boolean frontWheel) {
+ this.frontWheel = frontWheel;
+ applyInfo();
+ }
+
+ public Vector3f getLocation() {
+ return location;
+ }
+
+ public Vector3f getDirection() {
+ return direction;
+ }
+
+ public Vector3f getAxle() {
+ return axle;
+ }
+
+ public float getSuspensionStiffness() {
+ return suspensionStiffness;
+ }
+
+ /**
+ * the stiffness constant for the suspension. 10.0 - Offroad buggy, 50.0 - Sports car, 200.0 - F1 Car
+ * @param suspensionStiffness
+ */
+ public void setSuspensionStiffness(float suspensionStiffness) {
+ this.suspensionStiffness = suspensionStiffness;
+ applyInfo();
+ }
+
+ public float getWheelsDampingRelaxation() {
+ return wheelsDampingRelaxation;
+ }
+
+ /**
+ * the damping coefficient for when the suspension is expanding.
+ * See the comments for setWheelsDampingCompression for how to set k.
+ * @param wheelsDampingRelaxation
+ */
+ public void setWheelsDampingRelaxation(float wheelsDampingRelaxation) {
+ this.wheelsDampingRelaxation = wheelsDampingRelaxation;
+ applyInfo();
+ }
+
+ public float getWheelsDampingCompression() {
+ return wheelsDampingCompression;
+ }
+
+ /**
+ * the damping coefficient for when the suspension is compressed.
+ * Set to k * 2.0 * FastMath.sqrt(m_suspensionStiffness) so k is proportional to critical damping.
+ * k = 0.0 undamped & bouncy, k = 1.0 critical damping
+ * 0.1 to 0.3 are good values
+ * @param wheelsDampingCompression
+ */
+ public void setWheelsDampingCompression(float wheelsDampingCompression) {
+ this.wheelsDampingCompression = wheelsDampingCompression;
+ applyInfo();
+ }
+
+ public float getFrictionSlip() {
+ return frictionSlip;
+ }
+
+ /**
+ * the coefficient of friction between the tyre and the ground.
+ * Should be about 0.8 for realistic cars, but can increased for better handling.
+ * Set large (10000.0) for kart racers
+ * @param frictionSlip
+ */
+ public void setFrictionSlip(float frictionSlip) {
+ this.frictionSlip = frictionSlip;
+ applyInfo();
+ }
+
+ public float getRollInfluence() {
+ return rollInfluence;
+ }
+
+ /**
+ * reduces the rolling torque applied from the wheels that cause the vehicle to roll over.
+ * This is a bit of a hack, but it's quite effective. 0.0 = no roll, 1.0 = physical behaviour.
+ * If m_frictionSlip is too high, you'll need to reduce this to stop the vehicle rolling over.
+ * You should also try lowering the vehicle's centre of mass
+ * @param rollInfluence the rollInfluence to set
+ */
+ public void setRollInfluence(float rollInfluence) {
+ this.rollInfluence = rollInfluence;
+ applyInfo();
+ }
+
+ public float getMaxSuspensionTravelCm() {
+ return maxSuspensionTravelCm;
+ }
+
+ /**
+ * the maximum distance the suspension can be compressed (centimetres)
+ * @param maxSuspensionTravelCm
+ */
+ public void setMaxSuspensionTravelCm(float maxSuspensionTravelCm) {
+ this.maxSuspensionTravelCm = maxSuspensionTravelCm;
+ applyInfo();
+ }
+
+ public float getMaxSuspensionForce() {
+ return maxSuspensionForce;
+ }
+
+ /**
+ * The maximum suspension force, raise this above the default 6000 if your suspension cannot
+ * handle the weight of your vehcile.
+ * @param maxSuspensionTravelCm
+ */
+ public void setMaxSuspensionForce(float maxSuspensionForce) {
+ this.maxSuspensionForce = maxSuspensionForce;
+ applyInfo();
+ }
+
+ private void applyInfo() {
+ if (wheelId == 0) {
+ return;
+ }
+ applyInfo(wheelId, suspensionStiffness, wheelsDampingRelaxation, wheelsDampingCompression, frictionSlip, rollInfluence, maxSuspensionTravelCm, maxSuspensionForce, radius, frontWheel, restLength);
+ }
+
+ private native void applyInfo(long wheelId,
+ float suspensionStiffness,
+ float wheelsDampingRelaxation,
+ float wheelsDampingCompression,
+ float frictionSlip,
+ float rollInfluence,
+ float maxSuspensionTravelCm,
+ float maxSuspensionForce,
+ float wheelsRadius,
+ boolean frontWheel,
+ float suspensionRestLength);
+
+ public float getRadius() {
+ return radius;
+ }
+
+ public void setRadius(float radius) {
+ this.radius = radius;
+ applyInfo();
+ }
+
+ public float getRestLength() {
+ return restLength;
+ }
+
+ public void setRestLength(float restLength) {
+ this.restLength = restLength;
+ applyInfo();
+ }
+
+ /**
+ * returns the object this wheel is in contact with or null if no contact
+ * @return the PhysicsCollisionObject (PhysicsRigidBody, PhysicsGhostObject)
+ */
+ public PhysicsCollisionObject getGroundObject() {
+// if (wheelInfo.raycastInfo.groundObject == null) {
+// return null;
+// } else if (wheelInfo.raycastInfo.groundObject instanceof RigidBody) {
+// System.out.println("RigidBody");
+// return (PhysicsRigidBody) ((RigidBody) wheelInfo.raycastInfo.groundObject).getUserPointer();
+// } else {
+ return null;
+// }
+ }
+
+ /**
+ * returns the location where the wheel collides with the ground (world space)
+ */
+ public Vector3f getCollisionLocation(Vector3f vec) {
+ getCollisionLocation(wheelId, vec);
+ return vec;
+ }
+
+ private native void getCollisionLocation(long wheelId, Vector3f vec);
+
+ /**
+ * returns the location where the wheel collides with the ground (world space)
+ */
+ public Vector3f getCollisionLocation() {
+ Vector3f vec = new Vector3f();
+ getCollisionLocation(wheelId, vec);
+ return vec;
+ }
+
+ /**
+ * returns the normal where the wheel collides with the ground (world space)
+ */
+ public Vector3f getCollisionNormal(Vector3f vec) {
+ getCollisionNormal(wheelId, vec);
+ return vec;
+ }
+
+ private native void getCollisionNormal(long wheelId, Vector3f vec);
+
+ /**
+ * returns the normal where the wheel collides with the ground (world space)
+ */
+ public Vector3f getCollisionNormal() {
+ Vector3f vec = new Vector3f();
+ getCollisionNormal(wheelId, vec);
+ return vec;
+ }
+
+ /**
+ * returns how much the wheel skids on the ground (for skid sounds/smoke etc.)
+ * 0.0 = wheels are sliding, 1.0 = wheels have traction.
+ */
+ public float getSkidInfo() {
+ return getSkidInfo(wheelId);
+ }
+
+ public native float getSkidInfo(long wheelId);
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ InputCapsule capsule = im.getCapsule(this);
+ wheelSpatial = (Spatial) capsule.readSavable("wheelSpatial", null);
+ frontWheel = capsule.readBoolean("frontWheel", false);
+ location = (Vector3f) capsule.readSavable("wheelLocation", new Vector3f());
+ direction = (Vector3f) capsule.readSavable("wheelDirection", new Vector3f());
+ axle = (Vector3f) capsule.readSavable("wheelAxle", new Vector3f());
+ suspensionStiffness = capsule.readFloat("suspensionStiffness", 20.0f);
+ wheelsDampingRelaxation = capsule.readFloat("wheelsDampingRelaxation", 2.3f);
+ wheelsDampingCompression = capsule.readFloat("wheelsDampingCompression", 4.4f);
+ frictionSlip = capsule.readFloat("frictionSlip", 10.5f);
+ rollInfluence = capsule.readFloat("rollInfluence", 1.0f);
+ maxSuspensionTravelCm = capsule.readFloat("maxSuspensionTravelCm", 500f);
+ maxSuspensionForce = capsule.readFloat("maxSuspensionForce", 6000f);
+ radius = capsule.readFloat("wheelRadius", 0.5f);
+ restLength = capsule.readFloat("restLength", 1f);
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(wheelSpatial, "wheelSpatial", null);
+ capsule.write(frontWheel, "frontWheel", false);
+ capsule.write(location, "wheelLocation", new Vector3f());
+ capsule.write(direction, "wheelDirection", new Vector3f());
+ capsule.write(axle, "wheelAxle", new Vector3f());
+ capsule.write(suspensionStiffness, "suspensionStiffness", 20.0f);
+ capsule.write(wheelsDampingRelaxation, "wheelsDampingRelaxation", 2.3f);
+ capsule.write(wheelsDampingCompression, "wheelsDampingCompression", 4.4f);
+ capsule.write(frictionSlip, "frictionSlip", 10.5f);
+ capsule.write(rollInfluence, "rollInfluence", 1.0f);
+ capsule.write(maxSuspensionTravelCm, "maxSuspensionTravelCm", 500f);
+ capsule.write(maxSuspensionForce, "maxSuspensionForce", 6000f);
+ capsule.write(radius, "wheelRadius", 0.5f);
+ capsule.write(restLength, "restLength", 1f);
+ }
+
+ /**
+ * @return the wheelSpatial
+ */
+ public Spatial getWheelSpatial() {
+ return wheelSpatial;
+ }
+
+ /**
+ * @param wheelSpatial the wheelSpatial to set
+ */
+ public void setWheelSpatial(Spatial wheelSpatial) {
+ this.wheelSpatial = wheelSpatial;
+ }
+
+ public boolean isApplyLocal() {
+ return applyLocal;
+ }
+
+ public void setApplyLocal(boolean applyLocal) {
+ this.applyLocal = applyLocal;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing Wheel {0}", Long.toHexString(wheelId));
+ finalizeNative(wheelId);
+ }
+
+ private native void finalizeNative(long wheelId);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/objects/infos/RigidBodyMotionState.java b/engine/src/bullet/com/jme3/bullet/objects/infos/RigidBodyMotionState.java
new file mode 100644
index 000000000..c60d6c51e
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/objects/infos/RigidBodyMotionState.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.objects.infos;
+
+import com.jme3.bullet.objects.PhysicsVehicle;
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Spatial;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * stores transform info of a PhysicsNode in a threadsafe manner to
+ * allow multithreaded access from the jme scenegraph and the bullet physicsspace
+ * @author normenhansen
+ */
+public class RigidBodyMotionState {
+ long motionStateId = 0;
+ private Vector3f worldLocation = new Vector3f();
+ private Matrix3f worldRotation = new Matrix3f();
+ private Quaternion worldRotationQuat = new Quaternion();
+ private Quaternion tmp_inverseWorldRotation = new Quaternion();
+ private PhysicsVehicle vehicle;
+ private boolean applyPhysicsLocal = false;
+// protected LinkedList listeners = new LinkedList();
+
+ public RigidBodyMotionState() {
+ this.motionStateId = createMotionState();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created MotionState {0}", Long.toHexString(motionStateId));
+ }
+
+ private native long createMotionState();
+
+ /**
+ * applies the current transform to the given jme Node if the location has been updated on the physics side
+ * @param spatial
+ */
+ public synchronized boolean applyTransform(Spatial spatial) {
+ Vector3f localLocation = spatial.getLocalTranslation();
+ Quaternion localRotationQuat = spatial.getLocalRotation();
+ boolean physicsLocationDirty = applyTransform(motionStateId, localLocation, localRotationQuat);
+ if (!physicsLocationDirty) {
+ return false;
+ }
+ if (!applyPhysicsLocal && spatial.getParent() != null) {
+ localLocation.subtractLocal(spatial.getParent().getWorldTranslation());
+ localLocation.divideLocal(spatial.getParent().getWorldScale());
+ tmp_inverseWorldRotation.set(spatial.getParent().getWorldRotation()).inverseLocal().multLocal(localLocation);
+
+// localRotationQuat.set(worldRotationQuat);
+ tmp_inverseWorldRotation.mult(localRotationQuat, localRotationQuat);
+
+ spatial.setLocalTranslation(localLocation);
+ spatial.setLocalRotation(localRotationQuat);
+ } else {
+ spatial.setLocalTranslation(localLocation);
+ spatial.setLocalRotation(localRotationQuat);
+// spatial.setLocalTranslation(worldLocation);
+// spatial.setLocalRotation(worldRotationQuat);
+ }
+ if (vehicle != null) {
+ vehicle.updateWheels();
+ }
+ return true;
+ }
+
+ private synchronized native boolean applyTransform(long stateId, Vector3f location, Quaternion rotation);
+
+ /**
+ * @return the worldLocation
+ */
+ public Vector3f getWorldLocation() {
+ getWorldLocation(motionStateId, worldLocation);
+ return worldLocation;
+ }
+
+ private native void getWorldLocation(long stateId, Vector3f vec);
+
+ /**
+ * @return the worldRotation
+ */
+ public Matrix3f getWorldRotation() {
+ getWorldRotation(motionStateId, worldRotation);
+ return worldRotation;
+ }
+
+ private native void getWorldRotation(long stateId, Matrix3f vec);
+
+ /**
+ * @return the worldRotationQuat
+ */
+ public Quaternion getWorldRotationQuat() {
+ getWorldRotationQuat(motionStateId, worldRotationQuat);
+ return worldRotationQuat;
+ }
+
+ private native void getWorldRotationQuat(long stateId, Quaternion vec);
+
+ /**
+ * @param vehicle the vehicle to set
+ */
+ public void setVehicle(PhysicsVehicle vehicle) {
+ this.vehicle = vehicle;
+ }
+
+ public boolean isApplyPhysicsLocal() {
+ return applyPhysicsLocal;
+ }
+
+ public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
+ this.applyPhysicsLocal = applyPhysicsLocal;
+ }
+
+ public long getObjectId(){
+ return motionStateId;
+ }
+// public void addMotionStateListener(PhysicsMotionStateListener listener){
+// listeners.add(listener);
+// }
+//
+// public void removeMotionStateListener(PhysicsMotionStateListener listener){
+// listeners.remove(listener);
+// }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing MotionState {0}", Long.toHexString(motionStateId));
+ finalizeNative(motionStateId);
+ }
+
+ private native void finalizeNative(long objectId);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/objects/infos/VehicleTuning.java b/engine/src/bullet/com/jme3/bullet/objects/infos/VehicleTuning.java
new file mode 100644
index 000000000..892c9bde3
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/objects/infos/VehicleTuning.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.objects.infos;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class VehicleTuning {
+ public float suspensionStiffness = 5.88f;
+ public float suspensionCompression = 0.83f;
+ public float suspensionDamping = 0.88f;
+ public float maxSuspensionTravelCm = 500f;
+ public float maxSuspensionForce = 6000f;
+ public float frictionSlip = 10.5f;
+}
diff --git a/engine/src/bullet/com/jme3/bullet/util/CollisionShapeFactory.java b/engine/src/bullet/com/jme3/bullet/util/CollisionShapeFactory.java
new file mode 100644
index 000000000..278a53243
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/util/CollisionShapeFactory.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.util;
+
+import com.jme3.bounding.BoundingBox;
+import com.jme3.bullet.collision.shapes.BoxCollisionShape;
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
+import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
+import com.jme3.bullet.collision.shapes.HullCollisionShape;
+import com.jme3.bullet.collision.shapes.MeshCollisionShape;
+import com.jme3.bullet.collision.shapes.infos.ChildCollisionShape;
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.terrain.geomipmap.TerrainQuad;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ *
+ * @author normenhansen, tim8dev
+ */
+public class CollisionShapeFactory {
+
+ /**
+ * returns the correct transform for a collisionshape in relation
+ * to the ancestor for which the collisionshape is generated
+ * @param spat
+ * @param parent
+ * @return
+ */
+ private static Transform getTransform(Spatial spat, Spatial parent) {
+ Transform shapeTransform = new Transform();
+ Spatial parentNode = spat.getParent() != null ? spat.getParent() : spat;
+ Spatial currentSpatial = spat;
+ //if we have parents combine their transforms
+ while (parentNode != null) {
+ if (parent == currentSpatial) {
+ //real parent -> only apply scale, not transform
+ Transform trans = new Transform();
+ trans.setScale(currentSpatial.getLocalScale());
+ shapeTransform.combineWithParent(trans);
+ parentNode = null;
+ } else {
+ shapeTransform.combineWithParent(currentSpatial.getLocalTransform());
+ parentNode = currentSpatial.getParent();
+ currentSpatial = parentNode;
+ }
+ }
+ return shapeTransform;
+ }
+
+ private static CompoundCollisionShape createCompoundShape(Node realRootNode,
+ Node rootNode, CompoundCollisionShape shape, boolean meshAccurate, boolean dynamic) {
+ for (Spatial spatial : rootNode.getChildren()) {
+ if (spatial instanceof Node) {
+ createCompoundShape(realRootNode, (Node) spatial, shape, meshAccurate, dynamic);
+ } else if (spatial instanceof Geometry) {
+ if (meshAccurate) {
+ CollisionShape childShape = dynamic
+ ? createSingleDynamicMeshShape((Geometry) spatial, realRootNode)
+ : createSingleMeshShape((Geometry) spatial, realRootNode);
+ if (childShape != null) {
+ Transform trans = getTransform(spatial, realRootNode);
+ shape.addChildShape(childShape,
+ trans.getTranslation(),
+ trans.getRotation().toRotationMatrix());
+ }
+ } else {
+ Transform trans = getTransform(spatial, realRootNode);
+ shape.addChildShape(createSingleBoxShape(spatial, realRootNode),
+ trans.getTranslation(),
+ trans.getRotation().toRotationMatrix());
+ }
+ }
+ }
+ return shape;
+ }
+
+ private static CompoundCollisionShape createCompoundShape(
+ Node rootNode, CompoundCollisionShape shape, boolean meshAccurate) {
+ return createCompoundShape(rootNode, rootNode, shape, meshAccurate, false);
+ }
+
+ /**
+ * This type of collision shape is mesh-accurate and meant for immovable "world objects".
+ * Examples include terrain, houses or whole shooter levels.
+ * Objects with "mesh" type collision shape will not collide with each other.
+ */
+ private static CompoundCollisionShape createMeshCompoundShape(Node rootNode) {
+ return createCompoundShape(rootNode, new CompoundCollisionShape(), true);
+ }
+
+ /**
+ * This type of collision shape creates a CompoundShape made out of boxes that
+ * are based on the bounds of the Geometries in the tree.
+ * @param rootNode
+ * @return
+ */
+ private static CompoundCollisionShape createBoxCompoundShape(Node rootNode) {
+ return createCompoundShape(rootNode, new CompoundCollisionShape(), false);
+ }
+
+ /**
+ * This type of collision shape is mesh-accurate and meant for immovable "world objects".
+ * Examples include terrain, houses or whole shooter levels.
+ * Objects with "mesh" type collision shape will not collide with each other.
+ * Creates a HeightfieldCollisionShape if the supplied spatial is a TerrainQuad.
+ * @return A MeshCollisionShape or a CompoundCollisionShape with MeshCollisionShapes as children if the supplied spatial is a Node. A HeightieldCollisionShape if a TerrainQuad was supplied.
+ */
+ public static CollisionShape createMeshShape(Spatial spatial) {
+ if (spatial instanceof TerrainQuad) {
+ TerrainQuad terrain = (TerrainQuad) spatial;
+ return new HeightfieldCollisionShape(terrain.getHeightMap(), terrain.getLocalScale());
+ } else if (spatial instanceof Geometry) {
+ return createSingleMeshShape((Geometry) spatial, spatial);
+ } else if (spatial instanceof Node) {
+ return createMeshCompoundShape((Node) spatial);
+ } else {
+ throw new IllegalArgumentException("Supplied spatial must either be Node or Geometry!");
+ }
+ }
+
+ /**
+ * This method creates a hull shape for the given Spatial.
+ * If you want to have mesh-accurate dynamic shapes (CPU intense!!!) use GImpact shapes, its probably best to do so with a low-poly version of your model.
+ * @return A HullCollisionShape or a CompoundCollisionShape with HullCollisionShapes as children if the supplied spatial is a Node.
+ */
+ public static CollisionShape createDynamicMeshShape(Spatial spatial) {
+ if (spatial instanceof Geometry) {
+ return createSingleDynamicMeshShape((Geometry) spatial, spatial);
+ } else if (spatial instanceof Node) {
+ return createCompoundShape((Node) spatial, (Node) spatial, new CompoundCollisionShape(), true, true);
+ } else {
+ throw new IllegalArgumentException("Supplied spatial must either be Node or Geometry!");
+ }
+
+ }
+
+ public static CollisionShape createBoxShape(Spatial spatial) {
+ if (spatial instanceof Geometry) {
+ return createSingleBoxShape((Geometry) spatial, spatial);
+ } else if (spatial instanceof Node) {
+ return createBoxCompoundShape((Node) spatial);
+ } else {
+ throw new IllegalArgumentException("Supplied spatial must either be Node or Geometry!");
+ }
+ }
+
+ /**
+ * This type of collision shape is mesh-accurate and meant for immovable "world objects".
+ * Examples include terrain, houses or whole shooter levels.
+ * Objects with "mesh" type collision shape will not collide with each other.
+ */
+ private static MeshCollisionShape createSingleMeshShape(Geometry geom, Spatial parent) {
+ Mesh mesh = geom.getMesh();
+ Transform trans = getTransform(geom, parent);
+ if (mesh != null) {
+ MeshCollisionShape mColl = new MeshCollisionShape(mesh);
+ mColl.setScale(trans.getScale());
+ return mColl;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Uses the bounding box of the supplied spatial to create a BoxCollisionShape
+ * @param spatial
+ * @return BoxCollisionShape with the size of the spatials BoundingBox
+ */
+ private static BoxCollisionShape createSingleBoxShape(Spatial spatial, Spatial parent) {
+ spatial.setModelBound(new BoundingBox());
+ //TODO: using world bound here instead of "local world" bound...
+ BoxCollisionShape shape = new BoxCollisionShape(
+ ((BoundingBox) spatial.getWorldBound()).getExtent(new Vector3f()));
+ return shape;
+ }
+
+ /**
+ * This method creates a hull collision shape for the given mesh.
+ */
+ private static HullCollisionShape createSingleDynamicMeshShape(Geometry geom, Spatial parent) {
+ Mesh mesh = geom.getMesh();
+ Transform trans = getTransform(geom, parent);
+ if (mesh != null) {
+ HullCollisionShape dynamicShape = new HullCollisionShape(mesh);
+ dynamicShape.setScale(trans.getScale());
+ return dynamicShape;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * This method moves each child shape of a compound shape by the given vector
+ * @param vector
+ */
+ public static void shiftCompoundShapeContents(CompoundCollisionShape compoundShape, Vector3f vector) {
+ for (Iterator it = new LinkedList(compoundShape.getChildren()).iterator(); it.hasNext();) {
+ ChildCollisionShape childCollisionShape = it.next();
+ CollisionShape child = childCollisionShape.shape;
+ Vector3f location = childCollisionShape.location;
+ Matrix3f rotation = childCollisionShape.rotation;
+ compoundShape.removeChildShape(child);
+ compoundShape.addChildShape(child, location.add(vector), rotation);
+ }
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/util/DebugMeshCallback.java b/engine/src/bullet/com/jme3/bullet/util/DebugMeshCallback.java
new file mode 100644
index 000000000..9960011d4
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/util/DebugMeshCallback.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.util;
+
+import com.jme3.math.Vector3f;
+import com.jme3.util.BufferUtils;
+import java.nio.FloatBuffer;
+import java.util.ArrayList;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class DebugMeshCallback {
+
+ private ArrayList list = new ArrayList();
+
+ public void addVector(float x, float y, float z, int part, int index) {
+ list.add(new Vector3f(x, y, z));
+ }
+
+ public FloatBuffer getVertices() {
+ FloatBuffer buf = BufferUtils.createFloatBuffer(list.size() * 3);
+ for (int i = 0; i < list.size(); i++) {
+ Vector3f vector3f = list.get(i);
+ buf.put(vector3f.x);
+ buf.put(vector3f.y);
+ buf.put(vector3f.z);
+ }
+ return buf;
+ }
+}
diff --git a/engine/src/bullet/com/jme3/bullet/util/DebugShapeFactory.java b/engine/src/bullet/com/jme3/bullet/util/DebugShapeFactory.java
new file mode 100644
index 000000000..1dd1c3029
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/util/DebugShapeFactory.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.util;
+
+import com.jme3.bullet.collision.shapes.CollisionShape;
+import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
+import com.jme3.bullet.collision.shapes.infos.ChildCollisionShape;
+import com.jme3.math.Matrix3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.VertexBuffer.Type;
+import com.jme3.util.TempVars;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ *
+ * @author CJ Hare, normenhansen
+ */
+public class DebugShapeFactory {
+
+ /** The maximum corner for the aabb used for triangles to include in ConcaveShape processing.*/
+// private static final Vector3f aabbMax = new Vector3f(1e30f, 1e30f, 1e30f);
+ /** The minimum corner for the aabb used for triangles to include in ConcaveShape processing.*/
+// private static final Vector3f aabbMin = new Vector3f(-1e30f, -1e30f, -1e30f);
+
+ /**
+ * Creates a debug shape from the given collision shape. This is mostly used internally.
+ * To attach a debug shape to a physics object, call attachDebugShape(AssetManager manager);
on it.
+ * @param collisionShape
+ * @return
+ */
+ public static Spatial getDebugShape(CollisionShape collisionShape) {
+ if (collisionShape == null) {
+ return null;
+ }
+ Spatial debugShape;
+ if (collisionShape instanceof CompoundCollisionShape) {
+ CompoundCollisionShape shape = (CompoundCollisionShape) collisionShape;
+ List children = shape.getChildren();
+ Node node = new Node("DebugShapeNode");
+ for (Iterator it = children.iterator(); it.hasNext();) {
+ ChildCollisionShape childCollisionShape = it.next();
+ CollisionShape ccollisionShape = childCollisionShape.shape;
+ Geometry geometry = createDebugShape(ccollisionShape);
+
+ // apply translation
+ geometry.setLocalTranslation(childCollisionShape.location);
+
+ // apply rotation
+ TempVars vars = TempVars.get();
+ assert vars.lock();
+ Matrix3f tempRot = vars.tempMat3;
+
+ tempRot.set(geometry.getLocalRotation());
+ childCollisionShape.rotation.mult(tempRot, tempRot);
+ geometry.setLocalRotation(tempRot);
+
+ assert vars.unlock();
+
+ node.attachChild(geometry);
+ }
+ debugShape = node;
+ } else {
+ debugShape = createDebugShape(collisionShape);
+ }
+ if (debugShape == null) {
+ return null;
+ }
+ debugShape.updateGeometricState();
+ return debugShape;
+ }
+
+ private static Geometry createDebugShape(CollisionShape shape) {
+ Geometry geom = new Geometry();
+ geom.setMesh(DebugShapeFactory.getDebugMesh(shape));
+// geom.setLocalScale(shape.getScale());
+ geom.updateModelBound();
+ return geom;
+ }
+
+ public static Mesh getDebugMesh(CollisionShape shape) {
+ Mesh mesh = new Mesh();
+ mesh = new Mesh();
+ DebugMeshCallback callback = new DebugMeshCallback();
+ getVertices(shape.getObjectId(), callback);
+ mesh.setBuffer(Type.Position, 3, callback.getVertices());
+ mesh.getFloatBuffer(Type.Position).clear();
+ return mesh;
+ }
+
+ private static native void getVertices(long shapeId, DebugMeshCallback buffer);
+}
diff --git a/engine/src/bullet/com/jme3/bullet/util/NativeMeshUtil.java b/engine/src/bullet/com/jme3/bullet/util/NativeMeshUtil.java
new file mode 100644
index 000000000..d1950ffc6
--- /dev/null
+++ b/engine/src/bullet/com/jme3/bullet/util/NativeMeshUtil.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.bullet.util;
+
+import com.jme3.scene.Mesh;
+import com.jme3.scene.VertexBuffer.Type;
+import com.jme3.scene.mesh.IndexBuffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class NativeMeshUtil {
+
+ public static long getTriangleIndexVertexArray(Mesh mesh){
+ ByteBuffer triangleIndexBase = ByteBuffer.allocateDirect(mesh.getTriangleCount() * 3 * 4).order(ByteOrder.nativeOrder());
+ ByteBuffer vertexBase = ByteBuffer.allocateDirect(mesh.getVertexCount() * 3 * 4).order(ByteOrder.nativeOrder());
+ int numVertices = mesh.getVertexCount();
+ int vertexStride = 12; //3 verts * 4 bytes per.
+ int numTriangles = mesh.getTriangleCount();
+ int triangleIndexStride = 12; //3 index entries * 4 bytes each.
+
+ IndexBuffer indices = mesh.getIndexBuffer();
+ FloatBuffer vertices = mesh.getFloatBuffer(Type.Position);
+ vertices.rewind();
+
+ int verticesLength = mesh.getVertexCount() * 3;
+ for (int i = 0; i < verticesLength; i++) {
+ float tempFloat = vertices.get();
+ vertexBase.putFloat(tempFloat);
+ }
+
+ int indicesLength = mesh.getTriangleCount() * 3;
+ for (int i = 0; i < indicesLength; i++) {
+ triangleIndexBase.putInt(indices.get(i));
+ }
+ vertices.rewind();
+ vertices.clear();
+
+ return createTriangleIndexVertexArray(triangleIndexBase, vertexBase, numTriangles, numVertices, vertexStride, triangleIndexStride);
+ }
+
+ public static native long createTriangleIndexVertexArray(ByteBuffer triangleIndexBase, ByteBuffer vertexBase, int numTraingles, int numVertices, int vertextStride, int triangleIndexStride);
+
+}
diff --git a/engine/src/bullet/native/build.xml b/engine/src/bullet/native/build.xml
new file mode 100644
index 000000000..b5583a509
--- /dev/null
+++ b/engine/src/bullet/native/build.xml
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/engine/src/bullet/native/bullet-native-build.txt b/engine/src/bullet/native/bullet-native-build.txt
new file mode 100644
index 000000000..5fcb778eb
--- /dev/null
+++ b/engine/src/bullet/native/bullet-native-build.txt
@@ -0,0 +1,174 @@
+***********************************
+* Build info for bulletjme *
+* (c) 2011 Normen Hansen *
+***********************************
+
+This document outlines the process of building bullet-jme on different platforms.
+Since bullet-jme is a native java library and bullet gets included statically,
+building requires you to download and build the bullet source first.
+
+
+
+***********************************
+* Building bullet *
+***********************************
+
+-----------------------------------
+General info
+-----------------------------------
+Note that the compilation of bullet should not produce dll / so / dylib files
+but static *.a libraries which can later be compiled into the binary of bullet-jme.
+
+-----------------------------------
+Downloading and extracting bullet
+-----------------------------------
+Requirements:
+- Bullet source: http://bullet.googlecode.com/
+
+Extract bullet source and build bullet (see below)
+
+-----------------------------------
+Building on Mac OSX
+-----------------------------------
+Requirements:
+- Apple Developer tools: http://developer.apple.com/
+- CMake: http://www.cmake.org/ (or via http://www.macports.org)
+
+Commands:
+> cd bullet-trunk
+> cmake -DBUILD_SHARED_LIBS=OFF -DBUILD_STATIC_LIBS=ON \
+ -DCMAKE_OSX_ARCHITECTURES='ppc;i386;x86_64' \
+ -DBUILD_EXTRAS=off -DBUILD_DEMOS=off -DCMAKE_BUILD_TYPE=Release
+> make
+
+-----------------------------------
+Building on WINDOWS (MinGW/GCC, Recommended)
+-----------------------------------
+Requirements:
+- GNU C++ Compiler: http://www.mingw.org/
+ http://mingw-w64.sourceforge.net/
+- CMake: http://www.cmake.org/
+
+Commands:
+> cd bullet-trunk
+> cmake . -DBUILD_SHARED_LIBS=OFF -DBUILD_DEMOS:BOOL=OFF -DBUILD_EXTRAS:BOOL=OFF -DCMAKE_BUILD_TYPE=Release . -G "MinGW Makefiles"
+> mingw32-make
+
+-----------------------------------
+Building on WINDOWS (VisualStudio, untested)
+-----------------------------------
+Requirements:
+- Microsoft Visual Studio http://msdn.microsoft.com/
+
+Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8.
+The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version).
+
+Build the project to create static libraries.
+
+
+-----------------------------------
+Building bullet on LINUX
+-----------------------------------
+Requirements:
+- Gnu C++ Compiler: http://gcc.gnu.org/
+- CMake: http://www.cmake.org/ (or via your package manager of choice)
+
+On Linux, I had to remove two lines from bullet-2.77/src/BulletMultiThreaded/CMakeLists.txt
+to compile correctly:
+ SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.cpp
+ SpuNarrowPhaseCollisionTask/SpuMinkowskiPenetrationDepthSolver.h
+
+Commands:
+> cd bullet-trunk
+> cmake -DBUILD_SHARED_LIBS=OFF -DBUILD_STATIC_LIBS=ON -DCMAKE_C_FLAGS="-fPIC" -DCMAKE_CXX_FLAGS="-fPIC"\
+ -DBUILD_EXTRAS=off -DBUILD_DEMOS=off -DCMAKE_BUILD_TYPE=Release
+> make
+
+-----------------------------------
+More info on building bullet
+-----------------------------------
+http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Installation
+
+
+
+***********************************
+* Building bulletjme *
+***********************************
+
+-----------------------------------
+Requirements
+-----------------------------------
+- Java SDK 1.5+: http://java.sun.com
+- Apache ANT: http://ant.apache.org
+- C++ Compiler: (see below)
+- jme3 Source: http://jmonkeyengine.googlecode.com/
+- Statically compiled bullet source (see above)
+
+-----------------------------------
+Preparation
+-----------------------------------
+- copy/link bullet-trunk folder into the same folder where the bullet-jme folder is:
+
+disk
+ |
+ +-root folder
+ |
+ +-engine
+ |
+ +-sdk
+ |
+ +-bullet-trunk
+
+- You can alter options in the "src/bullet/native/bullet.properties" file, such as the used bullet
+ version, native compilation options etc. (see below)
+
+-----------------------------------
+Building bulletjme native
+-----------------------------------
+Commands:
+> cd engine
+> ant jar
+> ant build-bullet-natives
+
+Thats all. ANT takes care building native binaries and copies them to th elib directory.
+
+If you get compilation errors, try setting "native.java.include" in the build.properties file to your
+JDK include directory, e.g. /opt/java/include or "c:\Program Files\Java\jdk1.6.0_20\include".
+
+-----------------------------------
+Altering the native build process
+-----------------------------------
+bullet-jme uses cpptasks to compile native code.
+
+To change the used compiler, edit the "native.platform.compiler" entry in the
+"build.properties" file. The following c++ compilers work with cpptasks:
+
+gcc GCC C++ compiler
+g++ GCC C++ compiler
+c++ GCC C++ compiler
+msvc Microsoft Visual C++
+bcc Borland C++ Compiler
+icl Intel C++ compiler for Windows (IA-32)
+ecl Intel C++ compiler for Windows (IA-64)
+icc Intel C++ compiler for Linux (IA-32)
+ecc Intel C++ compiler for Linux (IA-64)
+CC Sun ONE C++ compiler
+aCC HP aC++ C++ Compiler
+wcl OpenWatcom C/C++ compiler
+
+In the "nbproject" folder you can find "build-native-platform.xml" files containing the commands
+to compile bullet-jme on different platforms. If you want to alter the process,
+you can copy and modify one of the files and import it in the "build.xml" file instead
+of the old one.
+
+-----------------------------------
+Netbeans Project
+-----------------------------------
+The project also includes a Netbeans project to edit and build
+the source in the Netbeans IDE.
+
+To have correct syntax highlighting in .cpp/.h files:
+
+- in Netbeans Settings -> C/C++ -> Code Assistance -> C++
+ - add bullet-2.77/src as include directories for c++
+ - add JAVA_HOME/include as include directories for c++
diff --git a/engine/src/bullet/native/bullet.properties b/engine/src/bullet/native/bullet.properties
new file mode 100644
index 000000000..ca8c444b0
--- /dev/null
+++ b/engine/src/bullet/native/bullet.properties
@@ -0,0 +1,32 @@
+#####################################################
+# these are the ant build properties for bullet-jme #
+#####################################################
+bullet.library.name=bulletjme
+bullet.library.version=0.9
+
+# change if bullet folder has different location
+bullet.folder=../bullet-trunk
+
+# compile options
+bullet.compile.debug=false
+
+# native library compilation options
+bullet.osx.compiler=g++
+bullet.osx.syslibroot=/Developer/SDKs/MacOSX10.5.sdk
+# change this to msvc for MS Visual Studio compiler
+bullet.windows.compiler=g++
+bullet.linux.compiler=g++
+
+# native header include directories
+bullet.java.include=${java.home}/../include
+# OSX has no JRE, only JDK
+bullet.osx.java.include=${java.home}/include
+
+# dont change these..
+bullet.bullet.include=${bullet.folder}/src
+bullet.build.dir=build/bullet/
+bullet.source.dir=src/bullet/native
+bullet.output.base=lib/bullet
+bullet.output.dir=${bullet.output.base}/jarcontent/native
+bullet.jme.dir=dist
+bullet.lib.dir=dist/lib
diff --git a/engine/src/bullet/native/com_jme3_bullet_PhysicsSpace.cpp b/engine/src/bullet/native/com_jme3_bullet_PhysicsSpace.cpp
new file mode 100644
index 000000000..21f0abc83
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_PhysicsSpace.cpp
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "com_jme3_bullet_PhysicsSpace.h"
+#include "jmePhysicsSpace.h"
+#include "jmeBulletUtil.h"
+
+/**
+ * Author: Normen Hansen
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: createPhysicsSpace
+ * Signature: (FFFFFFI)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_PhysicsSpace_createPhysicsSpace
+ (JNIEnv * env, jobject object, jfloat minX, jfloat minY, jfloat minZ, jfloat maxX, jfloat maxY, jfloat maxZ, jint broadphase, jboolean threading) {
+ jmePhysicsSpace* space = new jmePhysicsSpace(env, object);
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space has not been created.");
+ return 0;
+ }
+ space->createPhysicsSpace(minX, minY, minZ, maxX, maxY, maxZ, broadphase, threading);
+ return (long) space;
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: stepSimulation
+ * Signature: (JFIF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_stepSimulation
+ (JNIEnv * env, jobject object, jlong spaceId, jfloat tpf, jint maxSteps, jfloat accuracy) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ space->stepSimulation(tpf, maxSteps, accuracy);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addCollisionObject
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addCollisionObject
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btCollisionObject* collisionObject = (btCollisionObject*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (collisionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The collision object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->addCollisionObject(collisionObject);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeCollisionObject
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeCollisionObject
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btCollisionObject* collisionObject = (btCollisionObject*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (collisionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The collision object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->removeCollisionObject(collisionObject);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addRigidBody
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addRigidBody
+ (JNIEnv * env, jobject object, jlong spaceId, jlong rigidBodyId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btRigidBody* collisionObject = (btRigidBody*) rigidBodyId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (collisionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The collision object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->addRigidBody(collisionObject);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeRigidBody
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeRigidBody
+ (JNIEnv * env, jobject object, jlong spaceId, jlong rigidBodyId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btRigidBody* collisionObject = (btRigidBody*) rigidBodyId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (collisionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The collision object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->removeRigidBody(collisionObject);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addCharacterObject
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addCharacterObject
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btCollisionObject* collisionObject = (btCollisionObject*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (collisionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The collision object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->addCollisionObject(collisionObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeCharacterObject
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeCharacterObject
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btCollisionObject* collisionObject = (btCollisionObject*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (collisionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The collision object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->removeCollisionObject(collisionObject);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addAction
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addAction
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btActionInterface* actionObject = (btActionInterface*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (actionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The action object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->addAction(actionObject);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeAction
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeAction
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btActionInterface* actionObject = (btActionInterface*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (actionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The action object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->removeAction(actionObject);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addVehicle
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addVehicle
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btActionInterface* actionObject = (btActionInterface*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (actionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The vehicle object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->addVehicle(actionObject);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeVehicle
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeVehicle
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btActionInterface* actionObject = (btActionInterface*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (actionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The action object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->removeVehicle(actionObject);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addConstraint
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addConstraint
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btTypedConstraint* constraint = (btTypedConstraint*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (constraint == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The constraint object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->addConstraint(constraint);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeConstraint
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeConstraint
+ (JNIEnv * env, jobject object, jlong spaceId, jlong objectId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ btTypedConstraint* constraint = (btTypedConstraint*) objectId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ if (constraint == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The constraint object does not exist.");
+ return;
+ }
+ space->getDynamicsWorld()->removeConstraint(constraint);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: setGravity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_setGravity
+ (JNIEnv * env, jobject object, jlong spaceId, jobject vector) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ if (space == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The physics space does not exist.");
+ return;
+ }
+ btVector3* gravity = &btVector3();
+ jmeBulletUtil::convert(env, vector, gravity);
+ space->getDynamicsWorld()->setGravity(*gravity);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: initNativePhysics
+ * Signature: ()V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_initNativePhysics
+ (JNIEnv * env, jclass clazz) {
+ jmeClasses::initJavaClasses(env);
+ }
+
+ /*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_finalizeNative
+ (JNIEnv * env, jobject object, jlong spaceId) {
+ jmePhysicsSpace* space = (jmePhysicsSpace*) spaceId;
+ delete(space);
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_PhysicsSpace.h b/engine/src/bullet/native/com_jme3_bullet_PhysicsSpace.h
new file mode 100644
index 000000000..8dd476cf0
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_PhysicsSpace.h
@@ -0,0 +1,157 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_PhysicsSpace */
+
+#ifndef _Included_com_jme3_bullet_PhysicsSpace
+#define _Included_com_jme3_bullet_PhysicsSpace
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_jme3_bullet_PhysicsSpace_AXIS_X
+#define com_jme3_bullet_PhysicsSpace_AXIS_X 0L
+#undef com_jme3_bullet_PhysicsSpace_AXIS_Y
+#define com_jme3_bullet_PhysicsSpace_AXIS_Y 1L
+#undef com_jme3_bullet_PhysicsSpace_AXIS_Z
+#define com_jme3_bullet_PhysicsSpace_AXIS_Z 2L
+/* Inaccessible static: pQueueTL */
+/* Inaccessible static: physicsSpaceTL */
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: createPhysicsSpace
+ * Signature: (FFFFFFIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_PhysicsSpace_createPhysicsSpace
+ (JNIEnv *, jobject, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jint, jboolean);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: stepSimulation
+ * Signature: (JFIF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_stepSimulation
+ (JNIEnv *, jobject, jlong, jfloat, jint, jfloat);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addCollisionObject
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addCollisionObject
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeCollisionObject
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeCollisionObject
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addRigidBody
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addRigidBody
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeRigidBody
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeRigidBody
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addCharacterObject
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addCharacterObject
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeCharacterObject
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeCharacterObject
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addAction
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addAction
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeAction
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeAction
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addVehicle
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addVehicle
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeVehicle
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeVehicle
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: addConstraint
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addConstraint
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: removeConstraint
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_removeConstraint
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: setGravity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_setGravity
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: initNativePhysics
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_initNativePhysics
+ (JNIEnv *, jclass);
+
+/*
+ * Class: com_jme3_bullet_PhysicsSpace
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_finalizeNative
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_PhysicsCollisionObject.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_PhysicsCollisionObject.cpp
new file mode 100644
index 000000000..db9594be3
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_PhysicsCollisionObject.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_PhysicsCollisionObject.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_PhysicsCollisionObject
+ * Method: attachCollisionShape
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_PhysicsCollisionObject_attachCollisionShape
+ (JNIEnv * env, jobject object, jlong objectId, jlong shapeId) {
+ btCollisionObject* collisionObject = (btCollisionObject*) objectId;
+ if (collisionObject == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The collision object does not exist.");
+ return;
+ }
+ btCollisionShape* collisionShape = (btCollisionShape*) shapeId;
+ if (collisionShape == NULL) {
+ jclass newExc = env->FindClass("java/lang/IllegalStateException");
+ env->ThrowNew(newExc, "The collision shape does not exist.");
+ return;
+ }
+ collisionObject->setCollisionShape(collisionShape);
+ }
+
+ /*
+ * Class: com_jme3_bullet_collision_PhysicsCollisionObject
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_PhysicsCollisionObject_finalizeNative
+ (JNIEnv * env, jobject object, jlong objectId) {
+ btCollisionObject* collisionObject = (btCollisionObject*) objectId;
+ delete(collisionObject);
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_PhysicsCollisionObject.h b/engine/src/bullet/native/com_jme3_bullet_collision_PhysicsCollisionObject.h
new file mode 100644
index 000000000..955c7e31c
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_PhysicsCollisionObject.h
@@ -0,0 +1,63 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_PhysicsCollisionObject */
+
+#ifndef _Included_com_jme3_bullet_collision_PhysicsCollisionObject
+#define _Included_com_jme3_bullet_collision_PhysicsCollisionObject
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_NONE
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_NONE 0L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_01
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_01 1L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_02
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_02 2L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_03
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_03 4L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_04
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_04 8L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_05
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_05 16L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_06
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_06 32L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_07
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_07 64L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_08
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_08 128L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_09
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_09 256L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_10
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_10 512L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_11
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_11 1024L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_12
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_12 2048L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_13
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_13 4096L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_14
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_14 8192L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_15
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_15 16384L
+#undef com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_16
+#define com_jme3_bullet_collision_PhysicsCollisionObject_COLLISION_GROUP_16 32768L
+/*
+ * Class: com_jme3_bullet_collision_PhysicsCollisionObject
+ * Method: attachCollisionShape
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_PhysicsCollisionObject_attachCollisionShape
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_collision_PhysicsCollisionObject
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_PhysicsCollisionObject_finalizeNative
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_BoxCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_BoxCollisionShape.cpp
new file mode 100644
index 000000000..a415e6a5d
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_BoxCollisionShape.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_BoxCollisionShape.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_BoxCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_BoxCollisionShape_createShape
+ (JNIEnv *env, jobject object, jobject halfExtents) {
+ btVector3* extents = &btVector3();
+ jmeBulletUtil::convert(env, halfExtents, extents);
+ btBoxShape* shape = new btBoxShape(*extents);
+ return (long)shape;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_BoxCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_BoxCollisionShape.h
new file mode 100644
index 000000000..5602a0dd3
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_BoxCollisionShape.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_BoxCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_BoxCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_BoxCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_BoxCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_BoxCollisionShape_createShape
+ (JNIEnv *, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CapsuleCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CapsuleCollisionShape.cpp
new file mode 100644
index 000000000..7f7d70b05
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CapsuleCollisionShape.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_CapsuleCollisionShape.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_CapsuleCollisionShape
+ * Method: createShape
+ * Signature: (IFF)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CapsuleCollisionShape_createShape
+ (JNIEnv * env, jobject object, jint axis, jfloat radius, jfloat height) {
+ btCollisionShape* shape;
+ switch(axis){
+ case 0:
+ shape = new btCapsuleShapeX(radius, height);
+ break;
+ case 1:
+ shape = new btCapsuleShape(radius, height);
+ break;
+ case 2:
+ shape = new btCapsuleShapeZ(radius, height);
+ break;
+ }
+ return (long) shape;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CapsuleCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CapsuleCollisionShape.h
new file mode 100644
index 000000000..4d706748d
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CapsuleCollisionShape.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_CapsuleCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_CapsuleCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_CapsuleCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_CapsuleCollisionShape
+ * Method: createShape
+ * Signature: (IFF)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CapsuleCollisionShape_createShape
+ (JNIEnv *, jobject, jint, jfloat, jfloat);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CollisionShape.cpp
new file mode 100644
index 000000000..bdf594b46
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CollisionShape.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_CollisionShape.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_CollisionShape
+ * Method: getMargin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_collision_shapes_CollisionShape_getMargin
+ (JNIEnv * env, jobject object, jlong shapeId) {
+ btCollisionShape* shape = (btCollisionShape*) shapeId;
+ return shape->getMargin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_CollisionShape
+ * Method: setLocalScaling
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_CollisionShape_setLocalScaling
+ (JNIEnv * env, jobject object, jlong shapeId, jobject scale) {
+ btCollisionShape* shape = (btCollisionShape*) shapeId;
+ btVector3* scl = &btVector3();
+ jmeBulletUtil::convert(env, scale, scl);
+ shape->setLocalScaling(*scl);
+ }
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_CollisionShape
+ * Method: setMargin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_CollisionShape_setMargin
+ (JNIEnv * env, jobject object, jlong shapeId, jfloat newMargin) {
+ btCollisionShape* shape = (btCollisionShape*) shapeId;
+ shape->setMargin(newMargin);
+ }
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_CollisionShape
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_CollisionShape_finalizeNative
+ (JNIEnv * env, jobject object, jlong shapeId) {
+ btCollisionShape* shape = (btCollisionShape*) shapeId;
+ delete(shape);
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CollisionShape.h
new file mode 100644
index 000000000..cd5d70f21
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CollisionShape.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_CollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_CollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_CollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_CollisionShape
+ * Method: getMargin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_collision_shapes_CollisionShape_getMargin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_CollisionShape
+ * Method: setLocalScaling
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_CollisionShape_setLocalScaling
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_CollisionShape
+ * Method: setMargin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_CollisionShape_setMargin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_CollisionShape
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_CollisionShape_finalizeNative
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CompoundCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CompoundCollisionShape.cpp
new file mode 100644
index 000000000..b3383789f
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CompoundCollisionShape.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_CompoundCollisionShape.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_CompoundCollisionShape
+ * Method: createShape
+ * Signature: ()J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CompoundCollisionShape_createShape
+ (JNIEnv *env, jobject object) {
+ btCompoundShape* shape = new btCompoundShape();
+ return (long) shape;
+ }
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_CompoundCollisionShape
+ * Method: addChildShape
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CompoundCollisionShape_addChildShape
+ (JNIEnv *env, jobject object, jlong compoundId, jlong childId, jobject childLocation, jobject childRotation) {
+ btCompoundShape* shape = (btCompoundShape*) compoundId;
+ btCollisionShape* child = (btCollisionShape*) childId;
+ btMatrix3x3* mtx = &btMatrix3x3();
+ btTransform* trans = &btTransform(*mtx);
+ jmeBulletUtil::convert(env, childLocation, &trans->getOrigin());
+ jmeBulletUtil::convert(env, childRotation, &trans->getBasis());
+ shape->addChildShape(*trans, child);
+ return 0;
+ }
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_CompoundCollisionShape
+ * Method: removeChildShape
+ * Signature: (JJ)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CompoundCollisionShape_removeChildShape
+ (JNIEnv * env, jobject object, jlong compoundId, jlong childId) {
+ btCompoundShape* shape = (btCompoundShape*) compoundId;
+ btCollisionShape* child = (btCollisionShape*) childId;
+ shape->removeChildShape(child);
+ return 0;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CompoundCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CompoundCollisionShape.h
new file mode 100644
index 000000000..18783ce1d
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CompoundCollisionShape.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_CompoundCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_CompoundCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_CompoundCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_CompoundCollisionShape
+ * Method: createShape
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CompoundCollisionShape_createShape
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_CompoundCollisionShape
+ * Method: addChildShape
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CompoundCollisionShape_addChildShape
+ (JNIEnv *, jobject, jlong, jlong, jobject, jobject);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_CompoundCollisionShape
+ * Method: removeChildShape
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CompoundCollisionShape_removeChildShape
+ (JNIEnv *, jobject, jlong, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_ConeCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_ConeCollisionShape.cpp
new file mode 100644
index 000000000..3a2b9dad0
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_ConeCollisionShape.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_ConeCollisionShape.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_ConeCollisionShape
+ * Method: createShape
+ * Signature: (IFF)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_ConeCollisionShape_createShape
+ (JNIEnv * env, jobject object, jint axis, jfloat radius, jfloat height) {
+ btCollisionShape* shape;
+ switch (axis) {
+ case 0:
+ shape = new btConeShapeX(radius, height);
+ break;
+ case 1:
+ shape = new btConeShape(radius, height);
+ break;
+ case 2:
+ shape = new btConeShapeZ(radius, height);
+ break;
+ }
+ return (long) shape;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_ConeCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_ConeCollisionShape.h
new file mode 100644
index 000000000..711276ebb
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_ConeCollisionShape.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_ConeCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_ConeCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_ConeCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_ConeCollisionShape
+ * Method: createShape
+ * Signature: (IFF)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_ConeCollisionShape_createShape
+ (JNIEnv *, jobject, jint, jfloat, jfloat);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CylinderCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CylinderCollisionShape.cpp
new file mode 100644
index 000000000..a7c52fdc0
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CylinderCollisionShape.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_CylinderCollisionShape.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_CylinderCollisionShape
+ * Method: createShape
+ * Signature: (ILcom/jme3/math/Vector3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CylinderCollisionShape_createShape
+ (JNIEnv * env, jobject object, jint axis, jobject halfExtents) {
+ btVector3* extents = &btVector3();
+ jmeBulletUtil::convert(env, halfExtents, extents);
+ btCollisionShape* shape;
+ switch (axis) {
+ case 0:
+ shape = new btCylinderShapeX(*extents);
+ break;
+ case 1:
+ shape = new btCylinderShape(*extents);
+ break;
+ case 2:
+ shape = new btCylinderShapeZ(*extents);
+ break;
+ }
+ return (long) shape;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CylinderCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CylinderCollisionShape.h
new file mode 100644
index 000000000..48a665ac7
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_CylinderCollisionShape.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_CylinderCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_CylinderCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_CylinderCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_CylinderCollisionShape
+ * Method: createShape
+ * Signature: (ILcom/jme3/math/Vector3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_CylinderCollisionShape_createShape
+ (JNIEnv *, jobject, jint, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_GImpactCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_GImpactCollisionShape.cpp
new file mode 100644
index 000000000..68c7ff532
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_GImpactCollisionShape.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_GImpactCollisionShape.h"
+#include "jmeBulletUtil.h"
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_GImpactCollisionShape
+ * Method: createShape
+ * Signature: (J)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_GImpactCollisionShape_createShape
+ (JNIEnv * env, jobject object, jlong meshId) {
+ btTriangleIndexVertexArray* array = (btTriangleIndexVertexArray*) meshId;
+ btGImpactMeshShape* shape = new btGImpactMeshShape(array);
+ return (long) shape;
+ }
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_GImpactCollisionShape
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_GImpactCollisionShape_finalizeNative
+ (JNIEnv * env, jobject object, jlong meshId) {
+ btTriangleIndexVertexArray* array = (btTriangleIndexVertexArray*) meshId;
+ delete(array);
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_GImpactCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_GImpactCollisionShape.h
new file mode 100644
index 000000000..f08d3ebf8
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_GImpactCollisionShape.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_GImpactCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_GImpactCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_GImpactCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_GImpactCollisionShape
+ * Method: createShape
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_GImpactCollisionShape_createShape
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_GImpactCollisionShape
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_GImpactCollisionShape_finalizeNative
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HeightfieldCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HeightfieldCollisionShape.cpp
new file mode 100644
index 000000000..3946195ce
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HeightfieldCollisionShape.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_HeightfieldCollisionShape.h"
+#include "jmeBulletUtil.h"
+#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_HeightfieldCollisionShape
+ * Method: createShape
+ * Signature: (II[FFFFIZ)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_HeightfieldCollisionShape_createShape
+ (JNIEnv * env, jobject object, jint heightStickWidth, jint heightStickLength, jobject heightfieldData, jfloat heightScale, jfloat minHeight, jfloat maxHeight, jint upAxis, jboolean flipQuadEdges) {
+ void* data = env->GetDirectBufferAddress(heightfieldData);
+ btHeightfieldTerrainShape* shape=new btHeightfieldTerrainShape(heightStickWidth, heightStickLength, data, heightScale, minHeight, maxHeight, upAxis, PHY_FLOAT, flipQuadEdges);
+ return (long)shape;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HeightfieldCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HeightfieldCollisionShape.h
new file mode 100644
index 000000000..a3d1621b8
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HeightfieldCollisionShape.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_HeightfieldCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_HeightfieldCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_HeightfieldCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_HeightfieldCollisionShape
+ * Method: createShape
+ * Signature: (IILjava/nio/ByteBuffer;FFFIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_HeightfieldCollisionShape_createShape
+ (JNIEnv *, jobject, jint, jint, jobject, jfloat, jfloat, jfloat, jint, jboolean);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HullCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HullCollisionShape.cpp
new file mode 100644
index 000000000..f2ea8b01d
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HullCollisionShape.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_HullCollisionShape.h"
+#include "jmeBulletUtil.h"
+#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_HullCollisionShape
+ * Method: createShape
+ * Signature: ([F)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_HullCollisionShape_createShape
+ (JNIEnv *env, jobject object, jobject array) {
+ float* data = (float*) env->GetDirectBufferAddress(array);
+ //TODO: capacity will not always be length!
+ int length = env->GetDirectBufferCapacity(array)/4;
+ btConvexHullShape* shape = new btConvexHullShape();
+ for (int i = 0; i < length; i+=3) {
+ btVector3 vect = btVector3(data[i],
+ data[i + 1],
+ data[i + 2]);
+
+ shape->addPoint(vect);
+ }
+
+ return (long) shape;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HullCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HullCollisionShape.h
new file mode 100644
index 000000000..42a267216
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_HullCollisionShape.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_HullCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_HullCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_HullCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_HullCollisionShape
+ * Method: createShape
+ * Signature: (Ljava/nio/ByteBuffer;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_HullCollisionShape_createShape
+ (JNIEnv *, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_MeshCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_MeshCollisionShape.cpp
new file mode 100644
index 000000000..3534a1589
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_MeshCollisionShape.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_MeshCollisionShape.h"
+#include "jmeBulletUtil.h"
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_MeshCollisionShape
+ * Method: createShape
+ * Signature: (J)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_MeshCollisionShape_createShape
+ (JNIEnv * env, jobject object, jlong arrayId) {
+ btTriangleIndexVertexArray* array = (btTriangleIndexVertexArray*) arrayId;
+ btBvhTriangleMeshShape* shape = new btBvhTriangleMeshShape(array, true, true);
+ return (long) shape;
+ }
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_MeshCollisionShape
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_MeshCollisionShape_finalizeNative
+ (JNIEnv * env, jobject object, jlong arrayId){
+ btTriangleIndexVertexArray* array = (btTriangleIndexVertexArray*) arrayId;
+ delete(array);
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_MeshCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_MeshCollisionShape.h
new file mode 100644
index 000000000..4dd6aa28a
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_MeshCollisionShape.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_MeshCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_MeshCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_MeshCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_MeshCollisionShape
+ * Method: createShape
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_MeshCollisionShape_createShape
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_MeshCollisionShape
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_collision_shapes_MeshCollisionShape_finalizeNative
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_PlaneCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_PlaneCollisionShape.cpp
new file mode 100644
index 000000000..08b9dcf33
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_PlaneCollisionShape.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_PlaneCollisionShape.h"
+#include "jmeBulletUtil.h"
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_PlaneCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;F)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_PlaneCollisionShape_createShape
+ (JNIEnv * env, jobject object, jobject normal, jfloat constant) {
+ btVector3* norm = &btVector3();
+ jmeBulletUtil::convert(env, normal, norm);
+ btStaticPlaneShape* shape = new btStaticPlaneShape(*norm, constant);
+ return (long)shape;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_PlaneCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_PlaneCollisionShape.h
new file mode 100644
index 000000000..7e7a22bdf
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_PlaneCollisionShape.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_PlaneCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_PlaneCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_PlaneCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_PlaneCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;F)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_PlaneCollisionShape_createShape
+ (JNIEnv *, jobject, jobject, jfloat);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SimplexCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SimplexCollisionShape.cpp
new file mode 100644
index 000000000..30fe8233d
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SimplexCollisionShape.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_SimplexCollisionShape.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_SimplexCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SimplexCollisionShape_createShape__Lcom_jme3_math_Vector3f_2
+ (JNIEnv *env, jobject object, jobject vector1) {
+ btVector3* vec1 = &btVector3();
+ jmeBulletUtil::convert(env, vector1, vec1);
+ btBU_Simplex1to4* simplexShape = new btBU_Simplex1to4(*vec1);
+ return (long) simplexShape;
+ }
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_SimplexCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SimplexCollisionShape_createShape__Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2
+ (JNIEnv *env, jobject object, jobject vector1, jobject vector2) {
+ btVector3* vec1 = &btVector3();
+ jmeBulletUtil::convert(env, vector1, vec1);
+ btVector3* vec2 = &btVector3();
+ jmeBulletUtil::convert(env, vector2, vec2);
+ btBU_Simplex1to4* simplexShape = new btBU_Simplex1to4(*vec1, *vec2);
+ return (long) simplexShape;
+ }
+ /*
+ * Class: com_jme3_bullet_collision_shapes_SimplexCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SimplexCollisionShape_createShape__Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2
+ (JNIEnv * env, jobject object, jobject vector1, jobject vector2, jobject vector3) {
+ btVector3* vec1 = &btVector3();
+ jmeBulletUtil::convert(env, vector1, vec1);
+ btVector3* vec2 = &btVector3();
+ jmeBulletUtil::convert(env, vector2, vec2);
+ btVector3* vec3 = &btVector3();
+ jmeBulletUtil::convert(env, vector3, vec3);
+ btBU_Simplex1to4* simplexShape = new btBU_Simplex1to4(*vec1, *vec2, *vec3);
+ return (long) simplexShape;
+ }
+ /*
+ * Class: com_jme3_bullet_collision_shapes_SimplexCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SimplexCollisionShape_createShape__Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2
+ (JNIEnv * env, jobject object, jobject vector1, jobject vector2, jobject vector3, jobject vector4) {
+ btVector3* vec1 = &btVector3();
+ jmeBulletUtil::convert(env, vector1, vec1);
+ btVector3* vec2 = &btVector3();
+ jmeBulletUtil::convert(env, vector2, vec2);
+ btVector3* vec3 = &btVector3();
+ jmeBulletUtil::convert(env, vector3, vec3);
+ btVector3* vec4 = &btVector3();
+ jmeBulletUtil::convert(env, vector4, vec4);
+ btBU_Simplex1to4* simplexShape = new btBU_Simplex1to4(*vec1, *vec2, *vec3, *vec4);
+ return (long) simplexShape;
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SimplexCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SimplexCollisionShape.h
new file mode 100644
index 000000000..e50d06226
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SimplexCollisionShape.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_SimplexCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_SimplexCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_SimplexCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_SimplexCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SimplexCollisionShape_createShape__Lcom_jme3_math_Vector3f_2
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_SimplexCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SimplexCollisionShape_createShape__Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2
+ (JNIEnv *, jobject, jobject, jobject);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_SimplexCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SimplexCollisionShape_createShape__Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2
+ (JNIEnv *, jobject, jobject, jobject, jobject);
+
+/*
+ * Class: com_jme3_bullet_collision_shapes_SimplexCollisionShape
+ * Method: createShape
+ * Signature: (Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SimplexCollisionShape_createShape__Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2Lcom_jme3_math_Vector3f_2
+ (JNIEnv *, jobject, jobject, jobject, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SphereCollisionShape.cpp b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SphereCollisionShape.cpp
new file mode 100644
index 000000000..c896cda3a
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SphereCollisionShape.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_collision_shapes_SphereCollisionShape.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_collision_shapes_SphereCollisionShape
+ * Method: createShape
+ * Signature: (F)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SphereCollisionShape_createShape
+ (JNIEnv *env, jobject object, jfloat radius) {
+ btSphereShape* shape=new btSphereShape(radius);
+ return (long)shape;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SphereCollisionShape.h b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SphereCollisionShape.h
new file mode 100644
index 000000000..ef1b2cbed
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_collision_shapes_SphereCollisionShape.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_collision_shapes_SphereCollisionShape */
+
+#ifndef _Included_com_jme3_bullet_collision_shapes_SphereCollisionShape
+#define _Included_com_jme3_bullet_collision_shapes_SphereCollisionShape
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_collision_shapes_SphereCollisionShape
+ * Method: createShape
+ * Signature: (F)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_collision_shapes_SphereCollisionShape_createShape
+ (JNIEnv *, jobject, jfloat);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_ConeJoint.cpp b/engine/src/bullet/native/com_jme3_bullet_joints_ConeJoint.cpp
new file mode 100644
index 000000000..a7755fac9
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_ConeJoint.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_joints_ConeJoint.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_joints_ConeJoint
+ * Method: setLimit
+ * Signature: (JFFF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_ConeJoint_setLimit
+ (JNIEnv * env, jobject object, jlong jointId, jfloat swingSpan1, jfloat swingSpan2, jfloat twistSpan) {
+ btConeTwistConstraint* joint = (btConeTwistConstraint*) jointId;
+ //TODO: extended setLimit!
+ joint->setLimit(swingSpan1, swingSpan2, twistSpan);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_ConeJoint
+ * Method: setAngularOnly
+ * Signature: (JZ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_ConeJoint_setAngularOnly
+ (JNIEnv * env, jobject object, jlong jointId, jboolean angularOnly) {
+ btConeTwistConstraint* joint = (btConeTwistConstraint*) jointId;
+ joint->setAngularOnly(angularOnly);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_ConeJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_ConeJoint_createJoint
+ (JNIEnv * env, jobject object, jlong bodyIdA, jlong bodyIdB, jobject pivotA, jobject rotA, jobject pivotB, jobject rotB) {
+ btRigidBody* bodyA = (btRigidBody*) bodyIdA;
+ btRigidBody* bodyB = (btRigidBody*) bodyIdB;
+ btMatrix3x3* mtx1 = &btMatrix3x3();
+ btMatrix3x3* mtx2 = &btMatrix3x3();
+ btTransform* transA = &btTransform(*mtx1);
+ jmeBulletUtil::convert(env, pivotA, &transA->getOrigin());
+ jmeBulletUtil::convert(env, rotA, &transA->getBasis());
+ btTransform* transB = &btTransform(*mtx2);
+ jmeBulletUtil::convert(env, pivotB, &transB->getOrigin());
+ jmeBulletUtil::convert(env, rotB, &transB->getBasis());
+ btConeTwistConstraint* joint = new btConeTwistConstraint(*bodyA, *bodyB, *transA, *transB);
+ return (long) joint;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_ConeJoint.h b/engine/src/bullet/native/com_jme3_bullet_joints_ConeJoint.h
new file mode 100644
index 000000000..327b47f25
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_ConeJoint.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_joints_ConeJoint */
+
+#ifndef _Included_com_jme3_bullet_joints_ConeJoint
+#define _Included_com_jme3_bullet_joints_ConeJoint
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_joints_ConeJoint
+ * Method: setLimit
+ * Signature: (JFFF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_ConeJoint_setLimit
+ (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_ConeJoint
+ * Method: setAngularOnly
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_ConeJoint_setAngularOnly
+ (JNIEnv *, jobject, jlong, jboolean);
+
+/*
+ * Class: com_jme3_bullet_joints_ConeJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_ConeJoint_createJoint
+ (JNIEnv *, jobject, jlong, jlong, jobject, jobject, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_HingeJoint.cpp b/engine/src/bullet/native/com_jme3_bullet_joints_HingeJoint.cpp
new file mode 100644
index 000000000..7dd5d426a
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_HingeJoint.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_joints_HingeJoint.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: enableMotor
+ * Signature: (JZFF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_HingeJoint_enableMotor
+ (JNIEnv * env, jobject object, jlong jointId, jboolean enable, jfloat targetVelocity, jfloat maxMotorImpulse) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ joint->enableAngularMotor(enable, targetVelocity, maxMotorImpulse);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getEnableAngularMotor
+ * Signature: (J)Z
+ */
+ JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_joints_HingeJoint_getEnableAngularMotor
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ return joint->getEnableAngularMotor();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getMotorTargetVelocity
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getMotorTargetVelocity
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ return joint->getMotorTargetVelosity();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getMaxMotorImpulse
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getMaxMotorImpulse
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ return joint->getMaxMotorImpulse();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: setLimit
+ * Signature: (JFF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_HingeJoint_setLimit__JFF
+ (JNIEnv * env, jobject object, jlong jointId, jfloat low, jfloat high) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ return joint->setLimit(low, high);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: setLimit
+ * Signature: (JFFFFF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_HingeJoint_setLimit__JFFFFF
+ (JNIEnv * env, jobject object, jlong jointId, jfloat low, jfloat high, jfloat softness, jfloat biasFactor, jfloat relaxationFactor) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ return joint->setLimit(low, high, softness, biasFactor, relaxationFactor);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getUpperLimit
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getUpperLimit
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ return joint->getUpperLimit();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getLowerLimit
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getLowerLimit
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ return joint->getLowerLimit();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: setAngularOnly
+ * Signature: (JZ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_HingeJoint_setAngularOnly
+ (JNIEnv * env, jobject object, jlong jointId, jboolean angular) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ joint->setAngularOnly(angular);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getHingeAngle
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getHingeAngle
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btHingeConstraint* joint = (btHingeConstraint*) jointId;
+ return joint->getHingeAngle();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_HingeJoint_createJoint
+ (JNIEnv * env, jobject object, jlong bodyIdA, jlong bodyIdB, jobject pivotA, jobject axisA, jobject pivotB, jobject axisB) {
+ btRigidBody* bodyA = (btRigidBody*) bodyIdA;
+ btRigidBody* bodyB = (btRigidBody*) bodyIdB;
+ btVector3* vec1 = &btVector3();
+ btVector3* vec2 = &btVector3();
+ btVector3* vec3 = &btVector3();
+ btVector3* vec4 = &btVector3();
+ jmeBulletUtil::convert(env, pivotA, vec1);
+ jmeBulletUtil::convert(env, axisA, vec2);
+ jmeBulletUtil::convert(env, pivotB, vec3);
+ jmeBulletUtil::convert(env, axisB, vec4);
+ btHingeConstraint* joint = new btHingeConstraint(*bodyA, *bodyB, *vec1, *vec2, *vec3, *vec4);
+ return (long) joint;
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_HingeJoint.h b/engine/src/bullet/native/com_jme3_bullet_joints_HingeJoint.h
new file mode 100644
index 000000000..ab6e0034f
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_HingeJoint.h
@@ -0,0 +1,101 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_joints_HingeJoint */
+
+#ifndef _Included_com_jme3_bullet_joints_HingeJoint
+#define _Included_com_jme3_bullet_joints_HingeJoint
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: enableMotor
+ * Signature: (JZFF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_HingeJoint_enableMotor
+ (JNIEnv *, jobject, jlong, jboolean, jfloat, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getEnableAngularMotor
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_joints_HingeJoint_getEnableAngularMotor
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getMotorTargetVelocity
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getMotorTargetVelocity
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getMaxMotorImpulse
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getMaxMotorImpulse
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: setLimit
+ * Signature: (JFF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_HingeJoint_setLimit__JFF
+ (JNIEnv *, jobject, jlong, jfloat, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: setLimit
+ * Signature: (JFFFFF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_HingeJoint_setLimit__JFFFFF
+ (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat, jfloat, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getUpperLimit
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getUpperLimit
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getLowerLimit
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getLowerLimit
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: setAngularOnly
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_HingeJoint_setAngularOnly
+ (JNIEnv *, jobject, jlong, jboolean);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: getHingeAngle
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_HingeJoint_getHingeAngle
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_HingeJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_HingeJoint_createJoint
+ (JNIEnv *, jobject, jlong, jlong, jobject, jobject, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_PhysicsJoint.cpp b/engine/src/bullet/native/com_jme3_bullet_joints_PhysicsJoint.cpp
new file mode 100644
index 000000000..74cda4c35
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_PhysicsJoint.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_joints_PhysicsJoint.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_joints_PhysicsJoint
+ * Method: getAppliedImpulse
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_PhysicsJoint_getAppliedImpulse
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btTypedConstraint* joint = (btTypedConstraint*) jointId;
+ return joint->getAppliedImpulse();
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_PhysicsJoint.h b/engine/src/bullet/native/com_jme3_bullet_joints_PhysicsJoint.h
new file mode 100644
index 000000000..63e21a7d3
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_PhysicsJoint.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_joints_PhysicsJoint */
+
+#ifndef _Included_com_jme3_bullet_joints_PhysicsJoint
+#define _Included_com_jme3_bullet_joints_PhysicsJoint
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_joints_PhysicsJoint
+ * Method: getAppliedImpulse
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_PhysicsJoint_getAppliedImpulse
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_PhysicsJoint
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_PhysicsJoint_finalizeNative
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_Point2PointJoint.cpp b/engine/src/bullet/native/com_jme3_bullet_joints_Point2PointJoint.cpp
new file mode 100644
index 000000000..80869a851
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_Point2PointJoint.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_joints_Point2PointJoint.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: setDamping
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_setDamping
+ (JNIEnv * env, jobject object, jlong jointId, jfloat damping) {
+ btPoint2PointConstraint* joint = (btPoint2PointConstraint*) jointId;
+ joint->m_setting.m_damping = damping;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: setImpulseClamp
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_setImpulseClamp
+ (JNIEnv * env, jobject object, jlong jointId, jfloat clamp) {
+ btPoint2PointConstraint* joint = (btPoint2PointConstraint*) jointId;
+ joint->m_setting.m_impulseClamp = clamp;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: setTau
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_setTau
+ (JNIEnv * env, jobject object, jlong jointId, jfloat tau) {
+ btPoint2PointConstraint* joint = (btPoint2PointConstraint*) jointId;
+ joint->m_setting.m_tau = tau;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: getDamping
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_getDamping
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btPoint2PointConstraint* joint = (btPoint2PointConstraint*) jointId;
+ return joint->m_setting.m_damping;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: getImpulseClamp
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_getImpulseClamp
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btPoint2PointConstraint* joint = (btPoint2PointConstraint*) jointId;
+ return joint->m_setting.m_damping;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: getTau
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_getTau
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btPoint2PointConstraint* joint = (btPoint2PointConstraint*) jointId;
+ return joint->m_setting.m_damping;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_createJoint
+ (JNIEnv * env, jobject object, jlong bodyIdA, jlong bodyIdB, jobject pivotA, jobject pivotB) {
+ btRigidBody* bodyA = (btRigidBody*) bodyIdA;
+ btRigidBody* bodyB = (btRigidBody*) bodyIdB;
+ //TODO: matrix not needed?
+ btMatrix3x3* mtx1=&btMatrix3x3();
+ btMatrix3x3* mtx2=&btMatrix3x3();
+ btTransform* transA = &btTransform(*mtx1);
+ jmeBulletUtil::convert(env, pivotA, &transA->getOrigin());
+ btTransform* transB = &btTransform(*mtx2);
+ jmeBulletUtil::convert(env, pivotB, &transB->getOrigin());
+ btHingeConstraint* joint = new btHingeConstraint(*bodyA, *bodyB, *transA, *transB);
+ return (long) joint;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_Point2PointJoint.h b/engine/src/bullet/native/com_jme3_bullet_joints_Point2PointJoint.h
new file mode 100644
index 000000000..5cb8188a8
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_Point2PointJoint.h
@@ -0,0 +1,69 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_joints_Point2PointJoint */
+
+#ifndef _Included_com_jme3_bullet_joints_Point2PointJoint
+#define _Included_com_jme3_bullet_joints_Point2PointJoint
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: setDamping
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_setDamping
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: setImpulseClamp
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_setImpulseClamp
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: setTau
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_setTau
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: getDamping
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_getDamping
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: getImpulseClamp
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_getImpulseClamp
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: getTau
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_getTau
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_Point2PointJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_Point2PointJoint_createJoint
+ (JNIEnv *, jobject, jlong, jlong, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_SixDofJoint.cpp b/engine/src/bullet/native/com_jme3_bullet_joints_SixDofJoint.cpp
new file mode 100644
index 000000000..b9bc20b3e
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_SixDofJoint.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_joints_SixDofJoint.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: getRotationalLimitMotor
+ * Signature: (JI)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_SixDofJoint_getRotationalLimitMotor
+ (JNIEnv * env, jobject object, jlong jointId, jint index) {
+ btGeneric6DofConstraint* joint = (btGeneric6DofConstraint*) jointId;
+ return (long)joint->getRotationalLimitMotor(index);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: getTranslationalLimitMotor
+ * Signature: (J)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_SixDofJoint_getTranslationalLimitMotor
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btGeneric6DofConstraint* joint = (btGeneric6DofConstraint*) jointId;
+ return (long)joint->getTranslationalLimitMotor();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: setLinearUpperLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SixDofJoint_setLinearUpperLimit
+ (JNIEnv * env, jobject object, jlong jointId, jobject vector) {
+ btGeneric6DofConstraint* joint = (btGeneric6DofConstraint*) jointId;
+ btVector3* vec = &btVector3();
+ jmeBulletUtil::convert(env, vector, vec);
+ joint->setLinearUpperLimit(*vec);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: setLinearLowerLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SixDofJoint_setLinearLowerLimit
+ (JNIEnv * env, jobject object, jlong jointId, jobject vector) {
+ btGeneric6DofConstraint* joint = (btGeneric6DofConstraint*) jointId;
+ btVector3* vec = &btVector3();
+ jmeBulletUtil::convert(env, vector, vec);
+ joint->setLinearUpperLimit(*vec);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: setAngularUpperLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SixDofJoint_setAngularUpperLimit
+ (JNIEnv * env, jobject object, jlong jointId, jobject vector) {
+ btGeneric6DofConstraint* joint = (btGeneric6DofConstraint*) jointId;
+ btVector3* vec = &btVector3();
+ jmeBulletUtil::convert(env, vector, vec);
+ joint->setLinearUpperLimit(*vec);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: setAngularLowerLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SixDofJoint_setAngularLowerLimit
+ (JNIEnv * env, jobject object, jlong jointId, jobject vector) {
+ btGeneric6DofConstraint* joint = (btGeneric6DofConstraint*) jointId;
+ btVector3* vec = &btVector3();
+ jmeBulletUtil::convert(env, vector, vec);
+ joint->setAngularLowerLimit(*vec);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Z)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_SixDofJoint_createJoint
+ (JNIEnv * env, jobject object, jlong bodyIdA, jlong bodyIdB, jobject pivotA, jobject rotA, jobject pivotB, jobject rotB, jboolean useLinearReferenceFrameA) {
+ btRigidBody* bodyA = (btRigidBody*) bodyIdA;
+ btRigidBody* bodyB = (btRigidBody*) bodyIdB;
+ btMatrix3x3* mtx1 = &btMatrix3x3();
+ btMatrix3x3* mtx2 = &btMatrix3x3();
+ btTransform* transA = &btTransform(*mtx1);
+ jmeBulletUtil::convert(env, pivotA, &transA->getOrigin());
+ jmeBulletUtil::convert(env, rotA, &transA->getBasis());
+ btTransform* transB = &btTransform(*mtx2);
+ jmeBulletUtil::convert(env, pivotB, &transB->getOrigin());
+ jmeBulletUtil::convert(env, rotB, &transB->getBasis());
+ btGeneric6DofConstraint* joint = new btGeneric6DofConstraint(*bodyA, *bodyB, *transA, *transB, useLinearReferenceFrameA);
+ return (long)joint;
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_SixDofJoint.h b/engine/src/bullet/native/com_jme3_bullet_joints_SixDofJoint.h
new file mode 100644
index 000000000..86e610234
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_SixDofJoint.h
@@ -0,0 +1,69 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_joints_SixDofJoint */
+
+#ifndef _Included_com_jme3_bullet_joints_SixDofJoint
+#define _Included_com_jme3_bullet_joints_SixDofJoint
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: getRotationalLimitMotor
+ * Signature: (JI)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_SixDofJoint_getRotationalLimitMotor
+ (JNIEnv *, jobject, jlong, jint);
+
+/*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: getTranslationalLimitMotor
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_SixDofJoint_getTranslationalLimitMotor
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: setLinearUpperLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SixDofJoint_setLinearUpperLimit
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: setLinearLowerLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SixDofJoint_setLinearLowerLimit
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: setAngularUpperLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SixDofJoint_setAngularUpperLimit
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: setAngularLowerLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SixDofJoint_setAngularLowerLimit
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_SixDofJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Z)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_SixDofJoint_createJoint
+ (JNIEnv *, jobject, jlong, jlong, jobject, jobject, jobject, jobject, jboolean);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_SliderJoint.cpp b/engine/src/bullet/native/com_jme3_bullet_joints_SliderJoint.cpp
new file mode 100644
index 000000000..3a4e894c6
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_SliderJoint.cpp
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_joints_SliderJoint.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getLowerLinLimit
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getLowerLinLimit
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getLowerLinLimit();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setLowerLinLimit
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setLowerLinLimit
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setLowerLinLimit(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getUpperLinLimit
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getUpperLinLimit
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getUpperLinLimit();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setUpperLinLimit
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setUpperLinLimit
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setUpperLinLimit(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getLowerAngLimit
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getLowerAngLimit
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getLowerAngLimit();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setLowerAngLimit
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setLowerAngLimit
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setLowerAngLimit(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getUpperAngLimit
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getUpperAngLimit
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getUpperAngLimit();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setUpperAngLimit
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setUpperAngLimit
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setUpperAngLimit(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessDirLin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessDirLin
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getSoftnessDirLin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessDirLin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessDirLin
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setSoftnessDirLin(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionDirLin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionDirLin
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getRestitutionDirLin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionDirLin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionDirLin
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setRestitutionDirLin(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingDirLin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingDirLin
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getDampingDirLin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingDirLin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingDirLin
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setDampingDirLin(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessDirAng
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessDirAng
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getSoftnessDirAng();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessDirAng
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessDirAng
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setSoftnessDirAng(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionDirAng
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionDirAng
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getRestitutionDirAng();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionDirAng
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionDirAng
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setRestitutionDirAng(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingDirAng
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingDirAng
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getDampingDirAng();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingDirAng
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingDirAng
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setDampingDirAng(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessLimLin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessLimLin
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getSoftnessLimLin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessLimLin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessLimLin
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setSoftnessLimLin(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionLimLin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionLimLin
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getRestitutionLimLin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionLimLin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionLimLin
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setRestitutionLimLin(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingLimLin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingLimLin
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getDampingLimLin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingLimLin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingLimLin
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setDampingLimLin(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessLimAng
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessLimAng
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getSoftnessLimAng();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessLimAng
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessLimAng
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setSoftnessLimAng(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionLimAng
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionLimAng
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getRestitutionLimAng();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionLimAng
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionLimAng
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setRestitutionLimAng(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingLimAng
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingLimAng
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getDampingLimAng();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingLimAng
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingLimAng
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setDampingLimAng(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessOrthoLin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessOrthoLin
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getSoftnessOrthoLin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessOrthoLin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessOrthoLin
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setSoftnessOrthoLin(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionOrthoLin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionOrthoLin
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getRestitutionOrthoLin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionOrthoLin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionOrthoLin
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setRestitutionOrthoLin(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingOrthoLin
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingOrthoLin
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getDampingOrthoLin();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingOrthoLin
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingOrthoLin
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setDampingOrthoLin(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessOrthoAng
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessOrthoAng
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getSoftnessOrthoAng();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessOrthoAng
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessOrthoAng
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setSoftnessOrthoAng(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionOrthoAng
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionOrthoAng
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getRestitutionOrthoAng();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionOrthoAng
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionOrthoAng
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setRestitutionOrthoAng(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingOrthoAng
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingOrthoAng
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getDampingOrthoAng();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingOrthoAng
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingOrthoAng
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setDampingOrthoAng(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: isPoweredLinMotor
+ * Signature: (J)Z
+ */
+ JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_joints_SliderJoint_isPoweredLinMotor
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getPoweredLinMotor();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setPoweredLinMotor
+ * Signature: (JZ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setPoweredLinMotor
+ (JNIEnv * env, jobject object, jlong jointId, jboolean value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setPoweredLinMotor(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getTargetLinMotorVelocity
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getTargetLinMotorVelocity
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getTargetLinMotorVelocity();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setTargetLinMotorVelocity
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setTargetLinMotorVelocity
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setTargetLinMotorVelocity(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getMaxLinMotorForce
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getMaxLinMotorForce
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getMaxLinMotorForce();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setMaxLinMotorForce
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setMaxLinMotorForce
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setMaxLinMotorForce(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: isPoweredAngMotor
+ * Signature: (J)Z
+ */
+ JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_joints_SliderJoint_isPoweredAngMotor
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getPoweredAngMotor();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setPoweredAngMotor
+ * Signature: (JZ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setPoweredAngMotor
+ (JNIEnv * env, jobject object, jlong jointId, jboolean value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setPoweredAngMotor(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getTargetAngMotorVelocity
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getTargetAngMotorVelocity
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getTargetAngMotorVelocity();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setTargetAngMotorVelocity
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setTargetAngMotorVelocity
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setTargetAngMotorVelocity(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getMaxAngMotorForce
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getMaxAngMotorForce
+ (JNIEnv * env, jobject object, jlong jointId) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ return joint->getMaxAngMotorForce();
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setMaxAngMotorForce
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setMaxAngMotorForce
+ (JNIEnv * env, jobject object, jlong jointId, jfloat value) {
+ btSliderConstraint* joint = (btSliderConstraint*) jointId;
+ joint->setMaxAngMotorForce(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Z)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_SliderJoint_createJoint
+ (JNIEnv * env, jobject object, jlong bodyIdA, jlong bodyIdB, jobject pivotA, jobject rotA, jobject pivotB, jobject rotB, jboolean useLinearReferenceFrameA) {
+ btRigidBody* bodyA = (btRigidBody*) bodyIdA;
+ btRigidBody* bodyB = (btRigidBody*) bodyIdB;
+ btMatrix3x3* mtx1=&btMatrix3x3();
+ btMatrix3x3* mtx2=&btMatrix3x3();
+ btTransform* transA = &btTransform(*mtx1);
+ jmeBulletUtil::convert(env, pivotA, &transA->getOrigin());
+ jmeBulletUtil::convert(env, rotA, &transA->getBasis());
+ btTransform* transB = &btTransform(*mtx2);
+ jmeBulletUtil::convert(env, pivotB, &transB->getOrigin());
+ jmeBulletUtil::convert(env, rotB, &transB->getBasis());
+ btSliderConstraint* joint = new btSliderConstraint(*bodyA, *bodyB, *transA, *transB, useLinearReferenceFrameA);
+ return (long)joint;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_SliderJoint.h b/engine/src/bullet/native/com_jme3_bullet_joints_SliderJoint.h
new file mode 100644
index 000000000..7afd66a56
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_SliderJoint.h
@@ -0,0 +1,469 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_joints_SliderJoint */
+
+#ifndef _Included_com_jme3_bullet_joints_SliderJoint
+#define _Included_com_jme3_bullet_joints_SliderJoint
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getLowerLinLimit
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getLowerLinLimit
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setLowerLinLimit
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setLowerLinLimit
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getUpperLinLimit
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getUpperLinLimit
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setUpperLinLimit
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setUpperLinLimit
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getLowerAngLimit
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getLowerAngLimit
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setLowerAngLimit
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setLowerAngLimit
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getUpperAngLimit
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getUpperAngLimit
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setUpperAngLimit
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setUpperAngLimit
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessDirLin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessDirLin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessDirLin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessDirLin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionDirLin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionDirLin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionDirLin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionDirLin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingDirLin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingDirLin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingDirLin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingDirLin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessDirAng
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessDirAng
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessDirAng
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessDirAng
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionDirAng
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionDirAng
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionDirAng
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionDirAng
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingDirAng
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingDirAng
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingDirAng
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingDirAng
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessLimLin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessLimLin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessLimLin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessLimLin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionLimLin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionLimLin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionLimLin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionLimLin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingLimLin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingLimLin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingLimLin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingLimLin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessLimAng
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessLimAng
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessLimAng
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessLimAng
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionLimAng
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionLimAng
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionLimAng
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionLimAng
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingLimAng
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingLimAng
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingLimAng
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingLimAng
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessOrthoLin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessOrthoLin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessOrthoLin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessOrthoLin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionOrthoLin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionOrthoLin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionOrthoLin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionOrthoLin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingOrthoLin
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingOrthoLin
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingOrthoLin
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingOrthoLin
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getSoftnessOrthoAng
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getSoftnessOrthoAng
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setSoftnessOrthoAng
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setSoftnessOrthoAng
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getRestitutionOrthoAng
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getRestitutionOrthoAng
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setRestitutionOrthoAng
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setRestitutionOrthoAng
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getDampingOrthoAng
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getDampingOrthoAng
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setDampingOrthoAng
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setDampingOrthoAng
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: isPoweredLinMotor
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_joints_SliderJoint_isPoweredLinMotor
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setPoweredLinMotor
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setPoweredLinMotor
+ (JNIEnv *, jobject, jlong, jboolean);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getTargetLinMotorVelocity
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getTargetLinMotorVelocity
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setTargetLinMotorVelocity
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setTargetLinMotorVelocity
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getMaxLinMotorForce
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getMaxLinMotorForce
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setMaxLinMotorForce
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setMaxLinMotorForce
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: isPoweredAngMotor
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_joints_SliderJoint_isPoweredAngMotor
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setPoweredAngMotor
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setPoweredAngMotor
+ (JNIEnv *, jobject, jlong, jboolean);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getTargetAngMotorVelocity
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getTargetAngMotorVelocity
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setTargetAngMotorVelocity
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setTargetAngMotorVelocity
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: getMaxAngMotorForce
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_SliderJoint_getMaxAngMotorForce
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: setMaxAngMotorForce
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_SliderJoint_setMaxAngMotorForce
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_SliderJoint
+ * Method: createJoint
+ * Signature: (JJLcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Matrix3f;Z)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_joints_SliderJoint_createJoint
+ (JNIEnv *, jobject, jlong, jlong, jobject, jobject, jobject, jobject, jboolean);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_motors_RotationalLimitMotor.cpp b/engine/src/bullet/native/com_jme3_bullet_joints_motors_RotationalLimitMotor.cpp
new file mode 100644
index 000000000..6c9e5d930
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_motors_RotationalLimitMotor.cpp
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_joints_motors_RotationalLimitMotor.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getLoLimit
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getLoLimit
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_loLimit;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setLoLimit
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setLoLimit
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_loLimit = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getHiLimit
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getHiLimit
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_hiLimit;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setHiLimit
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setHiLimit
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_hiLimit = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getTargetVelocity
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getTargetVelocity
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_targetVelocity;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setTargetVelocity
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setTargetVelocity
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_targetVelocity = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getMaxMotorForce
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getMaxMotorForce
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_maxMotorForce;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setMaxMotorForce
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setMaxMotorForce
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_maxMotorForce = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getMaxLimitForce
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getMaxLimitForce
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_maxLimitForce;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setMaxLimitForce
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setMaxLimitForce
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_maxLimitForce = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getDamping
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getDamping
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_damping;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setDamping
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setDamping
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_damping = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getLimitSoftness
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getLimitSoftness
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_limitSoftness;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setLimitSoftness
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setLimitSoftness
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_limitSoftness = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getERP
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getERP
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_stopERP;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setERP
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setERP
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_stopERP = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getBounce
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getBounce
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_bounce;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setBounce
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setBounce
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_bounce = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: isEnableMotor
+ * Signature: (J)Z
+ */
+ JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_isEnableMotor
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ return motor->m_enableMotor;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setEnableMotor
+ * Signature: (JZ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setEnableMotor
+ (JNIEnv *env, jobject object, jlong motorId, jboolean value) {
+ btRotationalLimitMotor* motor = (btRotationalLimitMotor*) motorId;
+ motor->m_enableMotor = value;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_motors_RotationalLimitMotor.h b/engine/src/bullet/native/com_jme3_bullet_joints_motors_RotationalLimitMotor.h
new file mode 100644
index 000000000..b14bf1d73
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_motors_RotationalLimitMotor.h
@@ -0,0 +1,173 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_joints_motors_RotationalLimitMotor */
+
+#ifndef _Included_com_jme3_bullet_joints_motors_RotationalLimitMotor
+#define _Included_com_jme3_bullet_joints_motors_RotationalLimitMotor
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getLoLimit
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getLoLimit
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setLoLimit
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setLoLimit
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getHiLimit
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getHiLimit
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setHiLimit
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setHiLimit
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getTargetVelocity
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getTargetVelocity
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setTargetVelocity
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setTargetVelocity
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getMaxMotorForce
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getMaxMotorForce
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setMaxMotorForce
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setMaxMotorForce
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getMaxLimitForce
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getMaxLimitForce
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setMaxLimitForce
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setMaxLimitForce
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getDamping
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getDamping
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setDamping
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setDamping
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getLimitSoftness
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getLimitSoftness
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setLimitSoftness
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setLimitSoftness
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getERP
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getERP
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setERP
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setERP
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: getBounce
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_getBounce
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setBounce
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setBounce
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: isEnableMotor
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_isEnableMotor
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_RotationalLimitMotor
+ * Method: setEnableMotor
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_RotationalLimitMotor_setEnableMotor
+ (JNIEnv *, jobject, jlong, jboolean);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_motors_TranslationalLimitMotor.cpp b/engine/src/bullet/native/com_jme3_bullet_joints_motors_TranslationalLimitMotor.cpp
new file mode 100644
index 000000000..288df911d
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_motors_TranslationalLimitMotor.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_joints_motors_TranslationalLimitMotor.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getLowerLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getLowerLimit
+ (JNIEnv *env, jobject object, jlong motorId, jobject vector) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ jmeBulletUtil::convert(env, &motor->m_lowerLimit, vector);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setLowerLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setLowerLimit
+ (JNIEnv *env, jobject object, jlong motorId, jobject vector) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ jmeBulletUtil::convert(env, vector, &motor->m_lowerLimit);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getUpperLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getUpperLimit
+ (JNIEnv *env, jobject object, jlong motorId, jobject vector) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ jmeBulletUtil::convert(env, &motor->m_upperLimit, vector);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setUpperLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setUpperLimit
+ (JNIEnv *env, jobject object, jlong motorId, jobject vector) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ jmeBulletUtil::convert(env, vector, &motor->m_upperLimit);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getAccumulatedImpulse
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getAccumulatedImpulse
+ (JNIEnv *env, jobject object, jlong motorId, jobject vector) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ jmeBulletUtil::convert(env, &motor->m_accumulatedImpulse, vector);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setAccumulatedImpulse
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setAccumulatedImpulse
+ (JNIEnv *env, jobject object, jlong motorId, jobject vector) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ jmeBulletUtil::convert(env, vector, &motor->m_accumulatedImpulse);
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getLimitSoftness
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getLetLimitSoftness
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ return motor->m_limitSoftness;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setLimitSoftness
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setLimitSoftness
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ motor->m_limitSoftness = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getDamping
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getDamping
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ return motor->m_damping;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setDamping
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setDamping
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ motor->m_damping = value;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getRestitution
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getRestitution
+ (JNIEnv *env, jobject object, jlong motorId) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ return motor->m_restitution;
+ }
+
+ /*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setRestitution
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setRestitution
+ (JNIEnv *env, jobject object, jlong motorId, jfloat value) {
+ btTranslationalLimitMotor* motor = (btTranslationalLimitMotor*) motorId;
+ motor->m_restitution = value;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_joints_motors_TranslationalLimitMotor.h b/engine/src/bullet/native/com_jme3_bullet_joints_motors_TranslationalLimitMotor.h
new file mode 100644
index 000000000..0ea93e2b1
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_joints_motors_TranslationalLimitMotor.h
@@ -0,0 +1,109 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_joints_motors_TranslationalLimitMotor */
+
+#ifndef _Included_com_jme3_bullet_joints_motors_TranslationalLimitMotor
+#define _Included_com_jme3_bullet_joints_motors_TranslationalLimitMotor
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getLowerLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getLowerLimit
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setLowerLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setLowerLimit
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getUpperLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getUpperLimit
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setUpperLimit
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setUpperLimit
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getAccumulatedImpulse
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getAccumulatedImpulse
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setAccumulatedImpulse
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setAccumulatedImpulse
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getLimitSoftness
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getLimitSoftness
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setLimitSoftness
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setLimitSoftness
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getDamping
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getDamping
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setDamping
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setDamping
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: getRestitution
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_getRestitution
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_joints_motors_TranslationalLimitMotor
+ * Method: setRestitution
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_joints_motors_TranslationalLimitMotor_setRestitution
+ (JNIEnv *, jobject, jlong, jfloat);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsCharacter.cpp b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsCharacter.cpp
new file mode 100644
index 000000000..840d21e28
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsCharacter.cpp
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+
+#include "com_jme3_bullet_objects_PhysicsCharacter.h"
+#include "jmeBulletUtil.h"
+#include "BulletCollision/CollisionDispatch/btGhostObject.h"
+#include "BulletDynamics/Character/btKinematicCharacterController.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: createGhostObject
+ * Signature: ()J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_createGhostObject
+ (JNIEnv * env, jobject object) {
+ btPairCachingGhostObject* ghost = new btPairCachingGhostObject();
+ return (long) ghost;
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setCharacterFlags
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setCharacterFlags
+ (JNIEnv *env, jobject object, jlong ghostId) {
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*) ghostId;
+ ghost->setCollisionFlags(ghost->getCollisionFlags() | btCollisionObject::CF_CHARACTER_OBJECT);
+ ghost->setCollisionFlags(ghost->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: createCharacterObject
+ * Signature: (JJF)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_createCharacterObject
+ (JNIEnv *env, jobject object, jlong objectId, jlong shapeId, jfloat stepHeight) {
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*) objectId;
+ //TODO: check convexshape!
+ btConvexShape* shape = (btConvexShape*) shapeId;
+ btKinematicCharacterController* character = new btKinematicCharacterController(ghost, shape, stepHeight);
+ return (long) character;
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: warp
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_warp
+ (JNIEnv *env, jobject object, jlong objectId, jobject vector) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ btVector3* vec = &btVector3();
+ jmeBulletUtil::convert(env, vector, vec);
+ character->warp(*vec);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setWalkDirection
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setWalkDirection
+ (JNIEnv *env, jobject object, jlong objectId, jobject vector) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ btVector3* vec = &btVector3();
+ jmeBulletUtil::convert(env, vector, vec);
+ character->setWalkDirection(*vec);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setUpAxis
+ * Signature: (JI)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setUpAxis
+ (JNIEnv *env, jobject object, jlong objectId, jint value) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ character->setUpAxis(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setFallSpeed
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setFallSpeed
+ (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ character->setFallSpeed(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setJumpSpeed
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setJumpSpeed
+ (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ character->setJumpSpeed(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setGravity
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setGravity
+ (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ character->setGravity(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getGravity
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getGravity
+ (JNIEnv *env, jobject object, jlong objectId) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ return character->getGravity();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setMaxSlope
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setMaxSlope
+ (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ character->setMaxSlope(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getMaxSlope
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getMaxSlope
+ (JNIEnv *env, jobject object, jlong objectId) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ return character->getMaxSlope();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: onGround
+ * Signature: (J)Z
+ */
+ JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_onGround
+ (JNIEnv *env, jobject object, jlong objectId) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ return character->onGround();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: jump
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_jump
+ (JNIEnv *env, jobject object, jlong objectId) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ character->jump();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getPhysicsLocation
+ (JNIEnv *env, jobject object, jlong objectId, jobject value) {
+ btGhostObject* character = (btGhostObject*) objectId;
+ jmeBulletUtil::convert(env, &character->getWorldTransform().getOrigin(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setCcdSweptSphereRadius
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setCcdSweptSphereRadius
+ (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
+ btGhostObject* character = (btGhostObject*) objectId;
+ character->setCcdSweptSphereRadius(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setCcdMotionThreshold
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setCcdMotionThreshold
+ (JNIEnv *env, jobject object, jlong objectId, jfloat value) {
+ btGhostObject* character = (btGhostObject*) objectId;
+ character->setCcdMotionThreshold(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getCcdSweptSphereRadius
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getCcdSweptSphereRadius
+ (JNIEnv *env, jobject object, jlong objectId) {
+ btGhostObject* character = (btGhostObject*) objectId;
+ return character->getCcdSweptSphereRadius();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getCcdMotionThreshold
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getCcdMotionThreshold
+ (JNIEnv *env, jobject object, jlong objectId) {
+ btGhostObject* character = (btGhostObject*) objectId;
+ return character->getCcdMotionThreshold();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getCcdSquareMotionThreshold
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getCcdSquareMotionThreshold
+ (JNIEnv *env, jobject object, jlong objectId) {
+ btGhostObject* character = (btGhostObject*) objectId;
+ return character->getCcdSquareMotionThreshold();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: finalizeNativeCharacter
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_finalizeNativeCharacter
+ (JNIEnv *env, jobject object, jlong objectId) {
+ btKinematicCharacterController* character = (btKinematicCharacterController*) objectId;
+ delete(character);
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsCharacter.h b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsCharacter.h
new file mode 100644
index 000000000..210198c01
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsCharacter.h
@@ -0,0 +1,215 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_objects_PhysicsCharacter */
+
+#ifndef _Included_com_jme3_bullet_objects_PhysicsCharacter
+#define _Included_com_jme3_bullet_objects_PhysicsCharacter
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_NONE
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_NONE 0L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_01
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_01 1L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_02
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_02 2L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_03
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_03 4L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_04
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_04 8L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_05
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_05 16L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_06
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_06 32L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_07
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_07 64L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_08
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_08 128L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_09
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_09 256L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_10
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_10 512L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_11
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_11 1024L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_12
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_12 2048L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_13
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_13 4096L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_14
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_14 8192L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_15
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_15 16384L
+#undef com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_16
+#define com_jme3_bullet_objects_PhysicsCharacter_COLLISION_GROUP_16 32768L
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: createGhostObject
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_createGhostObject
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setCharacterFlags
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setCharacterFlags
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: createCharacterObject
+ * Signature: (JJF)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_createCharacterObject
+ (JNIEnv *, jobject, jlong, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: warp
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_warp
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setWalkDirection
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setWalkDirection
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setUpAxis
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setUpAxis
+ (JNIEnv *, jobject, jlong, jint);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setFallSpeed
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setFallSpeed
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setJumpSpeed
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setJumpSpeed
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setGravity
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setGravity
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getGravity
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getGravity
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setMaxSlope
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setMaxSlope
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getMaxSlope
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getMaxSlope
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: onGround
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_onGround
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: jump
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_jump
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getPhysicsLocation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setCcdSweptSphereRadius
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setCcdSweptSphereRadius
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: setCcdMotionThreshold
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_setCcdMotionThreshold
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getCcdSweptSphereRadius
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getCcdSweptSphereRadius
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getCcdMotionThreshold
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getCcdMotionThreshold
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: getCcdSquareMotionThreshold
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_getCcdSquareMotionThreshold
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsCharacter
+ * Method: finalizeNativeCharacter
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsCharacter_finalizeNativeCharacter
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsGhostObject.cpp b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsGhostObject.cpp
new file mode 100644
index 000000000..5aaa727dd
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsGhostObject.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+
+#include
+
+#include "com_jme3_bullet_objects_PhysicsGhostObject.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: createGhostObject
+ * Signature: ()J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_createGhostObject
+ (JNIEnv * env, jobject object) {
+ btPairCachingGhostObject* ghost = new btPairCachingGhostObject();
+ return (long) ghost;
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setGhostFlags
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setGhostFlags
+ (JNIEnv *env, jobject object, jlong objectId) {
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*) objectId;
+ ghost->setCollisionFlags(ghost->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsLocation
+ (JNIEnv *env, jobject object, jlong objectId, jobject value){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+// btVector3* vec = new btVector3();
+// jmeBulletUtil::convert(value, vec);
+// ghost->getWorldTransform().setOrigin(vec);
+// delete(vec);
+ jmeBulletUtil::convert(env, value, &ghost->getWorldTransform().getOrigin());
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setPhysicsRotation
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsRotation__JLcom_jme3_math_Matrix3f_2
+ (JNIEnv *env, jobject object, jlong objectId, jobject value){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+// btVector3* vec = new btVector3();
+// jmeBulletUtil::convert(value, vec);
+// ghost->getWorldTransform().setOrigin(vec);
+// delete(vec);
+ jmeBulletUtil::convert(env, value, &ghost->getWorldTransform().getBasis());
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setPhysicsRotation
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsRotation__JLcom_jme3_math_Quaternion_2
+ (JNIEnv *env, jobject object, jlong objectId, jobject value){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+// btVector3* vec = new btVector3();
+// jmeBulletUtil::convert(value, vec);
+// ghost->getWorldTransform().setOrigin(vec);
+// delete(vec);
+ jmeBulletUtil::convertQuat(env, value, &ghost->getWorldTransform().getBasis());
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsLocation
+ (JNIEnv *env, jobject object, jlong objectId, jobject value){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+ jmeBulletUtil::convert(env, &ghost->getWorldTransform().getOrigin(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getPhysicsRotation
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsRotation
+ (JNIEnv *env, jobject object, jlong objectId, jobject value){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+ jmeBulletUtil::convertQuat(env, &ghost->getWorldTransform().getBasis(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getPhysicsRotationMatrix
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsRotationMatrix
+ (JNIEnv *env, jobject object, jlong objectId, jobject value){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+ jmeBulletUtil::convert(env, &ghost->getWorldTransform().getBasis(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getOverlappingCount
+ * Signature: (J)I
+ */
+ JNIEXPORT jint JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getOverlappingCount
+ (JNIEnv *env, jobject object, jlong objectId){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+ return ghost->getNumOverlappingObjects();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setCcdSweptSphereRadius
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setCcdSweptSphereRadius
+ (JNIEnv *env, jobject object, jlong objectId, jfloat value){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+ ghost->setCcdSweptSphereRadius(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setCcdMotionThreshold
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setCcdMotionThreshold
+ (JNIEnv *env, jobject object, jlong objectId, jfloat value){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+ ghost->setCcdMotionThreshold(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getCcdSweptSphereRadius
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdSweptSphereRadius
+ (JNIEnv *env, jobject object, jlong objectId){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+ return ghost->getCcdSweptSphereRadius();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getCcdMotionThreshold
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdMotionThreshold
+ (JNIEnv *env, jobject object, jlong objectId){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+ return ghost->getCcdMotionThreshold();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getCcdSquareMotionThreshold
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdSquareMotionThreshold
+ (JNIEnv *env, jobject object, jlong objectId){
+ btPairCachingGhostObject* ghost = (btPairCachingGhostObject*)objectId;
+ return ghost->getCcdSquareMotionThreshold();
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsGhostObject.h b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsGhostObject.h
new file mode 100644
index 000000000..a3e18de76
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsGhostObject.h
@@ -0,0 +1,159 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_objects_PhysicsGhostObject */
+
+#ifndef _Included_com_jme3_bullet_objects_PhysicsGhostObject
+#define _Included_com_jme3_bullet_objects_PhysicsGhostObject
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_NONE
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_NONE 0L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_01
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_01 1L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_02
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_02 2L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_03
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_03 4L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_04
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_04 8L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_05
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_05 16L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_06
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_06 32L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_07
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_07 64L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_08
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_08 128L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_09
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_09 256L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_10
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_10 512L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_11
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_11 1024L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_12
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_12 2048L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_13
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_13 4096L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_14
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_14 8192L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_15
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_15 16384L
+#undef com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_16
+#define com_jme3_bullet_objects_PhysicsGhostObject_COLLISION_GROUP_16 32768L
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: createGhostObject
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_createGhostObject
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setGhostFlags
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setGhostFlags
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsLocation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setPhysicsRotation
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsRotation__JLcom_jme3_math_Matrix3f_2
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setPhysicsRotation
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setPhysicsRotation__JLcom_jme3_math_Quaternion_2
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsLocation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getPhysicsRotation
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsRotation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getPhysicsRotationMatrix
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getPhysicsRotationMatrix
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getOverlappingCount
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getOverlappingCount
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setCcdSweptSphereRadius
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setCcdSweptSphereRadius
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: setCcdMotionThreshold
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_setCcdMotionThreshold
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getCcdSweptSphereRadius
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdSweptSphereRadius
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getCcdMotionThreshold
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdMotionThreshold
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsGhostObject
+ * Method: getCcdSquareMotionThreshold
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsGhostObject_getCcdSquareMotionThreshold
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsRigidBody.cpp b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsRigidBody.cpp
new file mode 100644
index 000000000..d4aa8160f
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsRigidBody.cpp
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_objects_PhysicsRigidBody.h"
+#include "jmeBulletUtil.h"
+#include "jmeMotionState.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: createRigidBody
+ * Signature: (FJJ)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_createRigidBody
+ (JNIEnv *env, jobject object, jfloat mass, jlong motionstatId, jlong shapeId) {
+ btMotionState* motionState = (btMotionState*) motionstatId;
+ btCollisionShape* shape = (btCollisionShape*) shapeId;
+ btVector3* localInertia = &btVector3();
+ shape->calculateLocalInertia(mass, *localInertia);
+ btRigidBody* body = new btRigidBody(mass, motionState, shape, *localInertia);
+ return (long) body;
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: isInWorld
+ * Signature: (J)Z
+ */
+ JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_isInWorld
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->isInWorld();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setPhysicsLocation
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+// if (body->isStaticOrKinematicObject() || !body->isInWorld())
+ ((jmeMotionState*)body->getMotionState())->setKinematicLocation(env, value);
+ body->setCenterOfMassTransform(((jmeMotionState*)body->getMotionState())->worldTransform);
+// else{
+// btMatrix3x3* mtx = &btMatrix3x3();
+// btTransform* trans = &btTransform(*mtx);
+// trans->setBasis(body->getCenterOfMassTransform().getBasis());
+// jmeBulletUtil::convert(env, value, &trans->getOrigin());
+// body->setCenterOfMassTransform(*trans);
+// }
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setPhysicsRotation
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setPhysicsRotation__JLcom_jme3_math_Matrix3f_2
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+// if (body->isStaticOrKinematicObject() || !body->isInWorld())
+ ((jmeMotionState*)body->getMotionState())->setKinematicRotation(env, value);
+ body->setCenterOfMassTransform(((jmeMotionState*)body->getMotionState())->worldTransform);
+// else{
+// btMatrix3x3* mtx = &btMatrix3x3();
+// btTransform* trans = &btTransform(*mtx);
+// trans->setOrigin(body->getCenterOfMassTransform().getOrigin());
+// jmeBulletUtil::convert(env, value, &trans->getBasis());
+// body->setCenterOfMassTransform(*trans);
+// }
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setPhysicsRotation
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setPhysicsRotation__JLcom_jme3_math_Quaternion_2
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+// if (body->isStaticOrKinematicObject() || !body->isInWorld())
+ ((jmeMotionState*)body->getMotionState())->setKinematicRotationQuat(env, value);
+ body->setCenterOfMassTransform(((jmeMotionState*)body->getMotionState())->worldTransform);
+// else{
+// btMatrix3x3* mtx = &btMatrix3x3();
+// btTransform* trans = &btTransform(*mtx);
+// trans->setOrigin(body->getCenterOfMassTransform().getOrigin());
+// jmeBulletUtil::convertQuat(env, value, &trans->getBasis());
+// body->setCenterOfMassTransform(*trans);
+// }
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getPhysicsLocation
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ jmeBulletUtil::convert(env, &body->getWorldTransform().getOrigin(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getPhysicsRotation
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getPhysicsRotation
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ jmeBulletUtil::convertQuat(env, &body->getWorldTransform().getBasis(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getPhysicsRotationMatrix
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getPhysicsRotationMatrix
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ jmeBulletUtil::convert(env, &body->getWorldTransform().getBasis(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setKinematic
+ * Signature: (JZ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setKinematic
+ (JNIEnv *env, jobject object, jlong bodyId, jboolean value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ if (value) {
+ body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ body->setActivationState(DISABLE_DEACTIVATION);
+ } else {
+ body->setCollisionFlags(body->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
+ body->setActivationState(ACTIVE_TAG);
+ }
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setCcdSweptSphereRadius
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setCcdSweptSphereRadius
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->setCcdSweptSphereRadius(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setCcdMotionThreshold
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setCcdMotionThreshold
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->setCcdMotionThreshold(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getCcdSweptSphereRadius
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getCcdSweptSphereRadius
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getCcdSweptSphereRadius();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getCcdMotionThreshold
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getCcdMotionThreshold
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getCcdMotionThreshold();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getCcdSquareMotionThreshold
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getCcdSquareMotionThreshold
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getCcdSquareMotionThreshold();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setStatic
+ * Signature: (JZ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setStatic
+ (JNIEnv *env, jobject object, jlong bodyId, jboolean value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ if (value) {
+ body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
+ } else {
+ body->setCollisionFlags(body->getCollisionFlags() & ~btCollisionObject::CF_STATIC_OBJECT);
+ }
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: updateMassProps
+ * Signature: (JJF)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_updateMassProps
+ (JNIEnv *env, jobject object, jlong bodyId, jlong shapeId, jfloat mass) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btCollisionShape* shape = (btCollisionShape*) shapeId;
+ btVector3* localInertia = &btVector3();
+ shape->calculateLocalInertia(mass, *localInertia);
+ body->setMassProps(mass, *localInertia);
+ return (long) body;
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getGravity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getGravity
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ jmeBulletUtil::convert(env, &body->getGravity(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setGravity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setGravity
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btVector3* vec = &btVector3();
+ jmeBulletUtil::convert(env, value, vec);
+ body->setGravity(*vec);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getFriction
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getFriction
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getFriction();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setFriction
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setFriction
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->setFriction(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setDamping
+ * Signature: (JFF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setDamping
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat value1, jfloat value2) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->setDamping(value1, value2);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setAngularDamping
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularDamping
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->setDamping(body->getLinearDamping(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getLinearDamping
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearDamping
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getLinearDamping();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getAngularDamping
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularDamping
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getAngularDamping();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getRestitution
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getRestitution
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getRestitution();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setRestitution
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setRestitution
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->setRestitution(value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getAngularVelocity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularVelocity
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ jmeBulletUtil::convert(env, &body->getAngularVelocity(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setAngularVelocity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularVelocity
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btVector3* vec = &btVector3();
+ jmeBulletUtil::convert(env, value, vec);
+ body->setAngularVelocity(*vec);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getLinearVelocity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearVelocity
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ jmeBulletUtil::convert(env, &body->getLinearVelocity(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setLinearVelocity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setLinearVelocity
+ (JNIEnv *env, jobject object, jlong bodyId, jobject value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btVector3* vec = &btVector3();
+ jmeBulletUtil::convert(env, value, vec);
+ body->setLinearVelocity(*vec);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyForce
+ * Signature: (JLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyForce
+ (JNIEnv *env, jobject object, jlong bodyId, jobject force, jobject location) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btVector3* vec1 = &btVector3();
+ btVector3* vec2 = &btVector3();
+ jmeBulletUtil::convert(env, force, vec1);
+ jmeBulletUtil::convert(env, location, vec2);
+ body->applyForce(*vec1, *vec2);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyCentralForce
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyCentralForce
+ (JNIEnv *env, jobject object, jlong bodyId, jobject force) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btVector3* vec1 = &btVector3();
+ jmeBulletUtil::convert(env, force, vec1);
+ body->applyCentralForce(*vec1);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyTorque
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyTorque
+ (JNIEnv *env, jobject object, jlong bodyId, jobject force) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btVector3* vec1 = &btVector3();
+ jmeBulletUtil::convert(env, force, vec1);
+ body->applyTorque(*vec1);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyImpulse
+ * Signature: (JLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyImpulse
+ (JNIEnv *env, jobject object, jlong bodyId, jobject force, jobject location) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btVector3* vec1 = &btVector3();
+ btVector3* vec2 = &btVector3();
+ jmeBulletUtil::convert(env, force, vec1);
+ jmeBulletUtil::convert(env, location, vec2);
+ body->applyImpulse(*vec1, *vec2);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyTorqueImpulse
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyTorqueImpulse
+ (JNIEnv *env, jobject object, jlong bodyId, jobject force) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btVector3* vec1 = &btVector3();
+ jmeBulletUtil::convert(env, force, vec1);
+ body->applyTorqueImpulse(*vec1);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: clearForces
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_clearForces
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->clearForces();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setCollisionShape
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setCollisionShape
+ (JNIEnv *env, jobject object, jlong bodyId, jlong shapeId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btCollisionShape* shape = (btCollisionShape*) shapeId;
+ body->setCollisionShape(shape);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: activate
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_activate
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->activate(false);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: isActive
+ * Signature: (J)Z
+ */
+ JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_isActive
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->isActive();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setSleepingThresholds
+ * Signature: (JFF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setSleepingThresholds
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat linear, jfloat angular) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->setSleepingThresholds(linear, angular);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setLinearSleepingThreshold
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setLinearSleepingThreshold
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->setSleepingThresholds(value, body->getAngularSleepingThreshold());
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setAngularSleepingThreshold
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularSleepingThreshold
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ body->setSleepingThresholds(body->getLinearSleepingThreshold(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getLinearSleepingThreshold
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearSleepingThreshold
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getLinearSleepingThreshold();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getAngularSleepingThreshold
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularSleepingThreshold
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getAngularSleepingThreshold();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getAngularFactor
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor
+ (JNIEnv *env, jobject object, jlong bodyId) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ return body->getAngularFactor().getX();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setAngularFactor
+ * Signature: (JF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularFactor
+ (JNIEnv *env, jobject object, jlong bodyId, jfloat value) {
+ btRigidBody* body = (btRigidBody*) bodyId;
+ btVector3* vec1 = &btVector3();
+ vec1->setX(value);
+ vec1->setY(value);
+ vec1->setZ(value);
+ body->setAngularFactor(*vec1);
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsRigidBody.h b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsRigidBody.h
new file mode 100644
index 000000000..aa09a620a
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsRigidBody.h
@@ -0,0 +1,415 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_objects_PhysicsRigidBody */
+
+#ifndef _Included_com_jme3_bullet_objects_PhysicsRigidBody
+#define _Included_com_jme3_bullet_objects_PhysicsRigidBody
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_NONE
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_NONE 0L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_01
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_01 1L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_02
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_02 2L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_03
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_03 4L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_04
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_04 8L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_05
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_05 16L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_06
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_06 32L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_07
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_07 64L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_08
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_08 128L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_09
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_09 256L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_10
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_10 512L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_11
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_11 1024L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_12
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_12 2048L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_13
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_13 4096L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_14
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_14 8192L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_15
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_15 16384L
+#undef com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_16
+#define com_jme3_bullet_objects_PhysicsRigidBody_COLLISION_GROUP_16 32768L
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: createRigidBody
+ * Signature: (FJJ)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_createRigidBody
+ (JNIEnv *, jobject, jfloat, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: isInWorld
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_isInWorld
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setPhysicsLocation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setPhysicsRotation
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setPhysicsRotation__JLcom_jme3_math_Matrix3f_2
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setPhysicsRotation
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setPhysicsRotation__JLcom_jme3_math_Quaternion_2
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getPhysicsLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getPhysicsLocation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getPhysicsRotation
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getPhysicsRotation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getPhysicsRotationMatrix
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getPhysicsRotationMatrix
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setKinematic
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setKinematic
+ (JNIEnv *, jobject, jlong, jboolean);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setCcdSweptSphereRadius
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setCcdSweptSphereRadius
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setCcdMotionThreshold
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setCcdMotionThreshold
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getCcdSweptSphereRadius
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getCcdSweptSphereRadius
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getCcdMotionThreshold
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getCcdMotionThreshold
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getCcdSquareMotionThreshold
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getCcdSquareMotionThreshold
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setStatic
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setStatic
+ (JNIEnv *, jobject, jlong, jboolean);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: updateMassProps
+ * Signature: (JJF)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_updateMassProps
+ (JNIEnv *, jobject, jlong, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getGravity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getGravity
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setGravity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setGravity
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getFriction
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getFriction
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setFriction
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setFriction
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setDamping
+ * Signature: (JFF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setDamping
+ (JNIEnv *, jobject, jlong, jfloat, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setAngularDamping
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularDamping
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getLinearDamping
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearDamping
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getAngularDamping
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularDamping
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getRestitution
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getRestitution
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setRestitution
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setRestitution
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getAngularVelocity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularVelocity
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setAngularVelocity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularVelocity
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getLinearVelocity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearVelocity
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setLinearVelocity
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setLinearVelocity
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyForce
+ * Signature: (JLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyForce
+ (JNIEnv *, jobject, jlong, jobject, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyCentralForce
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyCentralForce
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyTorque
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyTorque
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyImpulse
+ * Signature: (JLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyImpulse
+ (JNIEnv *, jobject, jlong, jobject, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: applyTorqueImpulse
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_applyTorqueImpulse
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: clearForces
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_clearForces
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setCollisionShape
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setCollisionShape
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: activate
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_activate
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: isActive
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_isActive
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setSleepingThresholds
+ * Signature: (JFF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setSleepingThresholds
+ (JNIEnv *, jobject, jlong, jfloat, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setLinearSleepingThreshold
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setLinearSleepingThreshold
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setAngularSleepingThreshold
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularSleepingThreshold
+ (JNIEnv *, jobject, jlong, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getLinearSleepingThreshold
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearSleepingThreshold
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getAngularSleepingThreshold
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularSleepingThreshold
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: getAngularFactor
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsRigidBody
+ * Method: setAngularFactor
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularFactor
+ (JNIEnv *, jobject, jlong, jfloat);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsVehicle.cpp b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsVehicle.cpp
new file mode 100644
index 000000000..59e8b1c7d
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsVehicle.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+
+#include "com_jme3_bullet_objects_PhysicsVehicle.h"
+#include "jmeBulletUtil.h"
+#include "BulletDynamics/Vehicle/btRaycastVehicle.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: updateWheelTransform
+ * Signature: (JIZ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_updateWheelTransform
+ (JNIEnv *env, jobject object, jlong vehicleId, jint wheel, jboolean interpolated) {
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ vehicle->updateWheelTransform(wheel, interpolated);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: createVehicleRaycaster
+ * Signature: (JJ)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_createVehicleRaycaster
+ (JNIEnv *env, jobject object, jlong bodyId, jlong spaceId) {
+ //btRigidBody* body = (btRigidBody*) bodyId;
+ btDiscreteDynamicsWorld* spsace = (btDiscreteDynamicsWorld*) spaceId;
+ btDefaultVehicleRaycaster* caster = new btDefaultVehicleRaycaster(spsace);
+ return (long) caster;
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: createRaycastVehicle
+ * Signature: (JJ)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_createRaycastVehicle
+ (JNIEnv *env, jobject object, jlong objectId, jlong casterId) {
+ btRigidBody* body = (btRigidBody*) objectId;
+ body->setActivationState(DISABLE_DEACTIVATION);
+ btVehicleRaycaster* caster = (btDefaultVehicleRaycaster*) casterId;
+ btRaycastVehicle::btVehicleTuning tuning;
+ btRaycastVehicle* vehicle = new btRaycastVehicle(tuning, body, caster);
+ return (long) vehicle;
+
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: setCoordinateSystem
+ * Signature: (JIII)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_setCoordinateSystem
+ (JNIEnv *env, jobject object, jlong vehicleId, jint right, jint up, jint forward) {
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ vehicle->setCoordinateSystem(right, up, forward);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: addWheel
+ * Signature: (JLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;FFLcom/jme3/bullet/objects/infos/VehicleTuning;Z)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_addWheel
+ (JNIEnv *env, jobject object, jlong vehicleId, jobject location, jobject direction, jobject axle, jfloat restLength, jfloat radius, jobject tuning, jboolean frontWheel) {
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ btVector3* vec1 = &btVector3();
+ btVector3* vec2 = &btVector3();
+ btVector3* vec3 = &btVector3();
+ jmeBulletUtil::convert(env, location, vec1);
+ jmeBulletUtil::convert(env, direction, vec2);
+ jmeBulletUtil::convert(env, axle, vec3);
+ btRaycastVehicle::btVehicleTuning tune;
+ btWheelInfo* info = &vehicle->addWheel(*vec1, *vec2, *vec3, restLength, radius, tune, frontWheel);
+ return (long) info;
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: resetSuspension
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_resetSuspension
+ (JNIEnv *env, jobject object, jlong vehicleId) {
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ vehicle->resetSuspension();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: applyEngineForce
+ * Signature: (JIF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_applyEngineForce
+ (JNIEnv *env, jobject object, jlong vehicleId, jint wheel, jfloat force) {
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ vehicle->applyEngineForce(force, wheel);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: steer
+ * Signature: (JIF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_steer
+ (JNIEnv *env, jobject object, jlong vehicleId, jint wheel, jfloat value) {
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ vehicle->setSteeringValue(value, wheel);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: brake
+ * Signature: (JIF)F
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_brake
+ (JNIEnv *env, jobject object, jlong vehicleId, jint wheel, jfloat value) {
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ vehicle->setBrake(value, wheel);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: getCurrentVehicleSpeedKmHour
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_getCurrentVehicleSpeedKmHour
+ (JNIEnv *env, jobject object, jlong vehicleId) {
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ return vehicle->getCurrentSpeedKmHour();
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: getForwardVector
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_getForwardVector
+ (JNIEnv *env, jobject object, jlong vehicleId, jobject out) {
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ jmeBulletUtil::convert(env, &vehicle->getForwardVector(), out);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: finalizeNative
+ * Signature: (JJ)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_finalizeNative
+ (JNIEnv *env, jobject object, jlong casterId, jlong vehicleId) {
+ btVehicleRaycaster* rayCaster = (btVehicleRaycaster*) casterId;
+ btRaycastVehicle* vehicle = (btRaycastVehicle*) vehicleId;
+ delete(vehicle);
+ delete(rayCaster);
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsVehicle.h b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsVehicle.h
new file mode 100644
index 000000000..288caab6c
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_PhysicsVehicle.h
@@ -0,0 +1,143 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_objects_PhysicsVehicle */
+
+#ifndef _Included_com_jme3_bullet_objects_PhysicsVehicle
+#define _Included_com_jme3_bullet_objects_PhysicsVehicle
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_NONE
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_NONE 0L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_01
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_01 1L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_02
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_02 2L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_03
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_03 4L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_04
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_04 8L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_05
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_05 16L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_06
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_06 32L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_07
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_07 64L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_08
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_08 128L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_09
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_09 256L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_10
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_10 512L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_11
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_11 1024L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_12
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_12 2048L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_13
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_13 4096L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_14
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_14 8192L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_15
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_15 16384L
+#undef com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_16
+#define com_jme3_bullet_objects_PhysicsVehicle_COLLISION_GROUP_16 32768L
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: updateWheelTransform
+ * Signature: (JIZ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_updateWheelTransform
+ (JNIEnv *, jobject, jlong, jint, jboolean);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: createVehicleRaycaster
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_createVehicleRaycaster
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: createRaycastVehicle
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_createRaycastVehicle
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: setCoordinateSystem
+ * Signature: (JIII)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_setCoordinateSystem
+ (JNIEnv *, jobject, jlong, jint, jint, jint);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: addWheel
+ * Signature: (JLcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;FFLcom/jme3/bullet/objects/infos/VehicleTuning;Z)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_addWheel
+ (JNIEnv *, jobject, jlong, jobject, jobject, jobject, jfloat, jfloat, jobject, jboolean);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: resetSuspension
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_resetSuspension
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: applyEngineForce
+ * Signature: (JIF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_applyEngineForce
+ (JNIEnv *, jobject, jlong, jint, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: steer
+ * Signature: (JIF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_steer
+ (JNIEnv *, jobject, jlong, jint, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: brake
+ * Signature: (JIF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_brake
+ (JNIEnv *, jobject, jlong, jint, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: getCurrentVehicleSpeedKmHour
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_getCurrentVehicleSpeedKmHour
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: getForwardVector
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_getForwardVector
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_PhysicsVehicle
+ * Method: finalizeNative
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsVehicle_finalizeNative
+ (JNIEnv *, jobject, jlong, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_VehicleWheel.cpp b/engine/src/bullet/native/com_jme3_bullet_objects_VehicleWheel.cpp
new file mode 100644
index 000000000..6b493c53a
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_VehicleWheel.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+
+#include "com_jme3_bullet_objects_VehicleWheel.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getWheelLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getWheelLocation
+ (JNIEnv *env, jobject object, jlong wheelId, jobject out) {
+ btWheelInfo* wheel = (btWheelInfo*) wheelId;
+ jmeBulletUtil::convert(env, &wheel->m_worldTransform.getOrigin(), out);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getWheelRotation
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getWheelRotation
+ (JNIEnv *env, jobject object, jlong wheelId, jobject out) {
+ btWheelInfo* wheel = (btWheelInfo*) wheelId;
+ jmeBulletUtil::convert(env, &wheel->m_worldTransform.getBasis(), out);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: applyInfo
+ * Signature: (JFFFFFFFFZF)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_applyInfo
+ (JNIEnv *env, jobject object, jlong wheelId, jfloat suspensionStiffness, jfloat wheelsDampingRelaxation, jfloat wheelsDampingCompression, jfloat frictionSlip, jfloat rollInfluence, jfloat maxSuspensionTravelCm, jfloat maxSuspensionForce, jfloat radius, jboolean frontWheel, jfloat restLength) {
+ btWheelInfo* wheelInfo = (btWheelInfo*) wheelId;
+ wheelInfo->m_suspensionStiffness = suspensionStiffness;
+ wheelInfo->m_wheelsDampingRelaxation = wheelsDampingRelaxation;
+ wheelInfo->m_wheelsDampingCompression = wheelsDampingCompression;
+ wheelInfo->m_frictionSlip = frictionSlip;
+ wheelInfo->m_rollInfluence = rollInfluence;
+ wheelInfo->m_maxSuspensionTravelCm = maxSuspensionTravelCm;
+ wheelInfo->m_maxSuspensionForce = maxSuspensionForce;
+ wheelInfo->m_wheelsRadius = radius;
+ wheelInfo->m_bIsFrontWheel = frontWheel;
+ wheelInfo->m_suspensionRestLength1 = restLength;
+
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getCollisionLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getCollisionLocation
+ (JNIEnv *env, jobject object, jlong wheelId, jobject out) {
+ btWheelInfo* wheel = (btWheelInfo*) wheelId;
+ jmeBulletUtil::convert(env, &wheel->m_raycastInfo.m_contactPointWS, out);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getCollisionNormal
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getCollisionNormal
+ (JNIEnv *env, jobject object, jlong wheelId, jobject out) {
+ btWheelInfo* wheel = (btWheelInfo*) wheelId;
+ jmeBulletUtil::convert(env, &wheel->m_raycastInfo.m_contactNormalWS, out);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getSkidInfo
+ * Signature: (J)F
+ */
+ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getSkidInfo
+ (JNIEnv *env, jobject object, jlong wheelId) {
+ btWheelInfo* wheel = (btWheelInfo*) wheelId;
+ return wheel->m_skidInfo;
+ }
+
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_finalizeNative
+ (JNIEnv *env, jobject object, jlong wheelId){
+ btWheelInfo* wheel = (btWheelInfo*) wheelId;
+ delete(wheel);
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_VehicleWheel.h b/engine/src/bullet/native/com_jme3_bullet_objects_VehicleWheel.h
new file mode 100644
index 000000000..6f136a829
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_VehicleWheel.h
@@ -0,0 +1,69 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_objects_VehicleWheel */
+
+#ifndef _Included_com_jme3_bullet_objects_VehicleWheel
+#define _Included_com_jme3_bullet_objects_VehicleWheel
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getWheelLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getWheelLocation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getWheelRotation
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getWheelRotation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: applyInfo
+ * Signature: (JFFFFFFFFZF)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_applyInfo
+ (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jboolean, jfloat);
+
+/*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getCollisionLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getCollisionLocation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getCollisionNormal
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getCollisionNormal
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: getSkidInfo
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_VehicleWheel_getSkidInfo
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_jme3_bullet_objects_VehicleWheel
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_VehicleWheel_finalizeNative
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_infos_RigidBodyMotionState.cpp b/engine/src/bullet/native/com_jme3_bullet_objects_infos_RigidBodyMotionState.cpp
new file mode 100644
index 000000000..ff9849043
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_infos_RigidBodyMotionState.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_objects_infos_RigidBodyMotionState.h"
+#include "jmeBulletUtil.h"
+#include "jmeMotionState.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: createMotionState
+ * Signature: ()J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_createMotionState
+ (JNIEnv *env, jobject object) {
+ jmeMotionState* motionState = new jmeMotionState();
+ return (long) motionState;
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: applyTransform
+ * Signature: (JLcom/jme3/math/Vector3f;Lcom/jme3/math/Quaternion;)Z
+ */
+ JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_applyTransform
+ (JNIEnv *env, jobject object, jlong stateId, jobject location, jobject rotation) {
+ jmeMotionState* motionState = (jmeMotionState*) stateId;
+ return motionState->applyTransform(env, location, rotation);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: getWorldLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_getWorldLocation
+ (JNIEnv *env, jobject object, jlong stateId, jobject value) {
+ jmeMotionState* motionState = (jmeMotionState*) stateId;
+ jmeBulletUtil::convert(env, &motionState->worldTransform.getOrigin(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: getWorldRotation
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_getWorldRotation
+ (JNIEnv *env, jobject object, jlong stateId, jobject value) {
+ jmeMotionState* motionState = (jmeMotionState*) stateId;
+ jmeBulletUtil::convert(env, &motionState->worldTransform.getBasis(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: getWorldRotationQuat
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_getWorldRotationQuat
+ (JNIEnv *env, jobject object, jlong stateId, jobject value) {
+ jmeMotionState* motionState = (jmeMotionState*) stateId;
+ jmeBulletUtil::convertQuat(env, &motionState->worldTransform.getBasis(), value);
+ }
+
+ /*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_finalizeNative
+ (JNIEnv *env, jobject object, jlong stateId){
+ jmeMotionState* motionState = (jmeMotionState*) stateId;
+ delete(motionState);
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_objects_infos_RigidBodyMotionState.h b/engine/src/bullet/native/com_jme3_bullet_objects_infos_RigidBodyMotionState.h
new file mode 100644
index 000000000..7939038d2
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_objects_infos_RigidBodyMotionState.h
@@ -0,0 +1,61 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_objects_infos_RigidBodyMotionState */
+
+#ifndef _Included_com_jme3_bullet_objects_infos_RigidBodyMotionState
+#define _Included_com_jme3_bullet_objects_infos_RigidBodyMotionState
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: createMotionState
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_createMotionState
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: applyTransform
+ * Signature: (JLcom/jme3/math/Vector3f;Lcom/jme3/math/Quaternion;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_applyTransform
+ (JNIEnv *, jobject, jlong, jobject, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: getWorldLocation
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_getWorldLocation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: getWorldRotation
+ * Signature: (JLcom/jme3/math/Matrix3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_getWorldRotation
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: getWorldRotationQuat
+ * Signature: (JLcom/jme3/math/Quaternion;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_getWorldRotationQuat
+ (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class: com_jme3_bullet_objects_infos_RigidBodyMotionState
+ * Method: finalizeNative
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_infos_RigidBodyMotionState_finalizeNative
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_util_DebugShapeFactory.cpp b/engine/src/bullet/native/com_jme3_bullet_util_DebugShapeFactory.cpp
new file mode 100644
index 000000000..302db41cc
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_util_DebugShapeFactory.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen, CJ Hare
+ */
+#include "com_jme3_bullet_util_DebugShapeFactory.h"
+#include "jmeBulletUtil.h"
+#include "BulletCollision/CollisionShapes/btShapeHull.h"
+
+class DebugCallback : public btTriangleCallback, public btInternalTriangleIndexCallback {
+public:
+ JNIEnv* env;
+ jobject callback;
+
+ DebugCallback(JNIEnv* env, jobject object) {
+ this->env = env;
+ this->callback = object;
+ }
+
+ virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) {
+ processTriangle(triangle, partId, triangleIndex);
+ }
+
+ virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) {
+ btVector3 vertexA, vertexB, vertexC;
+ vertexA = triangle[0];
+ vertexB = triangle[1];
+ vertexC = triangle[2];
+ env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexA.getX(), vertexA.getY(), vertexA.getZ(), partId, triangleIndex);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+// triangle =
+ env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexB.getX(), vertexB.getY(), vertexB.getZ(), partId, triangleIndex);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexC.getX(), vertexC.getY(), vertexC.getZ(), partId, triangleIndex);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ }
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Inaccessible static: _00024assertionsDisabled */
+
+ /*
+ * Class: com_jme3_bullet_util_DebugShapeFactory
+ * Method: getVertices
+ * Signature: (JLcom/jme3/bullet/util/DebugMeshCallback;)V
+ */
+ JNIEXPORT void JNICALL Java_com_jme3_bullet_util_DebugShapeFactory_getVertices
+ (JNIEnv *env, jclass clazz, jlong shapeId, jobject callback) {
+ btCollisionShape* shape = (btCollisionShape*) shapeId;
+ if (shape->isConcave()) {
+ fprintf(stdout,"Concave shape");
+ fflush(stdout);
+ btConcaveShape* concave = (btConcaveShape*) shape;
+ DebugCallback* clb = new DebugCallback(env, callback);
+ btVector3 min = btVector3(-1e30, -1e30, -1e30);
+ btVector3 max = btVector3(1e30, 1e30, 1e30);
+ concave->processAllTriangles(clb, min, max);
+ delete(clb);
+ } else if (shape->isConvex()) {
+ fprintf(stdout,"Convex shape");
+ fflush(stdout);
+ btConvexShape* convexShape = (btConvexShape*) shape;
+ // Check there is a hull shape to render
+ if (convexShape->getUserPointer() == NULL) {
+ // create a hull approximation
+ btShapeHull* hull = &btShapeHull(convexShape);
+ float margin = convexShape->getMargin();
+ hull->buildHull(margin);
+ convexShape->setUserPointer(hull);
+ }
+
+ btShapeHull* hull = (btShapeHull*) convexShape->getUserPointer();
+
+ int numberOfTriangles = hull->numTriangles();
+ int numberOfFloats = 3 * 3 * numberOfTriangles;
+ int byteBufferSize = numberOfFloats * 4;
+
+ // Loop variables
+ const unsigned int* hullIndices = hull->getIndexPointer();
+ const btVector3* hullVertices = hull->getVertexPointer();
+ btVector3 vertexA, vertexB, vertexC;
+ int index = 0;
+
+ for (int i = 0; i < numberOfTriangles; i++) {
+ // Grab the data for this triangle from the hull
+ vertexA = hullVertices[hullIndices[index++]];
+ vertexB = hullVertices[hullIndices[index++]];
+ vertexC = hullVertices[hullIndices[index++]];
+
+ // Put the verticies into the vertex buffer
+ env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexA.getX(), vertexA.getY(), vertexA.getZ());
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexB.getX(), vertexB.getY(), vertexB.getZ());
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->CallVoidMethod(callback, jmeClasses::DebugMeshCallback_addVector, vertexC.getX(), vertexC.getY(), vertexC.getZ());
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ }
+
+ convexShape->setUserPointer(NULL);
+ }
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_util_DebugShapeFactory.h b/engine/src/bullet/native/com_jme3_bullet_util_DebugShapeFactory.h
new file mode 100644
index 000000000..45eca74cd
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_util_DebugShapeFactory.h
@@ -0,0 +1,22 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_util_DebugShapeFactory */
+
+#ifndef _Included_com_jme3_bullet_util_DebugShapeFactory
+#define _Included_com_jme3_bullet_util_DebugShapeFactory
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Inaccessible static: _00024assertionsDisabled */
+/*
+ * Class: com_jme3_bullet_util_DebugShapeFactory
+ * Method: getVertices
+ * Signature: (JLcom/jme3/bullet/util/DebugMeshCallback;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_util_DebugShapeFactory_getVertices
+ (JNIEnv *, jclass, jlong, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_util_NativeMeshUtil.cpp b/engine/src/bullet/native/com_jme3_bullet_util_NativeMeshUtil.cpp
new file mode 100644
index 000000000..c58e363f7
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_util_NativeMeshUtil.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Author: Normen Hansen
+ */
+#include "com_jme3_bullet_util_NativeMeshUtil.h"
+#include "jmeBulletUtil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Class: com_jme3_bullet_util_NativeMeshUtil
+ * Method: createTriangleIndexVertexArray
+ * Signature: (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;IIII)J
+ */
+ JNIEXPORT jlong JNICALL Java_com_jme3_bullet_util_NativeMeshUtil_createTriangleIndexVertexArray
+ (JNIEnv * env, jclass cls, jobject triangleIndexBase, jobject vertexIndexBase, jint numTriangles, jint numVertices, jint vertexStride, jint triangleIndexStride) {
+ int* triangles = (int*) env->GetDirectBufferAddress(triangleIndexBase);
+ float* vertices = (float*) env->GetDirectBufferAddress(vertexIndexBase);
+ btTriangleIndexVertexArray* array = new btTriangleIndexVertexArray(numTriangles, triangles, triangleIndexStride, numVertices, vertices, vertexStride);
+ return (long) array;
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/src/bullet/native/com_jme3_bullet_util_NativeMeshUtil.h b/engine/src/bullet/native/com_jme3_bullet_util_NativeMeshUtil.h
new file mode 100644
index 000000000..0be9f4d5a
--- /dev/null
+++ b/engine/src/bullet/native/com_jme3_bullet_util_NativeMeshUtil.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_jme3_bullet_util_NativeMeshUtil */
+
+#ifndef _Included_com_jme3_bullet_util_NativeMeshUtil
+#define _Included_com_jme3_bullet_util_NativeMeshUtil
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_jme3_bullet_util_NativeMeshUtil
+ * Method: createTriangleIndexVertexArray
+ * Signature: (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;IIII)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jme3_bullet_util_NativeMeshUtil_createTriangleIndexVertexArray
+ (JNIEnv *, jclass, jobject, jobject, jint, jint, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/engine/src/bullet/native/jmeBulletUtil.cpp b/engine/src/bullet/native/jmeBulletUtil.cpp
new file mode 100644
index 000000000..e0a20ed2d
--- /dev/null
+++ b/engine/src/bullet/native/jmeBulletUtil.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include
+#include "jmeBulletUtil.h"
+
+/**
+ * Author: Normen Hansen
+ */
+void jmeBulletUtil::convert(JNIEnv* env, jobject in, btVector3* out) {
+ if (in == NULL || out == NULL) {
+ jmeClasses::throwNPE(env);
+ }
+ float x = env->GetFloatField(in, jmeClasses::Vector3f_x);//env->CallFloatMethod(in, jmeClasses::Vector3f_getX);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float y = env->GetFloatField(in, jmeClasses::Vector3f_y);//env->CallFloatMethod(in, jmeClasses::Vector3f_getY);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float z = env->GetFloatField(in, jmeClasses::Vector3f_z);//env->CallFloatMethod(in, jmeClasses::Vector3f_getZ);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ out->setX(x);
+ out->setY(y);
+ out->setZ(z);
+}
+
+void jmeBulletUtil::convert(JNIEnv* env, const btVector3* in, jobject out) {
+ if (in == NULL || out == NULL) {
+ jmeClasses::throwNPE(env);
+ }
+ float x = in->getX();
+ float y = in->getY();
+ float z = in->getZ();
+ env->SetFloatField(out, jmeClasses::Vector3f_x, x);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Vector3f_y, y);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Vector3f_z, z);
+// env->CallObjectMethod(out, jmeClasses::Vector3f_set, x, y, z);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+}
+
+void jmeBulletUtil::convert(JNIEnv* env, jobject in, btMatrix3x3* out) {
+ if (in == NULL || out == NULL) {
+ jmeClasses::throwNPE(env);
+ }
+ float m00 = env->GetFloatField(in, jmeClasses::Matrix3f_m00);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float m01 = env->GetFloatField(in, jmeClasses::Matrix3f_m01);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float m02 = env->GetFloatField(in, jmeClasses::Matrix3f_m02);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float m10 = env->GetFloatField(in, jmeClasses::Matrix3f_m10);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float m11 = env->GetFloatField(in, jmeClasses::Matrix3f_m11);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float m12 = env->GetFloatField(in, jmeClasses::Matrix3f_m12);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float m20 = env->GetFloatField(in, jmeClasses::Matrix3f_m20);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float m21 = env->GetFloatField(in, jmeClasses::Matrix3f_m21);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float m22 = env->GetFloatField(in, jmeClasses::Matrix3f_m22);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ out->setValue(m00, m01, m02, m10, m11, m12, m20, m21, m22);
+}
+
+void jmeBulletUtil::convert(JNIEnv* env, const btMatrix3x3* in, jobject out) {
+ if (in == NULL || out == NULL) {
+ jmeClasses::throwNPE(env);
+ }
+ float m00 = in->getRow(0).m_floats[0];
+ float m01 = in->getRow(0).m_floats[1];
+ float m02 = in->getRow(0).m_floats[2];
+ float m10 = in->getRow(1).m_floats[0];
+ float m11 = in->getRow(1).m_floats[1];
+ float m12 = in->getRow(1).m_floats[2];
+ float m20 = in->getRow(2).m_floats[0];
+ float m21 = in->getRow(2).m_floats[1];
+ float m22 = in->getRow(2).m_floats[2];
+ env->SetFloatField(out, jmeClasses::Matrix3f_m00, m00);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Matrix3f_m01, m01);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Matrix3f_m02, m02);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Matrix3f_m10, m10);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Matrix3f_m11, m11);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Matrix3f_m12, m12);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Matrix3f_m20, m20);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Matrix3f_m21, m21);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Matrix3f_m22, m22);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+}
+
+void jmeBulletUtil::convertQuat(JNIEnv* env, jobject in, btMatrix3x3* 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);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float z = env->GetFloatField(in, jmeClasses::Quaternion_z);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ float w = env->GetFloatField(in, jmeClasses::Quaternion_w);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+
+ float norm = w * w + x * x + y * y + z * z;
+ float s = (norm == 1.0) ? 2.0 : (norm > 0.1) ? 2.0 / norm : 0.0;
+
+ // compute xs/ys/zs first to save 6 multiplications, since xs/ys/zs
+ // will be used 2-4 times each.
+ float xs = x * s;
+ float ys = y * s;
+ float zs = z * s;
+ float xx = x * xs;
+ float xy = x * ys;
+ float xz = x * zs;
+ float xw = w * xs;
+ float yy = y * ys;
+ float yz = y * zs;
+ float yw = w * ys;
+ float zz = z * zs;
+ float zw = w * zs;
+
+ // using s=2/norm (instead of 1/norm) saves 9 multiplications by 2 here
+ out->setValue(1.0 - (yy + zz), (xy - zw), (xz + yw),
+ (xy + zw), 1 - (xx + zz), (yz - xw),
+ (xz - yw), (yz + xw), 1.0 - (xx + yy));
+}
+
+void jmeBulletUtil::convertQuat(JNIEnv* env, const btMatrix3x3* in, jobject out) {
+ if (in == NULL || out == NULL) {
+ jmeClasses::throwNPE(env);
+ }
+ // the trace is the sum of the diagonal elements; see
+ // http://mathworld.wolfram.com/MatrixTrace.html
+ float t = in->getRow(0).m_floats[0] + in->getRow(1).m_floats[1] + in->getRow(2).m_floats[2];
+ float w, x, y, z;
+ // we protect the division by s by ensuring that s>=1
+ if (t >= 0) { // |w| >= .5
+ float s = sqrt(t + 1); // |s|>=1 ...
+ w = 0.5f * s;
+ s = 0.5f / s; // so this division isn't bad
+ x = (in->getRow(2).m_floats[1] - in->getRow(1).m_floats[2]) * s;
+ y = (in->getRow(0).m_floats[2] - in->getRow(2).m_floats[0]) * s;
+ z = (in->getRow(1).m_floats[0] - in->getRow(0).m_floats[1]) * s;
+ } else if ((in->getRow(0).m_floats[0] > in->getRow(1).m_floats[1]) && (in->getRow(0).m_floats[0] > in->getRow(2).m_floats[2])) {
+ float s = sqrt(1.0f + in->getRow(0).m_floats[0] - in->getRow(1).m_floats[1] - in->getRow(2).m_floats[2]); // |s|>=1
+ x = s * 0.5f; // |x| >= .5
+ s = 0.5f / s;
+ y = (in->getRow(1).m_floats[0] + in->getRow(0).m_floats[1]) * s;
+ z = (in->getRow(0).m_floats[2] + in->getRow(2).m_floats[0]) * s;
+ w = (in->getRow(2).m_floats[1] - in->getRow(1).m_floats[2]) * s;
+ } else if (in->getRow(1).m_floats[1] > in->getRow(2).m_floats[2]) {
+ float s = sqrt(1.0f + in->getRow(1).m_floats[1] - in->getRow(0).m_floats[0] - in->getRow(2).m_floats[2]); // |s|>=1
+ y = s * 0.5f; // |y| >= .5
+ s = 0.5f / s;
+ x = (in->getRow(1).m_floats[0] + in->getRow(0).m_floats[1]) * s;
+ z = (in->getRow(2).m_floats[1] + in->getRow(1).m_floats[2]) * s;
+ w = (in->getRow(0).m_floats[2] - in->getRow(2).m_floats[0]) * s;
+ } else {
+ float s = sqrt(1.0f + in->getRow(2).m_floats[2] - in->getRow(0).m_floats[0] - in->getRow(1).m_floats[1]); // |s|>=1
+ z = s * 0.5f; // |z| >= .5
+ s = 0.5f / s;
+ x = (in->getRow(0).m_floats[2] + in->getRow(2).m_floats[0]) * s;
+ y = (in->getRow(2).m_floats[1] + in->getRow(1).m_floats[2]) * s;
+ w = (in->getRow(1).m_floats[0] - in->getRow(0).m_floats[1]) * s;
+ }
+
+ env->SetFloatField(out, jmeClasses::Quaternion_x, x);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Quaternion_y, y);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Quaternion_z, z);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ env->SetFloatField(out, jmeClasses::Quaternion_w, w);
+// env->CallObjectMethod(out, jmeClasses::Quaternion_set, x, y, z, w);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+}
diff --git a/engine/src/bullet/native/jmeBulletUtil.h b/engine/src/bullet/native/jmeBulletUtil.h
new file mode 100644
index 000000000..d231bba73
--- /dev/null
+++ b/engine/src/bullet/native/jmeBulletUtil.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "jmeClasses.h"
+#include "btBulletDynamicsCommon.h"
+#include "btBulletCollisionCommon.h"
+#include "LinearMath/btVector3.h"
+
+/**
+ * Author: Normen Hansen
+ */
+class jmeBulletUtil{
+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, const btMatrix3x3* in, jobject out);
+ static void convertQuat(JNIEnv* env, jobject in, btMatrix3x3* out);
+ static void convertQuat(JNIEnv* env, const btMatrix3x3* in, jobject out);
+private:
+ jmeBulletUtil(){};
+ ~jmeBulletUtil(){};
+
+};
\ No newline at end of file
diff --git a/engine/src/bullet/native/jmeClasses.cpp b/engine/src/bullet/native/jmeClasses.cpp
new file mode 100644
index 000000000..c9e652e48
--- /dev/null
+++ b/engine/src/bullet/native/jmeClasses.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "jmeClasses.h"
+
+/**
+ * Author: Normen Hansen
+ */
+//public fields
+jclass jmeClasses::PhysicsSpace;
+jmethodID jmeClasses::PhysicsSpace_preTick;
+jmethodID jmeClasses::PhysicsSpace_postTick;
+
+jclass jmeClasses::Vector3f;
+jmethodID jmeClasses::Vector3f_set;
+jmethodID jmeClasses::Vector3f_toArray;
+jmethodID jmeClasses::Vector3f_getX;
+jmethodID jmeClasses::Vector3f_getY;
+jmethodID jmeClasses::Vector3f_getZ;
+jfieldID jmeClasses::Vector3f_x;
+jfieldID jmeClasses::Vector3f_y;
+jfieldID jmeClasses::Vector3f_z;
+
+jclass jmeClasses::Quaternion;
+jmethodID jmeClasses::Quaternion_set;
+jmethodID jmeClasses::Quaternion_getX;
+jmethodID jmeClasses::Quaternion_getY;
+jmethodID jmeClasses::Quaternion_getZ;
+jmethodID jmeClasses::Quaternion_getW;
+jfieldID jmeClasses::Quaternion_x;
+jfieldID jmeClasses::Quaternion_y;
+jfieldID jmeClasses::Quaternion_z;
+jfieldID jmeClasses::Quaternion_w;
+
+jclass jmeClasses::Matrix3f;
+jmethodID jmeClasses::Matrix3f_set;
+jmethodID jmeClasses::Matrix3f_get;
+jfieldID jmeClasses::Matrix3f_m00;
+jfieldID jmeClasses::Matrix3f_m01;
+jfieldID jmeClasses::Matrix3f_m02;
+jfieldID jmeClasses::Matrix3f_m10;
+jfieldID jmeClasses::Matrix3f_m11;
+jfieldID jmeClasses::Matrix3f_m12;
+jfieldID jmeClasses::Matrix3f_m20;
+jfieldID jmeClasses::Matrix3f_m21;
+jfieldID jmeClasses::Matrix3f_m22;
+
+jclass jmeClasses::DebugMeshCallback;
+jmethodID jmeClasses::DebugMeshCallback_addVector;
+
+//private fields
+//JNIEnv* jmeClasses::env;
+JavaVM* jmeClasses::vm;
+
+void jmeClasses::initJavaClasses(JNIEnv* env) {
+// if (env != NULL) {
+// fprintf(stdout, "Check Java VM state\n");
+// fflush(stdout);
+// int res = vm->AttachCurrentThread((void**) &jmeClasses::env, NULL);
+// if (res < 0) {
+// fprintf(stdout, "** ERROR: getting Java env!\n");
+// if (res == JNI_EVERSION) fprintf(stdout, "GetEnv Error because of different JNI Version!\n");
+// fflush(stdout);
+// }
+// return;
+// }
+ if(PhysicsSpace!=NULL) return;
+ fprintf(stdout, "Bullet-Native: Initializing java classes\n");
+ fflush(stdout);
+// jmeClasses::env = env;
+ env->GetJavaVM(&vm);
+
+ PhysicsSpace = env->FindClass("com/jme3/bullet/PhysicsSpace");
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+
+ PhysicsSpace_preTick = env->GetMethodID(PhysicsSpace, "preTick_native", "(F)V");
+ PhysicsSpace_postTick = env->GetMethodID(PhysicsSpace, "postTick_native", "(F)V");
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+
+ Vector3f = env->FindClass("com/jme3/math/Vector3f");
+ Vector3f_set = env->GetMethodID(Vector3f, "set", "(FFF)Lcom/jme3/math/Vector3f;");
+ Vector3f_toArray = env->GetMethodID(Vector3f, "toArray", "([F)[F");
+ Vector3f_getX = env->GetMethodID(Vector3f, "getX", "()F");
+ Vector3f_getY = env->GetMethodID(Vector3f, "getY", "()F");
+ Vector3f_getZ = env->GetMethodID(Vector3f, "getZ", "()F");
+ Vector3f_x = env->GetFieldID(Vector3f, "x", "F");
+ Vector3f_y = env->GetFieldID(Vector3f, "y", "F");
+ Vector3f_z = env->GetFieldID(Vector3f, "z", "F");
+
+ Quaternion = env->FindClass("com/jme3/math/Quaternion");
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ Quaternion_set = env->GetMethodID(Quaternion, "set", "(FFFF)Lcom/jme3/math/Quaternion;");
+ Quaternion_getW = env->GetMethodID(Quaternion, "getW", "()F");
+ Quaternion_getX = env->GetMethodID(Quaternion, "getX", "()F");
+ Quaternion_getY = env->GetMethodID(Quaternion, "getY", "()F");
+ Quaternion_getZ = env->GetMethodID(Quaternion, "getZ", "()F");
+ Quaternion_x = env->GetFieldID(Quaternion, "x", "F");
+ Quaternion_y = env->GetFieldID(Quaternion, "y", "F");
+ Quaternion_z = env->GetFieldID(Quaternion, "z", "F");
+ Quaternion_w = env->GetFieldID(Quaternion, "w", "F");
+
+ Matrix3f = env->FindClass("com/jme3/math/Matrix3f");
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ Matrix3f_set = env->GetMethodID(Matrix3f, "set", "(IIF)Lcom/jme3/math/Matrix3f;");
+ Matrix3f_get = env->GetMethodID(Matrix3f, "get", "(II)F");
+ Matrix3f_m00 = env->GetFieldID(Matrix3f, "m00", "F");
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+ Matrix3f_m01 = env->GetFieldID(Matrix3f, "m01", "F");
+ Matrix3f_m02 = env->GetFieldID(Matrix3f, "m02", "F");
+ Matrix3f_m10 = env->GetFieldID(Matrix3f, "m10", "F");
+ Matrix3f_m11 = env->GetFieldID(Matrix3f, "m11", "F");
+ Matrix3f_m12 = env->GetFieldID(Matrix3f, "m12", "F");
+ Matrix3f_m20 = env->GetFieldID(Matrix3f, "m20", "F");
+ Matrix3f_m21 = env->GetFieldID(Matrix3f, "m21", "F");
+ Matrix3f_m22 = env->GetFieldID(Matrix3f, "m22", "F");
+
+ DebugMeshCallback = env->FindClass("com/jme3/bullet/util/DebugMeshCallback");
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+
+ DebugMeshCallback_addVector = env->GetMethodID(DebugMeshCallback, "addVector", "(FFFII)V");
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+}
+
+void jmeClasses::throwNPE(JNIEnv* env) {
+ if (env == NULL) return;
+ jclass newExc = env->FindClass("java/lang/NullPointerException");
+ env->ThrowNew(newExc, "");
+ return;
+}
diff --git a/engine/src/bullet/native/jmeClasses.h b/engine/src/bullet/native/jmeClasses.h
new file mode 100644
index 000000000..b4cbef1f9
--- /dev/null
+++ b/engine/src/bullet/native/jmeClasses.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include
+
+/**
+ * Author: Normen Hansen
+ */
+
+class jmeClasses {
+public:
+ static void initJavaClasses(JNIEnv* env);
+// static JNIEnv* env;
+ static JavaVM* vm;
+ static jclass PhysicsSpace;
+ static jmethodID PhysicsSpace_preTick;
+ static jmethodID PhysicsSpace_postTick;
+
+ static jclass Vector3f;
+ static jmethodID Vector3f_set;
+ static jmethodID Vector3f_getX;
+ static jmethodID Vector3f_getY;
+ static jmethodID Vector3f_getZ;
+ static jmethodID Vector3f_toArray;
+ static jfieldID Vector3f_x;
+ static jfieldID Vector3f_y;
+ static jfieldID Vector3f_z;
+
+ static jclass Quaternion;
+ static jmethodID Quaternion_set;
+ static jmethodID Quaternion_getX;
+ static jmethodID Quaternion_getY;
+ static jmethodID Quaternion_getZ;
+ static jmethodID Quaternion_getW;
+ static jfieldID Quaternion_x;
+ static jfieldID Quaternion_y;
+ static jfieldID Quaternion_z;
+ static jfieldID Quaternion_w;
+
+ static jclass Matrix3f;
+ static jmethodID Matrix3f_get;
+ static jmethodID Matrix3f_set;
+ static jfieldID Matrix3f_m00;
+ static jfieldID Matrix3f_m01;
+ static jfieldID Matrix3f_m02;
+ static jfieldID Matrix3f_m10;
+ static jfieldID Matrix3f_m11;
+ static jfieldID Matrix3f_m12;
+ static jfieldID Matrix3f_m20;
+ static jfieldID Matrix3f_m21;
+ static jfieldID Matrix3f_m22;
+
+ static jclass DebugMeshCallback;
+ static jmethodID DebugMeshCallback_addVector;
+
+ static void throwNPE(JNIEnv* env);
+private:
+ jmeClasses(){};
+ ~jmeClasses(){};
+};
\ No newline at end of file
diff --git a/engine/src/bullet/native/jmeMotionState.cpp b/engine/src/bullet/native/jmeMotionState.cpp
new file mode 100644
index 000000000..c37e555d5
--- /dev/null
+++ b/engine/src/bullet/native/jmeMotionState.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "jmeMotionState.h"
+#include "jmeBulletUtil.h"
+
+/**
+ * Author: Normen Hansen
+ */
+
+jmeMotionState::jmeMotionState() {
+ trans = new btTransform();
+ worldTransform = *trans;
+ dirty = true;
+}
+
+void jmeMotionState::getWorldTransform(btTransform& worldTrans) const {
+ worldTrans = worldTransform;
+}
+
+void jmeMotionState::setWorldTransform(const btTransform& worldTrans) {
+ worldTransform = worldTrans;
+ dirty = true;
+}
+
+void jmeMotionState::setKinematicTransform(const btTransform& worldTrans) {
+ worldTransform = worldTrans;
+ dirty = true;
+}
+
+void jmeMotionState::setKinematicLocation(JNIEnv* env, jobject location) {
+ jmeBulletUtil::convert(env, location, &worldTransform.getOrigin());
+ dirty = true;
+}
+
+void jmeMotionState::setKinematicRotation(JNIEnv* env, jobject rotation) {
+ jmeBulletUtil::convert(env, rotation, &worldTransform.getBasis());
+ dirty = true;
+}
+
+void jmeMotionState::setKinematicRotationQuat(JNIEnv* env, jobject rotation) {
+ jmeBulletUtil::convertQuat(env, rotation, &worldTransform.getBasis());
+ dirty = true;
+}
+
+bool jmeMotionState::applyTransform(JNIEnv* env, jobject location, jobject rotation) {
+ if (dirty) {
+ // fprintf(stdout, "Apply world translation\n");
+ // fflush(stdout);
+ jmeBulletUtil::convert(env, &worldTransform.getOrigin(), location);
+ jmeBulletUtil::convertQuat(env, &worldTransform.getBasis(), rotation);
+ dirty = false;
+ return true;
+ }
+ return false;
+}
+
+jmeMotionState::~jmeMotionState() {
+ free(trans);
+}
diff --git a/engine/src/bullet/native/jmeMotionState.h b/engine/src/bullet/native/jmeMotionState.h
new file mode 100644
index 000000000..b9e6ebb9e
--- /dev/null
+++ b/engine/src/bullet/native/jmeMotionState.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include
+
+/**
+ * Author: Normen Hansen
+ */
+
+#include "btBulletDynamicsCommon.h"
+//#include "btBulletCollisionCommon.h"
+
+class jmeMotionState : public btMotionState {
+private:
+ bool dirty;
+ btTransform* trans;
+public:
+ jmeMotionState();
+ virtual ~jmeMotionState();
+
+ btTransform worldTransform;
+ virtual void getWorldTransform(btTransform& worldTrans) const;
+ virtual void setWorldTransform(const btTransform& worldTrans);
+ void setKinematicTransform(const btTransform& worldTrans);
+ void setKinematicLocation(JNIEnv*, jobject);
+ void setKinematicRotation(JNIEnv*, jobject);
+ void setKinematicRotationQuat(JNIEnv*, jobject);
+ bool applyTransform(JNIEnv* env, jobject location, jobject rotation);
+};
diff --git a/engine/src/bullet/native/jmePhysicsSpace.cpp b/engine/src/bullet/native/jmePhysicsSpace.cpp
new file mode 100644
index 000000000..2ed23e241
--- /dev/null
+++ b/engine/src/bullet/native/jmePhysicsSpace.cpp
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "jmePhysicsSpace.h"
+#include "jmeBulletUtil.h"
+
+/**
+ * Author: Normen Hansen
+ */
+jmePhysicsSpace::jmePhysicsSpace(JNIEnv* env, jobject javaSpace) {
+ //TODO: global ref? maybe not -> cleaning, rather callback class?
+ this->javaPhysicsSpace = env->NewWeakGlobalRef(javaSpace);
+ this->env = env;
+ env->GetJavaVM(&vm);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+}
+
+void jmePhysicsSpace::attachThread() {
+ vm->AttachCurrentThread((void **) &env, NULL);
+}
+
+JNIEnv* jmePhysicsSpace::getEnv() {
+ attachThread();
+ return this->env;
+}
+
+void jmePhysicsSpace::stepSimulation(jfloat tpf, jint maxSteps, jfloat accuracy) {
+ dynamicsWorld->stepSimulation(tpf, maxSteps, accuracy);
+}
+
+btThreadSupportInterface* jmePhysicsSpace::createSolverThreadSupport(int maxNumThreads) {
+#ifdef _WIN32
+ Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("solverThreads", SolverThreadFunc, SolverlsMemoryFunc, maxNumThreads);
+ Win32ThreadSupport* threadSupport = new Win32ThreadSupport(threadConstructionInfo);
+ threadSupport->startSPU();
+#elif defined (USE_PTHREADS)
+ PosixThreadSupport::ThreadConstructionInfo constructionInfo("collision", SolverThreadFunc,
+ SolverlsMemoryFunc, maxNumThreads);
+ PosixThreadSupport* threadSupport = new PosixThreadSupport(constructionInfo);
+ threadSupport->startSPU();
+#else
+ SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads", SolverThreadFunc, SolverlsMemoryFunc);
+ SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci);
+ threadSupport->startSPU();
+#endif
+ return threadSupport;
+}
+
+btThreadSupportInterface* jmePhysicsSpace::createDispatchThreadSupport(int maxNumThreads) {
+#ifdef _WIN32
+ Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("solverThreads", processCollisionTask, createCollisionLocalStoreMemory, maxNumThreads);
+ Win32ThreadSupport* threadSupport = new Win32ThreadSupport(threadConstructionInfo);
+ threadSupport->startSPU();
+#elif defined (USE_PTHREADS)
+ PosixThreadSupport::ThreadConstructionInfo solverConstructionInfo("solver", processCollisionTask,
+ createCollisionLocalStoreMemory, maxNumThreads);
+ PosixThreadSupport* threadSupport = new PosixThreadSupport(solverConstructionInfo);
+ threadSupport->startSPU();
+#else
+ SequentialThreadSupport::SequentialThreadConstructionInfo tci("solverThreads", processCollisionTask, createCollisionLocalStoreMemory);
+ SequentialThreadSupport* threadSupport = new SequentialThreadSupport(tci);
+ threadSupport->startSPU();
+#endif
+ return threadSupport;
+}
+
+void jmePhysicsSpace::createPhysicsSpace(jfloat minX, jfloat minY, jfloat minZ, jfloat maxX, jfloat maxY, jfloat maxZ, jint broadphaseId, jboolean threading) {
+ // collision configuration contains default setup for memory, collision setup
+ btDefaultCollisionConstructionInfo cci;
+ // if(threading){
+ // cci.m_defaultMaxPersistentManifoldPoolSize = 32768;
+ // }
+ btCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(cci);
+
+ btVector3 min = btVector3(minX, minY, minZ);
+ btVector3 max = btVector3(maxX, maxY, maxZ);
+
+ btBroadphaseInterface* broadphase;
+
+ switch (broadphaseId) {
+ case 0:
+ broadphase = new btSimpleBroadphase();
+ break;
+ case 1:
+ broadphase = new btAxisSweep3(min, max);
+ break;
+ case 2:
+ //TODO: 32bit!
+ broadphase = new btAxisSweep3(min, max);
+ break;
+ case 3:
+ broadphase = new btDbvtBroadphase();
+ break;
+ case 4:
+ // broadphase = new btGpu3DGridBroadphase(
+ // min, max,
+ // 20, 20, 20,
+ // 10000, 1000, 25);
+ break;
+ }
+
+ btCollisionDispatcher* dispatcher;
+ btConstraintSolver* solver;
+ // use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ if (threading) {
+ btThreadSupportInterface* dispatchThreads = createDispatchThreadSupport(4);
+ dispatcher = new SpuGatheringCollisionDispatcher(dispatchThreads, 4, collisionConfiguration);
+ dispatcher->setDispatcherFlags(btCollisionDispatcher::CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION);
+ } else {
+ dispatcher = new btCollisionDispatcher(collisionConfiguration);
+ }
+
+ // the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
+ if (threading) {
+ btThreadSupportInterface* solverThreads = createSolverThreadSupport(4);
+ solver = new btParallelConstraintSolver(solverThreads);
+ } else {
+ solver = new btSequentialImpulseConstraintSolver;
+ }
+
+ //create dynamics world
+ btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
+ dynamicsWorld = world;
+ dynamicsWorld->setWorldUserInfo(this);
+
+ //parallel solver requires the contacts to be in a contiguous pool, so avoid dynamic allocation
+ if (threading) {
+ world->getSimulationIslandManager()->setSplitIslands(false);
+ world->getSolverInfo().m_numIterations = 4;
+ world->getSolverInfo().m_solverMode = SOLVER_SIMD + SOLVER_USE_WARMSTARTING; //+SOLVER_RANDMIZE_ORDER;
+ world->getDispatchInfo().m_enableSPU = true;
+ }
+
+ broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
+
+ dynamicsWorld->setGravity(btVector3(0, -9.81f, 0));
+
+ struct jmeFilterCallback : public btOverlapFilterCallback {
+ // return true when pairs need collision
+
+ virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy * proxy1) const {
+ bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
+ collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+
+ //add some additional logic here that modified 'collides'
+ return collides;
+ }
+ };
+ dynamicsWorld->getPairCache()->setOverlapFilterCallback(new jmeFilterCallback());
+ dynamicsWorld->setInternalTickCallback(&jmePhysicsSpace::preTickCallback, static_cast (this), true);
+ dynamicsWorld->setInternalTickCallback(&jmePhysicsSpace::postTickCallback, static_cast (this));
+}
+
+void jmePhysicsSpace::preTickCallback(btDynamicsWorld *world, btScalar timeStep) {
+ jmePhysicsSpace* dynamicsWorld = (jmePhysicsSpace*) world->getWorldUserInfo();
+ JNIEnv* env = dynamicsWorld->getEnv();
+ env->CallVoidMethod(dynamicsWorld->getJavaPhysicsSpace(), jmeClasses::PhysicsSpace_preTick, timeStep);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+}
+
+void jmePhysicsSpace::postTickCallback(btDynamicsWorld *world, btScalar timeStep) {
+ jmePhysicsSpace* dynamicsWorld = (jmePhysicsSpace*) world->getWorldUserInfo();
+ JNIEnv* env = dynamicsWorld->getEnv();
+ env->CallVoidMethod(dynamicsWorld->getJavaPhysicsSpace(), jmeClasses::PhysicsSpace_postTick, timeStep);
+ if (env->ExceptionCheck()) {
+ env->Throw(env->ExceptionOccurred());
+ return;
+ }
+}
+
+btDynamicsWorld* jmePhysicsSpace::getDynamicsWorld() {
+ return dynamicsWorld;
+}
+
+jobject jmePhysicsSpace::getJavaPhysicsSpace() {
+ return javaPhysicsSpace;
+}
+
+jmePhysicsSpace::~jmePhysicsSpace() {
+ delete(dynamicsWorld);
+}
\ No newline at end of file
diff --git a/engine/src/bullet/native/jmePhysicsSpace.h b/engine/src/bullet/native/jmePhysicsSpace.h
new file mode 100644
index 000000000..932971ec5
--- /dev/null
+++ b/engine/src/bullet/native/jmePhysicsSpace.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include
+#include "btBulletDynamicsCommon.h"
+#include "btBulletCollisionCommon.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionDispatch/btGhostObject.h"
+#include "BulletDynamics/Character/btKinematicCharacterController.h"
+#ifdef _WIN32
+#include "BulletMultiThreaded/Win32ThreadSupport.h"
+#else
+#include "BulletMultiThreaded/PosixThreadSupport.h"
+#endif
+#include "BulletMultiThreaded/btParallelConstraintSolver.h"
+#include "BulletMultiThreaded/SpuGatheringCollisionDispatcher.h"
+#include "BulletMultiThreaded/SpuCollisionTaskProcess.h"
+#include "BulletMultiThreaded/SequentialThreadSupport.h"
+#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
+
+/**
+ * Author: Normen Hansen
+ */
+class jmePhysicsSpace {
+private:
+ JNIEnv* env;
+ JavaVM* vm;
+ btDynamicsWorld* dynamicsWorld;
+ jobject javaPhysicsSpace;
+ btThreadSupportInterface* createSolverThreadSupport(int);
+ btThreadSupportInterface* createDispatchThreadSupport(int);
+ void attachThread();
+public:
+ jmePhysicsSpace(){};
+ ~jmePhysicsSpace();
+ jmePhysicsSpace(JNIEnv*, jobject);
+ void stepSimulation(jfloat, jint, jfloat);
+ void createPhysicsSpace(jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jint, jboolean);
+ btDynamicsWorld* getDynamicsWorld();
+ jobject getJavaPhysicsSpace();
+ JNIEnv* getEnv();
+ static void preTickCallback(btDynamicsWorld*, btScalar);
+ static void postTickCallback(btDynamicsWorld*, btScalar);
+};
\ No newline at end of file
diff --git a/engine/src/bullet/native/nativeclasses.txt b/engine/src/bullet/native/nativeclasses.txt
new file mode 100644
index 000000000..cf6bcc6bb
--- /dev/null
+++ b/engine/src/bullet/native/nativeclasses.txt
@@ -0,0 +1,6 @@
+Classes that differ from the jbullet implementation:
+- com.jme3.bullet.PhysicsSpace
+- com.jme3.bullet.collision.PhysicsCollisionObject
+- All classes in com.jme3.bullet.objects
+- All classes in com.jme3.bullet.joints
+- All classes in com.jme3.bullet.collision.shapes