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