1/* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32package com.jme3.bullet.objects.infos; 33 34import com.jme3.bullet.objects.PhysicsVehicle; 35import com.jme3.math.Matrix3f; 36import com.jme3.math.Quaternion; 37import com.jme3.math.Vector3f; 38import com.jme3.scene.Spatial; 39import java.util.logging.Level; 40import java.util.logging.Logger; 41 42/** 43 * stores transform info of a PhysicsNode in a threadsafe manner to 44 * allow multithreaded access from the jme scenegraph and the bullet physicsspace 45 * @author normenhansen 46 */ 47public class RigidBodyMotionState { 48 long motionStateId = 0; 49 private Vector3f worldLocation = new Vector3f(); 50 private Matrix3f worldRotation = new Matrix3f(); 51 private Quaternion worldRotationQuat = new Quaternion(); 52 private Quaternion tmp_inverseWorldRotation = new Quaternion(); 53 private PhysicsVehicle vehicle; 54 private boolean applyPhysicsLocal = false; 55// protected LinkedList<PhysicsMotionStateListener> listeners = new LinkedList<PhysicsMotionStateListener>(); 56 57 public RigidBodyMotionState() { 58 this.motionStateId = createMotionState(); 59 Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created MotionState {0}", Long.toHexString(motionStateId)); 60 } 61 62 private native long createMotionState(); 63 64 /** 65 * applies the current transform to the given jme Node if the location has been updated on the physics side 66 * @param spatial 67 */ 68 public synchronized boolean applyTransform(Spatial spatial) { 69 Vector3f localLocation = spatial.getLocalTranslation(); 70 Quaternion localRotationQuat = spatial.getLocalRotation(); 71 boolean physicsLocationDirty = applyTransform(motionStateId, localLocation, localRotationQuat); 72 if (!physicsLocationDirty) { 73 return false; 74 } 75 if (!applyPhysicsLocal && spatial.getParent() != null) { 76 localLocation.subtractLocal(spatial.getParent().getWorldTranslation()); 77 localLocation.divideLocal(spatial.getParent().getWorldScale()); 78 tmp_inverseWorldRotation.set(spatial.getParent().getWorldRotation()).inverseLocal().multLocal(localLocation); 79 80// localRotationQuat.set(worldRotationQuat); 81 tmp_inverseWorldRotation.mult(localRotationQuat, localRotationQuat); 82 83 spatial.setLocalTranslation(localLocation); 84 spatial.setLocalRotation(localRotationQuat); 85 } else { 86 spatial.setLocalTranslation(localLocation); 87 spatial.setLocalRotation(localRotationQuat); 88// spatial.setLocalTranslation(worldLocation); 89// spatial.setLocalRotation(worldRotationQuat); 90 } 91 if (vehicle != null) { 92 vehicle.updateWheels(); 93 } 94 return true; 95 } 96 97 private synchronized native boolean applyTransform(long stateId, Vector3f location, Quaternion rotation); 98 99 /** 100 * @return the worldLocation 101 */ 102 public Vector3f getWorldLocation() { 103 getWorldLocation(motionStateId, worldLocation); 104 return worldLocation; 105 } 106 107 private native void getWorldLocation(long stateId, Vector3f vec); 108 109 /** 110 * @return the worldRotation 111 */ 112 public Matrix3f getWorldRotation() { 113 getWorldRotation(motionStateId, worldRotation); 114 return worldRotation; 115 } 116 117 private native void getWorldRotation(long stateId, Matrix3f vec); 118 119 /** 120 * @return the worldRotationQuat 121 */ 122 public Quaternion getWorldRotationQuat() { 123 getWorldRotationQuat(motionStateId, worldRotationQuat); 124 return worldRotationQuat; 125 } 126 127 private native void getWorldRotationQuat(long stateId, Quaternion vec); 128 129 /** 130 * @param vehicle the vehicle to set 131 */ 132 public void setVehicle(PhysicsVehicle vehicle) { 133 this.vehicle = vehicle; 134 } 135 136 public boolean isApplyPhysicsLocal() { 137 return applyPhysicsLocal; 138 } 139 140 public void setApplyPhysicsLocal(boolean applyPhysicsLocal) { 141 this.applyPhysicsLocal = applyPhysicsLocal; 142 } 143 144 public long getObjectId(){ 145 return motionStateId; 146 } 147// public void addMotionStateListener(PhysicsMotionStateListener listener){ 148// listeners.add(listener); 149// } 150// 151// public void removeMotionStateListener(PhysicsMotionStateListener listener){ 152// listeners.remove(listener); 153// } 154 155 @Override 156 protected void finalize() throws Throwable { 157 super.finalize(); 158 Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing MotionState {0}", Long.toHexString(motionStateId)); 159 finalizeNative(motionStateId); 160 } 161 162 private native void finalizeNative(long objectId); 163} 164