- fix non-displayed physics objects in debug view - remove dependency of base physics objects to scenegraph api, only jme math dependencies are left git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10342 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
2d5800d667
commit
8992563b86
@ -0,0 +1,81 @@ |
||||
/* |
||||
* Copyright (c) 2009-2012 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.bullet.debug; |
||||
|
||||
import com.jme3.math.Quaternion; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.scene.Spatial; |
||||
import com.jme3.scene.control.AbstractControl; |
||||
|
||||
/** |
||||
* |
||||
* @author normenhansen |
||||
*/ |
||||
public abstract class AbstractPhysicsDebugControl extends AbstractControl { |
||||
|
||||
private final Quaternion tmp_inverseWorldRotation = new Quaternion(); |
||||
protected final BulletDebugAppState debugAppState; |
||||
|
||||
public AbstractPhysicsDebugControl(BulletDebugAppState debugAppState) { |
||||
this.debugAppState = debugAppState; |
||||
} |
||||
|
||||
/** |
||||
* This is called on the physics thread for debug controls |
||||
*/ |
||||
@Override |
||||
protected abstract void controlUpdate(float tpf); |
||||
|
||||
protected void applyPhysicsTransform(Vector3f worldLocation, Quaternion worldRotation) { |
||||
applyPhysicsTransform(worldLocation, worldRotation, this.spatial); |
||||
} |
||||
|
||||
protected void applyPhysicsTransform(Vector3f worldLocation, Quaternion worldRotation, Spatial spatial) { |
||||
if (spatial != null) { |
||||
Vector3f localLocation = spatial.getLocalTranslation(); |
||||
Quaternion localRotationQuat = spatial.getLocalRotation(); |
||||
if (spatial.getParent() != null) { |
||||
localLocation.set(worldLocation).subtractLocal(spatial.getParent().getWorldTranslation()); |
||||
localLocation.divideLocal(spatial.getParent().getWorldScale()); |
||||
tmp_inverseWorldRotation.set(spatial.getParent().getWorldRotation()).inverseLocal().multLocal(localLocation); |
||||
localRotationQuat.set(worldRotation); |
||||
tmp_inverseWorldRotation.set(spatial.getParent().getWorldRotation()).inverseLocal().mult(localRotationQuat, localRotationQuat); |
||||
spatial.setLocalTranslation(localLocation); |
||||
spatial.setLocalRotation(localRotationQuat); |
||||
} else { |
||||
spatial.setLocalTranslation(worldLocation); |
||||
spatial.setLocalRotation(worldRotation); |
||||
} |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,92 @@ |
||||
/* |
||||
* Copyright (c) 2009-2012 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.bullet.debug; |
||||
|
||||
import com.jme3.bullet.objects.PhysicsCharacter; |
||||
import com.jme3.math.Quaternion; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.renderer.RenderManager; |
||||
import com.jme3.renderer.ViewPort; |
||||
import com.jme3.scene.Geometry; |
||||
import com.jme3.scene.Mesh; |
||||
import com.jme3.scene.Node; |
||||
import com.jme3.scene.Spatial; |
||||
|
||||
/** |
||||
* |
||||
* @author normenhansen |
||||
*/ |
||||
public class BulletCharacterDebugControl extends AbstractPhysicsDebugControl { |
||||
|
||||
protected final PhysicsCharacter body; |
||||
protected final Geometry geom; |
||||
protected final Vector3f location = new Vector3f(); |
||||
protected final Quaternion rotation = new Quaternion(); |
||||
|
||||
public BulletCharacterDebugControl(BulletDebugAppState debugAppState, PhysicsCharacter body) { |
||||
super(debugAppState); |
||||
this.body = body; |
||||
this.geom = new Geometry(body.toString()); |
||||
geom.setMaterial(debugAppState.DEBUG_PINK); |
||||
} |
||||
|
||||
@Override |
||||
public void setSpatial(Spatial spatial) { |
||||
if (spatial != null && spatial instanceof Node) { |
||||
Node node = (Node) spatial; |
||||
node.attachChild(geom); |
||||
} else if (spatial == null && this.spatial != null) { |
||||
Node node = (Node) this.spatial; |
||||
node.detachChild(geom); |
||||
} |
||||
super.setSpatial(spatial); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlUpdate(float tpf) { |
||||
Mesh mesh = debugAppState.getShapeBuffer().getShapeMesh(body.getCollisionShape()); |
||||
if (mesh != null) { |
||||
if (geom.getMesh() != mesh) { |
||||
geom.setMesh(mesh); |
||||
} |
||||
} else { |
||||
if (geom.getMesh() != BulletDebugAppState.CollisionShapeBuffer.NO_MESH) { |
||||
geom.setMesh(BulletDebugAppState.CollisionShapeBuffer.NO_MESH); |
||||
} |
||||
} |
||||
applyPhysicsTransform(body.getPhysicsLocation(location), Quaternion.IDENTITY); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlRender(RenderManager rm, ViewPort vp) { |
||||
} |
||||
} |
@ -0,0 +1,361 @@ |
||||
/* |
||||
* Copyright (c) 2009-2012 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.bullet.debug; |
||||
|
||||
import com.jme3.app.Application; |
||||
import com.jme3.app.state.AbstractAppState; |
||||
import com.jme3.app.state.AppStateManager; |
||||
import com.jme3.asset.AssetManager; |
||||
import com.jme3.bullet.PhysicsSpace; |
||||
import com.jme3.bullet.collision.shapes.CollisionShape; |
||||
import com.jme3.bullet.joints.PhysicsJoint; |
||||
import com.jme3.bullet.objects.PhysicsCharacter; |
||||
import com.jme3.bullet.objects.PhysicsGhostObject; |
||||
import com.jme3.bullet.objects.PhysicsRigidBody; |
||||
import com.jme3.bullet.objects.PhysicsVehicle; |
||||
import com.jme3.bullet.util.DebugShapeFactory; |
||||
import com.jme3.material.Material; |
||||
import com.jme3.math.ColorRGBA; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.renderer.RenderManager; |
||||
import com.jme3.renderer.ViewPort; |
||||
import com.jme3.scene.Mesh; |
||||
import com.jme3.scene.Node; |
||||
import com.jme3.scene.Spatial; |
||||
import com.jme3.scene.debug.Arrow; |
||||
import java.util.Collection; |
||||
import java.util.HashMap; |
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
import java.util.Queue; |
||||
import java.util.concurrent.ConcurrentLinkedQueue; |
||||
import java.util.logging.Level; |
||||
import java.util.logging.Logger; |
||||
|
||||
/** |
||||
* |
||||
* @author normenhansen |
||||
*/ |
||||
public class BulletDebugAppState extends AbstractAppState { |
||||
|
||||
protected static final Logger logger = Logger.getLogger(BulletDebugAppState.class.getName()); |
||||
protected final PhysicsSpace space; |
||||
protected final CollisionShapeBuffer shapeBuffer = new CollisionShapeBuffer(); |
||||
protected final ArrowBuffer arrowBuffer = new ArrowBuffer(); |
||||
protected final Node physicsDebugRootNode = new Node("Physics Debug Root Node"); |
||||
protected ViewPort viewPort; |
||||
protected RenderManager rm; |
||||
public Material DEBUG_BLUE; |
||||
public Material DEBUG_RED; |
||||
public Material DEBUG_GREEN; |
||||
public Material DEBUG_YELLOW; |
||||
public Material DEBUG_MAGENTA; |
||||
public Material DEBUG_PINK; |
||||
protected HashMap<PhysicsRigidBody, Spatial> bodies = new HashMap<PhysicsRigidBody, Spatial>(); |
||||
protected HashMap<PhysicsJoint, Spatial> joints = new HashMap<PhysicsJoint, Spatial>(); |
||||
protected HashMap<PhysicsGhostObject, Spatial> ghosts = new HashMap<PhysicsGhostObject, Spatial>(); |
||||
protected HashMap<PhysicsCharacter, Spatial> characters = new HashMap<PhysicsCharacter, Spatial>(); |
||||
protected HashMap<PhysicsVehicle, Spatial> vehicles = new HashMap<PhysicsVehicle, Spatial>(); |
||||
|
||||
public BulletDebugAppState(PhysicsSpace space) { |
||||
this.space = space; |
||||
} |
||||
|
||||
@Override |
||||
public void initialize(AppStateManager stateManager, Application app) { |
||||
super.initialize(stateManager, app); |
||||
this.rm = app.getRenderManager(); |
||||
setupMaterials(app); |
||||
physicsDebugRootNode.setCullHint(Spatial.CullHint.Never); |
||||
viewPort = rm.createMainView("Physics Debug Overlay", app.getCamera()); |
||||
viewPort.setClearFlags(false, true, false); |
||||
viewPort.attachScene(physicsDebugRootNode); |
||||
} |
||||
|
||||
@Override |
||||
public void cleanup() { |
||||
rm.removeMainView(viewPort); |
||||
super.cleanup(); |
||||
} |
||||
|
||||
@Override |
||||
public void update(float tpf) { |
||||
super.update(tpf); |
||||
//update all object links
|
||||
updateRigidBodies(); |
||||
updateGhosts(); |
||||
updateCharacters(); |
||||
updateJoints(); |
||||
updateVehicles(); |
||||
//update our debug root node
|
||||
physicsDebugRootNode.updateLogicalState(tpf); |
||||
physicsDebugRootNode.updateGeometricState(); |
||||
//reset shapes -> this removes all meshes for shapes that were not used this update cycle
|
||||
shapeBuffer.resetShapes(); |
||||
//reset arrows -> this makes arrow meshes available for the next update cycle
|
||||
arrowBuffer.resetArrows(); |
||||
} |
||||
|
||||
@Override |
||||
public void render(RenderManager rm) { |
||||
super.render(rm); |
||||
if (viewPort != null) { |
||||
rm.renderScene(physicsDebugRootNode, viewPort); |
||||
} |
||||
} |
||||
|
||||
private void setupMaterials(Application app) { |
||||
AssetManager manager = app.getAssetManager(); |
||||
DEBUG_BLUE = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); |
||||
DEBUG_BLUE.getAdditionalRenderState().setWireframe(true); |
||||
DEBUG_BLUE.setColor("Color", ColorRGBA.Blue); |
||||
DEBUG_GREEN = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); |
||||
DEBUG_GREEN.getAdditionalRenderState().setWireframe(true); |
||||
DEBUG_GREEN.setColor("Color", ColorRGBA.Green); |
||||
DEBUG_RED = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); |
||||
DEBUG_RED.getAdditionalRenderState().setWireframe(true); |
||||
DEBUG_RED.setColor("Color", ColorRGBA.Red); |
||||
DEBUG_YELLOW = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); |
||||
DEBUG_YELLOW.getAdditionalRenderState().setWireframe(true); |
||||
DEBUG_YELLOW.setColor("Color", ColorRGBA.Yellow); |
||||
DEBUG_MAGENTA = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); |
||||
DEBUG_MAGENTA.getAdditionalRenderState().setWireframe(true); |
||||
DEBUG_MAGENTA.setColor("Color", ColorRGBA.Magenta); |
||||
DEBUG_PINK = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); |
||||
DEBUG_PINK.getAdditionalRenderState().setWireframe(true); |
||||
DEBUG_PINK.setColor("Color", ColorRGBA.Pink); |
||||
} |
||||
|
||||
private void updateRigidBodies() { |
||||
HashMap<PhysicsRigidBody, Spatial> oldObjects = bodies; |
||||
bodies = new HashMap<PhysicsRigidBody, Spatial>(); |
||||
Collection<PhysicsRigidBody> current = space.getRigidBodyList(); |
||||
//create new map
|
||||
for (Iterator<PhysicsRigidBody> it = current.iterator(); it.hasNext();) { |
||||
PhysicsRigidBody physicsObject = it.next(); |
||||
//copy existing spatials
|
||||
if (oldObjects.containsKey(physicsObject)) { |
||||
Spatial spat = oldObjects.get(physicsObject); |
||||
bodies.put(physicsObject, spat); |
||||
oldObjects.remove(physicsObject); |
||||
} else { |
||||
logger.log(Level.FINE, "Create new debug RigidBody"); |
||||
//create new spatial
|
||||
Node node = new Node(physicsObject.toString()); |
||||
node.addControl(new BulletRigidBodyDebugControl(this, physicsObject)); |
||||
bodies.put(physicsObject, node); |
||||
physicsDebugRootNode.attachChild(node); |
||||
} |
||||
} |
||||
//remove leftover spatials
|
||||
for (Map.Entry<PhysicsRigidBody, Spatial> entry : oldObjects.entrySet()) { |
||||
PhysicsRigidBody object = entry.getKey(); |
||||
Spatial spatial = entry.getValue(); |
||||
spatial.removeFromParent(); |
||||
} |
||||
} |
||||
|
||||
private void updateJoints() { |
||||
HashMap<PhysicsJoint, Spatial> oldObjects = joints; |
||||
joints = new HashMap<PhysicsJoint, Spatial>(); |
||||
Collection<PhysicsJoint> current = space.getJointList(); |
||||
//create new map
|
||||
for (Iterator<PhysicsJoint> it = current.iterator(); it.hasNext();) { |
||||
PhysicsJoint physicsObject = it.next(); |
||||
//copy existing spatials
|
||||
if (oldObjects.containsKey(physicsObject)) { |
||||
Spatial spat = oldObjects.get(physicsObject); |
||||
joints.put(physicsObject, spat); |
||||
oldObjects.remove(physicsObject); |
||||
} else { |
||||
logger.log(Level.FINE, "Create new debug Joint"); |
||||
//create new spatial
|
||||
Node node = new Node(physicsObject.toString()); |
||||
node.addControl(new BulletJointDebugControl(this, physicsObject)); |
||||
joints.put(physicsObject, node); |
||||
physicsDebugRootNode.attachChild(node); |
||||
} |
||||
} |
||||
//remove leftover spatials
|
||||
for (Map.Entry<PhysicsJoint, Spatial> entry : oldObjects.entrySet()) { |
||||
PhysicsJoint object = entry.getKey(); |
||||
Spatial spatial = entry.getValue(); |
||||
spatial.removeFromParent(); |
||||
} |
||||
} |
||||
|
||||
private void updateGhosts() { |
||||
HashMap<PhysicsGhostObject, Spatial> oldObjects = ghosts; |
||||
ghosts = new HashMap<PhysicsGhostObject, Spatial>(); |
||||
Collection<PhysicsGhostObject> current = space.getGhostObjectList(); |
||||
//create new map
|
||||
for (Iterator<PhysicsGhostObject> it = current.iterator(); it.hasNext();) { |
||||
PhysicsGhostObject physicsObject = it.next(); |
||||
//copy existing spatials
|
||||
if (oldObjects.containsKey(physicsObject)) { |
||||
Spatial spat = oldObjects.get(physicsObject); |
||||
ghosts.put(physicsObject, spat); |
||||
oldObjects.remove(physicsObject); |
||||
} else { |
||||
logger.log(Level.FINE, "Create new debug GhostObject"); |
||||
//create new spatial
|
||||
Node node = new Node(physicsObject.toString()); |
||||
node.addControl(new BulletGhostObjectDebugControl(this, physicsObject)); |
||||
ghosts.put(physicsObject, node); |
||||
physicsDebugRootNode.attachChild(node); |
||||
} |
||||
} |
||||
//remove leftover spatials
|
||||
for (Map.Entry<PhysicsGhostObject, Spatial> entry : oldObjects.entrySet()) { |
||||
PhysicsGhostObject object = entry.getKey(); |
||||
Spatial spatial = entry.getValue(); |
||||
spatial.removeFromParent(); |
||||
} |
||||
} |
||||
|
||||
private void updateCharacters() { |
||||
HashMap<PhysicsCharacter, Spatial> oldObjects = characters; |
||||
characters = new HashMap<PhysicsCharacter, Spatial>(); |
||||
Collection<PhysicsCharacter> current = space.getCharacterList(); |
||||
//create new map
|
||||
for (Iterator<PhysicsCharacter> it = current.iterator(); it.hasNext();) { |
||||
PhysicsCharacter physicsObject = it.next(); |
||||
//copy existing spatials
|
||||
if (oldObjects.containsKey(physicsObject)) { |
||||
Spatial spat = oldObjects.get(physicsObject); |
||||
characters.put(physicsObject, spat); |
||||
oldObjects.remove(physicsObject); |
||||
} else { |
||||
logger.log(Level.FINE, "Create new debug Character"); |
||||
//create new spatial
|
||||
Node node = new Node(physicsObject.toString()); |
||||
node.addControl(new BulletCharacterDebugControl(this, physicsObject)); |
||||
characters.put(physicsObject, node); |
||||
physicsDebugRootNode.attachChild(node); |
||||
} |
||||
} |
||||
//remove leftover spatials
|
||||
for (Map.Entry<PhysicsCharacter, Spatial> entry : oldObjects.entrySet()) { |
||||
PhysicsCharacter object = entry.getKey(); |
||||
Spatial spatial = entry.getValue(); |
||||
spatial.removeFromParent(); |
||||
} |
||||
} |
||||
|
||||
private void updateVehicles() { |
||||
HashMap<PhysicsVehicle, Spatial> oldObjects = vehicles; |
||||
vehicles = new HashMap<PhysicsVehicle, Spatial>(); |
||||
Collection<PhysicsVehicle> current = space.getVehicleList(); |
||||
//create new map
|
||||
for (Iterator<PhysicsVehicle> it = current.iterator(); it.hasNext();) { |
||||
PhysicsVehicle physicsObject = it.next(); |
||||
//copy existing spatials
|
||||
if (oldObjects.containsKey(physicsObject)) { |
||||
Spatial spat = oldObjects.get(physicsObject); |
||||
vehicles.put(physicsObject, spat); |
||||
oldObjects.remove(physicsObject); |
||||
} else { |
||||
logger.log(Level.FINE, "Create new debug Vehicle"); |
||||
//create new spatial
|
||||
Node node = new Node(physicsObject.toString()); |
||||
node.addControl(new BulletVehicleDebugControl(this, physicsObject)); |
||||
vehicles.put(physicsObject, node); |
||||
physicsDebugRootNode.attachChild(node); |
||||
} |
||||
} |
||||
//remove leftover spatials
|
||||
for (Map.Entry<PhysicsVehicle, Spatial> entry : oldObjects.entrySet()) { |
||||
PhysicsVehicle object = entry.getKey(); |
||||
Spatial spatial = entry.getValue(); |
||||
spatial.removeFromParent(); |
||||
} |
||||
} |
||||
|
||||
public ArrowBuffer getArrowBuffer() { |
||||
return arrowBuffer; |
||||
} |
||||
|
||||
public CollisionShapeBuffer getShapeBuffer() { |
||||
return shapeBuffer; |
||||
} |
||||
|
||||
public static class CollisionShapeBuffer { |
||||
|
||||
public static final Mesh NO_MESH = new Arrow(new Vector3f(0, 0, 0)); |
||||
private HashMap<CollisionShape, Mesh> shapes = new HashMap<CollisionShape, Mesh>(); |
||||
private HashMap<CollisionShape, Mesh> usedShapes = new HashMap<CollisionShape, Mesh>(); |
||||
|
||||
public void resetShapes() { |
||||
shapes = usedShapes; |
||||
usedShapes = new HashMap<CollisionShape, Mesh>(); |
||||
} |
||||
|
||||
public Mesh getShapeMesh(CollisionShape shape) { |
||||
if (shape == null) { |
||||
return null; |
||||
} |
||||
Mesh mesh = shapes.get(shape); |
||||
if (mesh == null) { |
||||
logger.log(Level.FINE, "Create new debug MESH"); |
||||
mesh = DebugShapeFactory.getDebugMesh(shape); |
||||
shapes.put(shape, mesh); |
||||
} |
||||
usedShapes.put(shape, mesh); |
||||
return mesh; |
||||
} |
||||
} |
||||
|
||||
public static class ArrowBuffer { |
||||
|
||||
private final Queue<Arrow> arrows = new ConcurrentLinkedQueue<Arrow>(); |
||||
private final Queue<Arrow> usedArrows = new ConcurrentLinkedQueue<Arrow>(); |
||||
|
||||
public void resetArrows() { |
||||
arrows.addAll(usedArrows); |
||||
} |
||||
|
||||
public Arrow getArrow() { |
||||
return getArrow(Vector3f.UNIT_Y); |
||||
} |
||||
|
||||
public Arrow getArrow(Vector3f extent) { |
||||
Arrow arrow = arrows.poll(); |
||||
if (arrow == null) { |
||||
arrow = new Arrow(extent); |
||||
} else { |
||||
arrow.setArrowExtent(extent); |
||||
} |
||||
usedArrows.add(arrow); |
||||
return arrow; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,91 @@ |
||||
/* |
||||
* Copyright (c) 2009-2012 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.bullet.debug; |
||||
|
||||
import com.jme3.bullet.objects.PhysicsGhostObject; |
||||
import com.jme3.math.Quaternion; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.renderer.RenderManager; |
||||
import com.jme3.renderer.ViewPort; |
||||
import com.jme3.scene.Geometry; |
||||
import com.jme3.scene.Mesh; |
||||
import com.jme3.scene.Node; |
||||
import com.jme3.scene.Spatial; |
||||
|
||||
/** |
||||
* |
||||
* @author normenhansen |
||||
*/ |
||||
public class BulletGhostObjectDebugControl extends AbstractPhysicsDebugControl{ |
||||
protected final PhysicsGhostObject body; |
||||
protected final Geometry geom; |
||||
protected final Vector3f location = new Vector3f(); |
||||
protected final Quaternion rotation = new Quaternion(); |
||||
|
||||
public BulletGhostObjectDebugControl(BulletDebugAppState debugAppState, PhysicsGhostObject body) { |
||||
super(debugAppState); |
||||
this.body = body; |
||||
this.geom = new Geometry(body.toString()); |
||||
geom.setMaterial(debugAppState.DEBUG_YELLOW); |
||||
} |
||||
|
||||
@Override |
||||
public void setSpatial(Spatial spatial) { |
||||
if (spatial != null && spatial instanceof Node) { |
||||
Node node = (Node) spatial; |
||||
node.attachChild(geom); |
||||
} else if (spatial == null && this.spatial != null) { |
||||
Node node = (Node) this.spatial; |
||||
node.detachChild(geom); |
||||
} |
||||
super.setSpatial(spatial); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlUpdate(float tpf) { |
||||
Mesh mesh = debugAppState.getShapeBuffer().getShapeMesh(body.getCollisionShape()); |
||||
if (mesh != null) { |
||||
if (geom.getMesh() != mesh) { |
||||
geom.setMesh(mesh); |
||||
} |
||||
} else { |
||||
if (geom.getMesh() != BulletDebugAppState.CollisionShapeBuffer.NO_MESH) { |
||||
geom.setMesh(BulletDebugAppState.CollisionShapeBuffer.NO_MESH); |
||||
} |
||||
} |
||||
applyPhysicsTransform(body.getPhysicsLocation(location), Quaternion.IDENTITY); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlRender(RenderManager rm, ViewPort vp) { |
||||
} |
||||
} |
@ -0,0 +1,106 @@ |
||||
/* |
||||
* Copyright (c) 2009-2012 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.bullet.debug; |
||||
|
||||
import com.jme3.bullet.joints.PhysicsJoint; |
||||
import com.jme3.math.Quaternion; |
||||
import com.jme3.math.Transform; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.renderer.RenderManager; |
||||
import com.jme3.renderer.ViewPort; |
||||
import com.jme3.scene.Geometry; |
||||
import com.jme3.scene.Node; |
||||
import com.jme3.scene.Spatial; |
||||
import com.jme3.scene.debug.Arrow; |
||||
|
||||
/** |
||||
* |
||||
* @author normenhansen |
||||
*/ |
||||
public class BulletJointDebugControl extends AbstractPhysicsDebugControl { |
||||
|
||||
protected final PhysicsJoint body; |
||||
protected final Geometry geomA; |
||||
protected final Arrow arrowA; |
||||
protected final Geometry geomB; |
||||
protected final Arrow arrowB; |
||||
protected final Transform a = new Transform(new Vector3f(), new Quaternion()); |
||||
protected final Transform b = new Transform(new Vector3f(), new Quaternion()); |
||||
protected final Vector3f offA = new Vector3f(); |
||||
protected final Vector3f offB = new Vector3f(); |
||||
|
||||
public BulletJointDebugControl(BulletDebugAppState debugAppState, PhysicsJoint body) { |
||||
super(debugAppState); |
||||
this.body = body; |
||||
this.geomA = new Geometry(body.toString()); |
||||
arrowA = new Arrow(Vector3f.ZERO); |
||||
geomA.setMesh(arrowA); |
||||
geomA.setMaterial(debugAppState.DEBUG_GREEN); |
||||
this.geomB = new Geometry(body.toString()); |
||||
arrowB = new Arrow(Vector3f.ZERO); |
||||
geomB.setMesh(arrowB); |
||||
geomB.setMaterial(debugAppState.DEBUG_GREEN); |
||||
} |
||||
|
||||
@Override |
||||
public void setSpatial(Spatial spatial) { |
||||
if (spatial != null && spatial instanceof Node) { |
||||
Node node = (Node) spatial; |
||||
node.attachChild(geomA); |
||||
node.attachChild(geomB); |
||||
} else if (spatial == null && this.spatial != null) { |
||||
Node node = (Node) this.spatial; |
||||
node.detachChild(geomA); |
||||
node.detachChild(geomB); |
||||
} |
||||
super.setSpatial(spatial); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlUpdate(float tpf) { |
||||
body.getBodyA().getPhysicsLocation(a.getTranslation()); |
||||
body.getBodyA().getPhysicsRotation(a.getRotation()); |
||||
|
||||
body.getBodyB().getPhysicsLocation(b.getTranslation()); |
||||
body.getBodyB().getPhysicsRotation(b.getRotation()); |
||||
|
||||
geomA.setLocalTransform(a); |
||||
geomB.setLocalTransform(b); |
||||
|
||||
arrowA.setArrowExtent(body.getPivotA()); |
||||
arrowB.setArrowExtent(body.getPivotB()); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlRender(RenderManager rm, ViewPort vp) { |
||||
} |
||||
} |
@ -0,0 +1,95 @@ |
||||
/* |
||||
* Copyright (c) 2009-2012 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.bullet.debug; |
||||
|
||||
import com.jme3.bullet.debug.BulletDebugAppState.CollisionShapeBuffer; |
||||
import com.jme3.bullet.objects.PhysicsRigidBody; |
||||
import com.jme3.math.Quaternion; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.renderer.RenderManager; |
||||
import com.jme3.renderer.ViewPort; |
||||
import com.jme3.scene.Geometry; |
||||
import com.jme3.scene.Mesh; |
||||
import com.jme3.scene.Node; |
||||
import com.jme3.scene.Spatial; |
||||
import java.util.logging.Logger; |
||||
|
||||
/** |
||||
* |
||||
* @author normenhansen |
||||
*/ |
||||
public class BulletRigidBodyDebugControl extends AbstractPhysicsDebugControl { |
||||
|
||||
private static final Logger logger = Logger.getLogger(BulletRigidBodyDebugControl.class.getName()); |
||||
protected final PhysicsRigidBody body; |
||||
protected final Geometry geom; |
||||
protected final Vector3f location = new Vector3f(); |
||||
protected final Quaternion rotation = new Quaternion(); |
||||
|
||||
public BulletRigidBodyDebugControl(BulletDebugAppState debugAppState, PhysicsRigidBody body) { |
||||
super(debugAppState); |
||||
this.body = body; |
||||
this.geom = new Geometry(body.toString()); |
||||
geom.setMaterial(debugAppState.DEBUG_BLUE); |
||||
} |
||||
|
||||
@Override |
||||
public void setSpatial(Spatial spatial) { |
||||
if (spatial != null && spatial instanceof Node) { |
||||
Node node = (Node) spatial; |
||||
node.attachChild(geom); |
||||
} else if (spatial == null && this.spatial != null) { |
||||
Node node = (Node) this.spatial; |
||||
node.detachChild(geom); |
||||
} |
||||
super.setSpatial(spatial); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlUpdate(float tpf) { |
||||
Mesh mesh = debugAppState.getShapeBuffer().getShapeMesh(body.getCollisionShape()); |
||||
if (mesh != null) { |
||||
if (geom.getMesh() != mesh) { |
||||
geom.setMesh(mesh); |
||||
} |
||||
} else { |
||||
if (geom.getMesh() != CollisionShapeBuffer.NO_MESH) { |
||||
geom.setMesh(CollisionShapeBuffer.NO_MESH); |
||||
} |
||||
} |
||||
applyPhysicsTransform(body.getPhysicsLocation(location), body.getPhysicsRotation(rotation)); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlRender(RenderManager rm, ViewPort vp) { |
||||
} |
||||
} |
@ -0,0 +1,142 @@ |
||||
/* |
||||
* Copyright (c) 2009-2012 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.bullet.debug; |
||||
|
||||
import com.jme3.bullet.objects.PhysicsVehicle; |
||||
import com.jme3.bullet.objects.VehicleWheel; |
||||
import com.jme3.math.Quaternion; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.renderer.RenderManager; |
||||
import com.jme3.renderer.ViewPort; |
||||
import com.jme3.scene.Geometry; |
||||
import com.jme3.scene.Node; |
||||
import com.jme3.scene.Spatial; |
||||
import com.jme3.scene.debug.Arrow; |
||||
|
||||
/** |
||||
* |
||||
* @author normenhansen |
||||
*/ |
||||
public class BulletVehicleDebugControl extends AbstractPhysicsDebugControl { |
||||
|
||||
protected final PhysicsVehicle body; |
||||
protected final Node suspensionNode; |
||||
protected final Vector3f location = new Vector3f(); |
||||
protected final Quaternion rotation = new Quaternion(); |
||||
|
||||
public BulletVehicleDebugControl(BulletDebugAppState debugAppState, PhysicsVehicle body) { |
||||
super(debugAppState); |
||||
this.body = body; |
||||
suspensionNode = new Node("Suspension"); |
||||
createVehicle(); |
||||
} |
||||
|
||||
@Override |
||||
public void setSpatial(Spatial spatial) { |
||||
if (spatial != null && spatial instanceof Node) { |
||||
Node node = (Node) spatial; |
||||
node.attachChild(suspensionNode); |
||||
} else if (spatial == null && this.spatial != null) { |
||||
Node node = (Node) this.spatial; |
||||
node.detachChild(suspensionNode); |
||||
} |
||||
super.setSpatial(spatial); |
||||
} |
||||
|
||||
private void createVehicle() { |
||||
suspensionNode.detachAllChildren(); |
||||
for (int i = 0; i < body.getNumWheels(); i++) { |
||||
VehicleWheel physicsVehicleWheel = body.getWheel(i); |
||||
Vector3f location = physicsVehicleWheel.getLocation().clone(); |
||||
Vector3f direction = physicsVehicleWheel.getDirection().clone(); |
||||
Vector3f axle = physicsVehicleWheel.getAxle().clone(); |
||||
float restLength = physicsVehicleWheel.getRestLength(); |
||||
float radius = physicsVehicleWheel.getRadius(); |
||||
|
||||
Arrow locArrow = new Arrow(location); |
||||
Arrow axleArrow = new Arrow(axle.normalizeLocal().multLocal(0.3f)); |
||||
Arrow wheelArrow = new Arrow(direction.normalizeLocal().multLocal(radius)); |
||||
Arrow dirArrow = new Arrow(direction.normalizeLocal().multLocal(restLength)); |
||||
Geometry locGeom = new Geometry("WheelLocationDebugShape" + i, locArrow); |
||||
Geometry dirGeom = new Geometry("WheelDirectionDebugShape" + i, dirArrow); |
||||
Geometry axleGeom = new Geometry("WheelAxleDebugShape" + i, axleArrow); |
||||
Geometry wheelGeom = new Geometry("WheelRadiusDebugShape" + i, wheelArrow); |
||||
dirGeom.setLocalTranslation(location); |
||||
axleGeom.setLocalTranslation(location.add(direction)); |
||||
wheelGeom.setLocalTranslation(location.add(direction)); |
||||
locGeom.setMaterial(debugAppState.DEBUG_GREEN); |
||||
dirGeom.setMaterial(debugAppState.DEBUG_GREEN); |
||||
axleGeom.setMaterial(debugAppState.DEBUG_GREEN); |
||||
wheelGeom.setMaterial(debugAppState.DEBUG_GREEN); |
||||
suspensionNode.attachChild(locGeom); |
||||
suspensionNode.attachChild(dirGeom); |
||||
suspensionNode.attachChild(axleGeom); |
||||
suspensionNode.attachChild(wheelGeom); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected void controlUpdate(float tpf) { |
||||
for (int i = 0; i < body.getNumWheels(); i++) { |
||||
VehicleWheel physicsVehicleWheel = body.getWheel(i); |
||||
Vector3f location = physicsVehicleWheel.getLocation().clone(); |
||||
Vector3f direction = physicsVehicleWheel.getDirection().clone(); |
||||
Vector3f axle = physicsVehicleWheel.getAxle().clone(); |
||||
float restLength = physicsVehicleWheel.getRestLength(); |
||||
float radius = physicsVehicleWheel.getRadius(); |
||||
|
||||
Geometry locGeom = (Geometry) suspensionNode.getChild("WheelLocationDebugShape" + i); |
||||
Geometry dirGeom = (Geometry) suspensionNode.getChild("WheelDirectionDebugShape" + i); |
||||
Geometry axleGeom = (Geometry) suspensionNode.getChild("WheelAxleDebugShape" + i); |
||||
Geometry wheelGeom = (Geometry) suspensionNode.getChild("WheelRadiusDebugShape" + i); |
||||
|
||||
Arrow locArrow = (Arrow) locGeom.getMesh(); |
||||
locArrow.setArrowExtent(location); |
||||
Arrow axleArrow = (Arrow) axleGeom.getMesh(); |
||||
axleArrow.setArrowExtent(axle.normalizeLocal().multLocal(0.3f)); |
||||
Arrow wheelArrow = (Arrow) wheelGeom.getMesh(); |
||||
wheelArrow.setArrowExtent(direction.normalizeLocal().multLocal(radius)); |
||||
Arrow dirArrow = (Arrow) dirGeom.getMesh(); |
||||
dirArrow.setArrowExtent(direction.normalizeLocal().multLocal(restLength)); |
||||
|
||||
dirGeom.setLocalTranslation(location); |
||||
axleGeom.setLocalTranslation(location.addLocal(direction)); |
||||
wheelGeom.setLocalTranslation(location); |
||||
i++; |
||||
} |
||||
applyPhysicsTransform(body.getPhysicsLocation(location), body.getPhysicsRotation(rotation)); |
||||
} |
||||
|
||||
@Override |
||||
protected void controlRender(RenderManager rm, ViewPort vp) { |
||||
} |
||||
} |
Loading…
Reference in new issue