• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.bulletphysics.linearmath.MotionState;
35 import com.bulletphysics.linearmath.Transform;
36 import com.jme3.bullet.objects.PhysicsVehicle;
37 import com.jme3.bullet.util.Converter;
38 import com.jme3.math.Matrix3f;
39 import com.jme3.math.Quaternion;
40 import com.jme3.math.Vector3f;
41 import com.jme3.scene.Spatial;
42 
43 /**
44  * stores transform info of a PhysicsNode in a threadsafe manner to
45  * allow multithreaded access from the jme scenegraph and the bullet physicsspace
46  * @author normenhansen
47  */
48 public class RigidBodyMotionState extends MotionState {
49     //stores the bullet transform
50 
51     private Transform motionStateTrans = new Transform(Converter.convert(new Matrix3f()));
52     private Vector3f worldLocation = new Vector3f();
53     private Matrix3f worldRotation = new Matrix3f();
54     private Quaternion worldRotationQuat = new Quaternion();
55     private Vector3f localLocation = new Vector3f();
56     private Quaternion localRotationQuat = new Quaternion();
57     //keep track of transform changes
58     private boolean physicsLocationDirty = false;
59     private boolean jmeLocationDirty = false;
60     //temp variable for conversion
61     private Quaternion tmp_inverseWorldRotation = new Quaternion();
62     private PhysicsVehicle vehicle;
63     private boolean applyPhysicsLocal = false;
64 //    protected LinkedList<PhysicsMotionStateListener> listeners = new LinkedList<PhysicsMotionStateListener>();
65 
RigidBodyMotionState()66     public RigidBodyMotionState() {
67     }
68 
69     /**
70      * called from bullet when creating the rigidbody
71      * @param t
72      * @return
73      */
getWorldTransform(Transform t)74     public synchronized Transform getWorldTransform(Transform t) {
75         t.set(motionStateTrans);
76         return t;
77     }
78 
79     /**
80      * called from bullet when the transform of the rigidbody changes
81      * @param worldTrans
82      */
setWorldTransform(Transform worldTrans)83     public synchronized void setWorldTransform(Transform worldTrans) {
84         if (jmeLocationDirty) {
85             return;
86         }
87         motionStateTrans.set(worldTrans);
88         Converter.convert(worldTrans.origin, worldLocation);
89         Converter.convert(worldTrans.basis, worldRotation);
90         worldRotationQuat.fromRotationMatrix(worldRotation);
91 //        for (Iterator<PhysicsMotionStateListener> it = listeners.iterator(); it.hasNext();) {
92 //            PhysicsMotionStateListener physicsMotionStateListener = it.next();
93 //            physicsMotionStateListener.stateChanged(worldLocation, worldRotation);
94 //        }
95         physicsLocationDirty = true;
96         if (vehicle != null) {
97             vehicle.updateWheels();
98         }
99     }
100 
101     /**
102      * applies the current transform to the given jme Node if the location has been updated on the physics side
103      * @param spatial
104      */
applyTransform(Spatial spatial)105     public synchronized boolean applyTransform(Spatial spatial) {
106         if (!physicsLocationDirty) {
107             return false;
108         }
109         if (!applyPhysicsLocal && spatial.getParent() != null) {
110             localLocation.set(worldLocation).subtractLocal(spatial.getParent().getWorldTranslation());
111             localLocation.divideLocal(spatial.getParent().getWorldScale());
112             tmp_inverseWorldRotation.set(spatial.getParent().getWorldRotation()).inverseLocal().multLocal(localLocation);
113 
114             localRotationQuat.set(worldRotationQuat);
115             tmp_inverseWorldRotation.set(spatial.getParent().getWorldRotation()).inverseLocal().mult(localRotationQuat, localRotationQuat);
116 
117             spatial.setLocalTranslation(localLocation);
118             spatial.setLocalRotation(localRotationQuat);
119         } else {
120             spatial.setLocalTranslation(worldLocation);
121             spatial.setLocalRotation(worldRotationQuat);
122         }
123         physicsLocationDirty = false;
124         return true;
125     }
126 
127     /**
128      * @return the worldLocation
129      */
getWorldLocation()130     public Vector3f getWorldLocation() {
131         return worldLocation;
132     }
133 
134     /**
135      * @return the worldRotation
136      */
getWorldRotation()137     public Matrix3f getWorldRotation() {
138         return worldRotation;
139     }
140 
141     /**
142      * @return the worldRotationQuat
143      */
getWorldRotationQuat()144     public Quaternion getWorldRotationQuat() {
145         return worldRotationQuat;
146     }
147 
148     /**
149      * @param vehicle the vehicle to set
150      */
setVehicle(PhysicsVehicle vehicle)151     public void setVehicle(PhysicsVehicle vehicle) {
152         this.vehicle = vehicle;
153     }
154 
isApplyPhysicsLocal()155     public boolean isApplyPhysicsLocal() {
156         return applyPhysicsLocal;
157     }
158 
setApplyPhysicsLocal(boolean applyPhysicsLocal)159     public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
160         this.applyPhysicsLocal = applyPhysicsLocal;
161     }
162 //    public void addMotionStateListener(PhysicsMotionStateListener listener){
163 //        listeners.add(listener);
164 //    }
165 //
166 //    public void removeMotionStateListener(PhysicsMotionStateListener listener){
167 //        listeners.remove(listener);
168 //    }
169 //    public synchronized boolean applyTransform(com.jme3.math.Transform trans) {
170 //        if (!physicsLocationDirty) {
171 //            return false;
172 //        }
173 //        trans.setTranslation(worldLocation);
174 //        trans.setRotation(worldRotationQuat);
175 //        physicsLocationDirty = false;
176 //        return true;
177 //    }
178 //
179 //    /**
180 //     * called from jme when the location of the jme Node changes
181 //     * @param location
182 //     * @param rotation
183 //     */
184 //    public synchronized void setWorldTransform(Vector3f location, Quaternion rotation) {
185 //        worldLocation.set(location);
186 //        worldRotationQuat.set(rotation);
187 //        worldRotation.set(rotation.toRotationMatrix());
188 //        Converter.convert(worldLocation, motionStateTrans.origin);
189 //        Converter.convert(worldRotation, motionStateTrans.basis);
190 //        jmeLocationDirty = true;
191 //    }
192 //
193 //    /**
194 //     * applies the current transform to the given RigidBody if the value has been changed on the jme side
195 //     * @param rBody
196 //     */
197 //    public synchronized void applyTransform(RigidBody rBody) {
198 //        if (!jmeLocationDirty) {
199 //            return;
200 //        }
201 //        assert (rBody != null);
202 //        rBody.setWorldTransform(motionStateTrans);
203 //        rBody.activate();
204 //        jmeLocationDirty = false;
205 //    }
206 }
207