diff options
Diffstat (limited to 'engine/src/jbullet/com/jme3/bullet/objects/PhysicsCharacter.java')
-rw-r--r-- | engine/src/jbullet/com/jme3/bullet/objects/PhysicsCharacter.java | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/engine/src/jbullet/com/jme3/bullet/objects/PhysicsCharacter.java b/engine/src/jbullet/com/jme3/bullet/objects/PhysicsCharacter.java new file mode 100644 index 0000000..932c2e1 --- /dev/null +++ b/engine/src/jbullet/com/jme3/bullet/objects/PhysicsCharacter.java @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2009-2010 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.objects; + +import com.bulletphysics.collision.dispatch.CollisionFlags; +import com.bulletphysics.collision.dispatch.PairCachingGhostObject; +import com.bulletphysics.collision.shapes.ConvexShape; +import com.bulletphysics.dynamics.character.KinematicCharacterController; +import com.bulletphysics.linearmath.Transform; +import com.jme3.bullet.collision.PhysicsCollisionObject; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.util.Converter; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; +import com.jme3.math.Matrix3f; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import java.io.IOException; + +/** + * Basic Bullet Character + * @author normenhansen + */ +public class PhysicsCharacter extends PhysicsCollisionObject { + + protected KinematicCharacterController character; + protected float stepHeight; + protected Vector3f walkDirection = new Vector3f(); + protected float fallSpeed = 55.0f; + protected float jumpSpeed = 10.0f; + protected int upAxis = 1; + protected PairCachingGhostObject gObject; + protected boolean locationDirty = false; + //TEMP VARIABLES + protected final Quaternion tmp_inverseWorldRotation = new Quaternion(); + private Transform tempTrans = new Transform(Converter.convert(new Matrix3f())); + private com.jme3.math.Transform physicsLocation = new com.jme3.math.Transform(); + private javax.vecmath.Vector3f tempVec = new javax.vecmath.Vector3f(); + + public PhysicsCharacter() { + } + + /** + * @param shape The CollisionShape (no Mesh or CompoundCollisionShapes) + * @param stepHeight The quantization size for vertical movement + */ + public PhysicsCharacter(CollisionShape shape, float stepHeight) { + this.collisionShape = shape; + if (!(shape.getCShape() instanceof ConvexShape)) { + throw (new UnsupportedOperationException("Kinematic character nodes cannot have mesh collision shapes")); + } + this.stepHeight = stepHeight; + buildObject(); + } + + protected void buildObject() { + if (gObject == null) { + gObject = new PairCachingGhostObject(); + } + gObject.setCollisionFlags(CollisionFlags.CHARACTER_OBJECT); + gObject.setCollisionFlags(gObject.getCollisionFlags() & ~CollisionFlags.NO_CONTACT_RESPONSE); + gObject.setCollisionShape(collisionShape.getCShape()); + gObject.setUserPointer(this); + character = new KinematicCharacterController(gObject, (ConvexShape) collisionShape.getCShape(), stepHeight); + } + + /** + * Sets the location of this physics character + * @param location + */ + public void warp(Vector3f location) { + character.warp(Converter.convert(location, tempVec)); + } + + /** + * Set the walk direction, works continuously. + * This should probably be called setPositionIncrementPerSimulatorStep. + * This is neither a direction nor a velocity, but the amount to + * increment the position each physics tick. So vector length = accuracy*speed in m/s + * @param vec the walk direction to set + */ + public void setWalkDirection(Vector3f vec) { + walkDirection.set(vec); + character.setWalkDirection(Converter.convert(walkDirection, tempVec)); + } + + /** + * @return the currently set walkDirection + */ + public Vector3f getWalkDirection() { + return walkDirection; + } + + public void setUpAxis(int axis) { + upAxis = axis; + character.setUpAxis(axis); + } + + public int getUpAxis() { + return upAxis; + } + + public void setFallSpeed(float fallSpeed) { + this.fallSpeed = fallSpeed; + character.setFallSpeed(fallSpeed); + } + + public float getFallSpeed() { + return fallSpeed; + } + + public void setJumpSpeed(float jumpSpeed) { + this.jumpSpeed = jumpSpeed; + character.setJumpSpeed(jumpSpeed); + } + + public float getJumpSpeed() { + return jumpSpeed; + } + + //does nothing.. +// public void setMaxJumpHeight(float height) { +// character.setMaxJumpHeight(height); +// } + public void setGravity(float value) { + character.setGravity(value); + } + + public float getGravity() { + return character.getGravity(); + } + + public void setMaxSlope(float slopeRadians) { + character.setMaxSlope(slopeRadians); + } + + public float getMaxSlope() { + return character.getMaxSlope(); + } + + public boolean onGround() { + return character.onGround(); + } + + public void jump() { + character.jump(); + } + + @Override + public void setCollisionShape(CollisionShape collisionShape) { + if (!(collisionShape.getCShape() instanceof ConvexShape)) { + throw (new UnsupportedOperationException("Kinematic character nodes cannot have mesh collision shapes")); + } + super.setCollisionShape(collisionShape); + if (gObject == null) { + buildObject(); + }else{ + gObject.setCollisionShape(collisionShape.getCShape()); + } + } + + /** + * Set the physics location (same as warp()) + * @param location the location of the actual physics object + */ + public void setPhysicsLocation(Vector3f location) { + warp(location); + } + + /** + * @return the physicsLocation + */ + public Vector3f getPhysicsLocation(Vector3f trans) { + if (trans == null) { + trans = new Vector3f(); + } + gObject.getWorldTransform(tempTrans); + Converter.convert(tempTrans.origin, physicsLocation.getTranslation()); + return trans.set(physicsLocation.getTranslation()); + } + + /** + * @return the physicsLocation + */ + public Vector3f getPhysicsLocation() { + gObject.getWorldTransform(tempTrans); + Converter.convert(tempTrans.origin, physicsLocation.getTranslation()); + return physicsLocation.getTranslation(); + } + + public void setCcdSweptSphereRadius(float radius) { + gObject.setCcdSweptSphereRadius(radius); + } + + public void setCcdMotionThreshold(float threshold) { + gObject.setCcdMotionThreshold(threshold); + } + + public float getCcdSweptSphereRadius() { + return gObject.getCcdSweptSphereRadius(); + } + + public float getCcdMotionThreshold() { + return gObject.getCcdMotionThreshold(); + } + + public float getCcdSquareMotionThreshold() { + return gObject.getCcdSquareMotionThreshold(); + } + + /** + * used internally + */ + public KinematicCharacterController getControllerId() { + return character; + } + + /** + * used internally + */ + public PairCachingGhostObject getObjectId() { + return gObject; + } + + public void destroy() { + } + + @Override + public void write(JmeExporter e) throws IOException { + super.write(e); + OutputCapsule capsule = e.getCapsule(this); + capsule.write(stepHeight, "stepHeight", 1.0f); + capsule.write(getGravity(), "gravity", 9.8f * 3); + capsule.write(getMaxSlope(), "maxSlope", 1.0f); + capsule.write(fallSpeed, "fallSpeed", 55.0f); + capsule.write(jumpSpeed, "jumpSpeed", 10.0f); + capsule.write(upAxis, "upAxis", 1); + capsule.write(getCcdMotionThreshold(), "ccdMotionThreshold", 0); + capsule.write(getCcdSweptSphereRadius(), "ccdSweptSphereRadius", 0); + capsule.write(getPhysicsLocation(new Vector3f()), "physicsLocation", new Vector3f()); + } + + @Override + public void read(JmeImporter e) throws IOException { + super.read(e); + InputCapsule capsule = e.getCapsule(this); + stepHeight = capsule.readFloat("stepHeight", 1.0f); + buildObject(); + character = new KinematicCharacterController(gObject, (ConvexShape) collisionShape.getCShape(), stepHeight); + setGravity(capsule.readFloat("gravity", 9.8f * 3)); + setMaxSlope(capsule.readFloat("maxSlope", 1.0f)); + setFallSpeed(capsule.readFloat("fallSpeed", 55.0f)); + setJumpSpeed(capsule.readFloat("jumpSpeed", 10.0f)); + setUpAxis(capsule.readInt("upAxis", 1)); + setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0)); + setCcdSweptSphereRadius(capsule.readFloat("ccdSweptSphereRadius", 0)); + setPhysicsLocation((Vector3f) capsule.readSavable("physicsLocation", new Vector3f())); + } +} |