aboutsummaryrefslogtreecommitdiff
path: root/engine/src/jbullet/com/jme3/bullet/objects/PhysicsCharacter.java
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/jbullet/com/jme3/bullet/objects/PhysicsCharacter.java')
-rw-r--r--engine/src/jbullet/com/jme3/bullet/objects/PhysicsCharacter.java290
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()));
+ }
+}