• 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;
33 
34 import com.jme3.bullet.collision.PhysicsCollisionObject;
35 import com.jme3.bullet.collision.shapes.CollisionShape;
36 import com.jme3.export.InputCapsule;
37 import com.jme3.export.JmeExporter;
38 import com.jme3.export.JmeImporter;
39 import com.jme3.export.OutputCapsule;
40 import com.jme3.math.Matrix3f;
41 import com.jme3.math.Quaternion;
42 import com.jme3.math.Vector3f;
43 import com.jme3.scene.Spatial;
44 import java.io.IOException;
45 import java.util.LinkedList;
46 import java.util.List;
47 import java.util.logging.Level;
48 import java.util.logging.Logger;
49 
50 /**
51  * <i>From Bullet manual:</i><br>
52  * GhostObject can keep track of all objects that are overlapping.
53  * By default, this overlap is based on the AABB.
54  * This is useful for creating a character controller,
55  * collision sensors/triggers, explosions etc.<br>
56  * @author normenhansen
57  */
58 public class PhysicsGhostObject extends PhysicsCollisionObject {
59 
60     protected boolean locationDirty = false;
61     protected final Quaternion tmp_inverseWorldRotation = new Quaternion();
62     private List<PhysicsCollisionObject> overlappingObjects = new LinkedList<PhysicsCollisionObject>();
63 
PhysicsGhostObject()64     public PhysicsGhostObject() {
65     }
66 
PhysicsGhostObject(CollisionShape shape)67     public PhysicsGhostObject(CollisionShape shape) {
68         collisionShape = shape;
69         buildObject();
70     }
71 
PhysicsGhostObject(Spatial child, CollisionShape shape)72     public PhysicsGhostObject(Spatial child, CollisionShape shape) {
73         collisionShape = shape;
74         buildObject();
75     }
76 
buildObject()77     protected void buildObject() {
78         if (objectId == 0) {
79 //            gObject = new PairCachingGhostObject();
80             objectId = createGhostObject();
81             Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Ghost Object {0}", Long.toHexString(objectId));
82             setGhostFlags(objectId);
83             initUserPointer();
84         }
85 //        if (gObject == null) {
86 //            gObject = new PairCachingGhostObject();
87 //            gObject.setCollisionFlags(gObject.getCollisionFlags() | CollisionFlags.NO_CONTACT_RESPONSE);
88 //        }
89         attachCollisionShape(objectId, collisionShape.getObjectId());
90     }
91 
createGhostObject()92     private native long createGhostObject();
93 
setGhostFlags(long objectId)94     private native void setGhostFlags(long objectId);
95 
96     @Override
setCollisionShape(CollisionShape collisionShape)97     public void setCollisionShape(CollisionShape collisionShape) {
98         super.setCollisionShape(collisionShape);
99         if (objectId == 0) {
100             buildObject();
101         } else {
102             attachCollisionShape(objectId, collisionShape.getObjectId());
103         }
104     }
105 
106     /**
107      * Sets the physics object location
108      * @param location the location of the actual physics object
109      */
setPhysicsLocation(Vector3f location)110     public void setPhysicsLocation(Vector3f location) {
111         setPhysicsLocation(objectId, location);
112     }
113 
setPhysicsLocation(long objectId, Vector3f location)114     private native void setPhysicsLocation(long objectId, Vector3f location);
115 
116     /**
117      * Sets the physics object rotation
118      * @param rotation the rotation of the actual physics object
119      */
setPhysicsRotation(Matrix3f rotation)120     public void setPhysicsRotation(Matrix3f rotation) {
121         setPhysicsRotation(objectId, rotation);
122     }
123 
setPhysicsRotation(long objectId, Matrix3f rotation)124     private native void setPhysicsRotation(long objectId, Matrix3f rotation);
125 
126     /**
127      * Sets the physics object rotation
128      * @param rotation the rotation of the actual physics object
129      */
setPhysicsRotation(Quaternion rotation)130     public void setPhysicsRotation(Quaternion rotation) {
131         setPhysicsRotation(objectId, rotation);
132     }
133 
setPhysicsRotation(long objectId, Quaternion rotation)134     private native void setPhysicsRotation(long objectId, Quaternion rotation);
135 
136     /**
137      * @return the physicsLocation
138      */
getPhysicsLocation(Vector3f trans)139     public Vector3f getPhysicsLocation(Vector3f trans) {
140         if (trans == null) {
141             trans = new Vector3f();
142         }
143         getPhysicsLocation(objectId, trans);
144         return trans;
145     }
146 
getPhysicsLocation(long objectId, Vector3f vector)147     private native void getPhysicsLocation(long objectId, Vector3f vector);
148 
149     /**
150      * @return the physicsLocation
151      */
getPhysicsRotation(Quaternion rot)152     public Quaternion getPhysicsRotation(Quaternion rot) {
153         if (rot == null) {
154             rot = new Quaternion();
155         }
156         getPhysicsRotation(objectId, rot);
157         return rot;
158     }
159 
getPhysicsRotation(long objectId, Quaternion rot)160     private native void getPhysicsRotation(long objectId, Quaternion rot);
161 
162     /**
163      * @return the physicsLocation
164      */
getPhysicsRotationMatrix(Matrix3f rot)165     public Matrix3f getPhysicsRotationMatrix(Matrix3f rot) {
166         if (rot == null) {
167             rot = new Matrix3f();
168         }
169         getPhysicsRotationMatrix(objectId, rot);
170         return rot;
171     }
172 
getPhysicsRotationMatrix(long objectId, Matrix3f rot)173     private native void getPhysicsRotationMatrix(long objectId, Matrix3f rot);
174 
175     /**
176      * @return the physicsLocation
177      */
getPhysicsLocation()178     public Vector3f getPhysicsLocation() {
179         Vector3f vec = new Vector3f();
180         getPhysicsLocation(objectId, vec);
181         return vec;
182     }
183 
184     /**
185      * @return the physicsLocation
186      */
getPhysicsRotation()187     public Quaternion getPhysicsRotation() {
188         Quaternion quat = new Quaternion();
189         getPhysicsRotation(objectId, quat);
190         return quat;
191     }
192 
getPhysicsRotationMatrix()193     public Matrix3f getPhysicsRotationMatrix() {
194         Matrix3f mtx = new Matrix3f();
195         getPhysicsRotationMatrix(objectId, mtx);
196         return mtx;
197     }
198 
199     /**
200      * used internally
201      */
202 //    public PairCachingGhostObject getObjectId() {
203 //        return gObject;
204 //    }
205     /**
206      * destroys this PhysicsGhostNode and removes it from memory
207      */
destroy()208     public void destroy() {
209     }
210 
211     /**
212      * Another Object is overlapping with this GhostNode,
213      * if and if only there CollisionShapes overlaps.
214      * They could be both regular PhysicsRigidBodys or PhysicsGhostObjects.
215      * @return All CollisionObjects overlapping with this GhostNode.
216      */
getOverlappingObjects()217     public List<PhysicsCollisionObject> getOverlappingObjects() {
218         overlappingObjects.clear();
219         getOverlappingObjects(objectId);
220 //        for (com.bulletphysics.collision.dispatch.CollisionObject collObj : gObject.getOverlappingPairs()) {
221 //            overlappingObjects.add((PhysicsCollisionObject) collObj.getUserPointer());
222 //        }
223         return overlappingObjects;
224     }
225 
getOverlappingObjects(long objectId)226     protected native void getOverlappingObjects(long objectId);
227 
addOverlappingObject_native(PhysicsCollisionObject co)228     private void addOverlappingObject_native(PhysicsCollisionObject co) {
229         overlappingObjects.add(co);
230     }
231 
232     /**
233      *
234      * @return With how many other CollisionObjects this GhostNode is currently overlapping.
235      */
getOverlappingCount()236     public int getOverlappingCount() {
237         return getOverlappingCount(objectId);
238     }
239 
getOverlappingCount(long objectId)240     private native int getOverlappingCount(long objectId);
241 
242     /**
243      *
244      * @param index The index of the overlapping Node to retrieve.
245      * @return The Overlapping CollisionObject at the given index.
246      */
getOverlapping(int index)247     public PhysicsCollisionObject getOverlapping(int index) {
248         return overlappingObjects.get(index);
249     }
250 
setCcdSweptSphereRadius(float radius)251     public void setCcdSweptSphereRadius(float radius) {
252         setCcdSweptSphereRadius(objectId, radius);
253     }
254 
setCcdSweptSphereRadius(long objectId, float radius)255     private native void setCcdSweptSphereRadius(long objectId, float radius);
256 
setCcdMotionThreshold(float threshold)257     public void setCcdMotionThreshold(float threshold) {
258         setCcdMotionThreshold(objectId, threshold);
259     }
260 
setCcdMotionThreshold(long objectId, float threshold)261     private native void setCcdMotionThreshold(long objectId, float threshold);
262 
getCcdSweptSphereRadius()263     public float getCcdSweptSphereRadius() {
264         return getCcdSweptSphereRadius(objectId);
265     }
266 
getCcdSweptSphereRadius(long objectId)267     private native float getCcdSweptSphereRadius(long objectId);
268 
getCcdMotionThreshold()269     public float getCcdMotionThreshold() {
270         return getCcdMotionThreshold(objectId);
271     }
272 
getCcdMotionThreshold(long objectId)273     private native float getCcdMotionThreshold(long objectId);
274 
getCcdSquareMotionThreshold()275     public float getCcdSquareMotionThreshold() {
276         return getCcdSquareMotionThreshold(objectId);
277     }
278 
getCcdSquareMotionThreshold(long objectId)279     private native float getCcdSquareMotionThreshold(long objectId);
280 
281     @Override
write(JmeExporter e)282     public void write(JmeExporter e) throws IOException {
283         super.write(e);
284         OutputCapsule capsule = e.getCapsule(this);
285         capsule.write(getPhysicsLocation(new Vector3f()), "physicsLocation", new Vector3f());
286         capsule.write(getPhysicsRotationMatrix(new Matrix3f()), "physicsRotation", new Matrix3f());
287         capsule.write(getCcdMotionThreshold(), "ccdMotionThreshold", 0);
288         capsule.write(getCcdSweptSphereRadius(), "ccdSweptSphereRadius", 0);
289     }
290 
291     @Override
read(JmeImporter e)292     public void read(JmeImporter e) throws IOException {
293         super.read(e);
294         InputCapsule capsule = e.getCapsule(this);
295         buildObject();
296         setPhysicsLocation((Vector3f) capsule.readSavable("physicsLocation", new Vector3f()));
297         setPhysicsRotation(((Matrix3f) capsule.readSavable("physicsRotation", new Matrix3f())));
298         setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0));
299         setCcdSweptSphereRadius(capsule.readFloat("ccdSweptSphereRadius", 0));
300     }
301 }
302