Home | History | Annotate | Download | only in infos
      1 /*
      2  * Copyright (c) 2009-2010 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 package com.jme3.bullet.objects.infos;
     33 
     34 import com.jme3.bullet.objects.PhysicsVehicle;
     35 import com.jme3.math.Matrix3f;
     36 import com.jme3.math.Quaternion;
     37 import com.jme3.math.Vector3f;
     38 import com.jme3.scene.Spatial;
     39 import java.util.logging.Level;
     40 import 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  */
     47 public 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