aboutsummaryrefslogtreecommitdiff
path: root/engine/src/test/jme3test/bullet/TestAttachDriver.java
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/test/jme3test/bullet/TestAttachDriver.java')
-rw-r--r--engine/src/test/jme3test/bullet/TestAttachDriver.java294
1 files changed, 294 insertions, 0 deletions
diff --git a/engine/src/test/jme3test/bullet/TestAttachDriver.java b/engine/src/test/jme3test/bullet/TestAttachDriver.java
new file mode 100644
index 0000000..31f5f2f
--- /dev/null
+++ b/engine/src/test/jme3test/bullet/TestAttachDriver.java
@@ -0,0 +1,294 @@
+/*
+ * 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 jme3test.bullet;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.asset.TextureKey;
+import com.jme3.bullet.BulletAppState;
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.collision.shapes.BoxCollisionShape;
+import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
+import com.jme3.bullet.collision.shapes.MeshCollisionShape;
+import com.jme3.bullet.control.RigidBodyControl;
+import com.jme3.bullet.control.VehicleControl;
+import com.jme3.bullet.joints.SliderJoint;
+import com.jme3.input.KeyInput;
+import com.jme3.input.controls.ActionListener;
+import com.jme3.input.controls.KeyTrigger;
+import com.jme3.material.Material;
+import com.jme3.math.*;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.shape.Box;
+import com.jme3.scene.shape.Cylinder;
+import com.jme3.texture.Texture;
+
+/**
+ * Tests attaching/detaching nodes via joints
+ * @author normenhansen
+ */
+public class TestAttachDriver extends SimpleApplication implements ActionListener {
+
+ private VehicleControl vehicle;
+ private RigidBodyControl driver;
+ private RigidBodyControl bridge;
+ private SliderJoint slider;
+ private final float accelerationForce = 1000.0f;
+ private final float brakeForce = 100.0f;
+ private float steeringValue = 0;
+ private float accelerationValue = 0;
+ private Vector3f jumpForce = new Vector3f(0, 3000, 0);
+ private BulletAppState bulletAppState;
+
+ public static void main(String[] args) {
+ TestAttachDriver app = new TestAttachDriver();
+ app.start();
+ }
+
+ @Override
+ public void simpleInitApp() {
+ bulletAppState = new BulletAppState();
+ stateManager.attach(bulletAppState);
+ bulletAppState.getPhysicsSpace().enableDebug(assetManager);
+ setupKeys();
+ setupFloor();
+ buildPlayer();
+ }
+
+ private PhysicsSpace getPhysicsSpace(){
+ return bulletAppState.getPhysicsSpace();
+ }
+
+ private void setupKeys() {
+ inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H));
+ inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K));
+ inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U));
+ inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J));
+ inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE));
+ inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN));
+ inputManager.addListener(this, "Lefts");
+ inputManager.addListener(this, "Rights");
+ inputManager.addListener(this, "Ups");
+ inputManager.addListener(this, "Downs");
+ inputManager.addListener(this, "Space");
+ inputManager.addListener(this, "Reset");
+ }
+
+ public void setupFloor() {
+ Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+ TextureKey key = new TextureKey("Interface/Logo/Monkey.jpg", true);
+ key.setGenerateMips(true);
+ Texture tex = assetManager.loadTexture(key);
+ tex.setMinFilter(Texture.MinFilter.Trilinear);
+ mat.setTexture("ColorMap", tex);
+
+ Box floor = new Box(Vector3f.ZERO, 100, 1f, 100);
+ Geometry floorGeom = new Geometry("Floor", floor);
+ floorGeom.setMaterial(mat);
+ floorGeom.setLocalTranslation(new Vector3f(0f, -3, 0f));
+
+ floorGeom.addControl(new RigidBodyControl(new MeshCollisionShape(floorGeom.getMesh()), 0));
+ rootNode.attachChild(floorGeom);
+ getPhysicsSpace().add(floorGeom);
+ }
+
+ private void buildPlayer() {
+ Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
+ mat.getAdditionalRenderState().setWireframe(true);
+ mat.setColor("Color", ColorRGBA.Red);
+
+ //create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0
+ //this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0
+ CompoundCollisionShape compoundShape = new CompoundCollisionShape();
+ BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.2f, 0.5f, 2.4f));
+ compoundShape.addChildShape(box, new Vector3f(0, 1, 0));
+
+ //create vehicle node
+ Node vehicleNode=new Node("vehicleNode");
+ vehicle = new VehicleControl(compoundShape, 800);
+ vehicleNode.addControl(vehicle);
+
+ //setting suspension values for wheels, this can be a bit tricky
+ //see also https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en
+ float stiffness = 60.0f;//200=f1 car
+ float compValue = .3f; //(should be lower than damp)
+ float dampValue = .4f;
+ vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));
+ vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));
+ vehicle.setSuspensionStiffness(stiffness);
+ vehicle.setMaxSuspensionForce(10000.0f);
+
+ //Create four wheels and add them at their locations
+ Vector3f wheelDirection = new Vector3f(0, -1, 0); // was 0, -1, 0
+ Vector3f wheelAxle = new Vector3f(-1, 0, 0); // was -1, 0, 0
+ float radius = 0.5f;
+ float restLength = 0.3f;
+ float yOff = 0.5f;
+ float xOff = 1f;
+ float zOff = 2f;
+
+ Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.6f, true);
+
+ Node node1 = new Node("wheel 1 node");
+ Geometry wheels1 = new Geometry("wheel 1", wheelMesh);
+ node1.attachChild(wheels1);
+ wheels1.rotate(0, FastMath.HALF_PI, 0);
+ wheels1.setMaterial(mat);
+ vehicle.addWheel(node1, new Vector3f(-xOff, yOff, zOff),
+ wheelDirection, wheelAxle, restLength, radius, true);
+
+ Node node2 = new Node("wheel 2 node");
+ Geometry wheels2 = new Geometry("wheel 2", wheelMesh);
+ node2.attachChild(wheels2);
+ wheels2.rotate(0, FastMath.HALF_PI, 0);
+ wheels2.setMaterial(mat);
+ vehicle.addWheel(node2, new Vector3f(xOff, yOff, zOff),
+ wheelDirection, wheelAxle, restLength, radius, true);
+
+ Node node3 = new Node("wheel 3 node");
+ Geometry wheels3 = new Geometry("wheel 3", wheelMesh);
+ node3.attachChild(wheels3);
+ wheels3.rotate(0, FastMath.HALF_PI, 0);
+ wheels3.setMaterial(mat);
+ vehicle.addWheel(node3, new Vector3f(-xOff, yOff, -zOff),
+ wheelDirection, wheelAxle, restLength, radius, false);
+
+ Node node4 = new Node("wheel 4 node");
+ Geometry wheels4 = new Geometry("wheel 4", wheelMesh);
+ node4.attachChild(wheels4);
+ wheels4.rotate(0, FastMath.HALF_PI, 0);
+ wheels4.setMaterial(mat);
+ vehicle.addWheel(node4, new Vector3f(xOff, yOff, -zOff),
+ wheelDirection, wheelAxle, restLength, radius, false);
+
+ vehicleNode.attachChild(node1);
+ vehicleNode.attachChild(node2);
+ vehicleNode.attachChild(node3);
+ vehicleNode.attachChild(node4);
+
+ rootNode.attachChild(vehicleNode);
+ getPhysicsSpace().add(vehicle);
+
+ //driver
+ Node driverNode=new Node("driverNode");
+ driverNode.setLocalTranslation(0,2,0);
+ driver=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,.5f,0.2f)));
+ driverNode.addControl(driver);
+
+ rootNode.attachChild(driverNode);
+ getPhysicsSpace().add(driver);
+
+ //joint
+ slider=new SliderJoint(driver, vehicle, Vector3f.UNIT_Y.negate(), Vector3f.UNIT_Y, true);
+ slider.setUpperLinLimit(.1f);
+ slider.setLowerLinLimit(-.1f);
+
+ getPhysicsSpace().add(slider);
+
+ Node pole1Node=new Node("pole1Node");
+ Node pole2Node=new Node("pole1Node");
+ Node bridgeNode=new Node("pole1Node");
+ pole1Node.setLocalTranslation(new Vector3f(-2,-1,4));
+ pole2Node.setLocalTranslation(new Vector3f(2,-1,4));
+ bridgeNode.setLocalTranslation(new Vector3f(0,1.4f,4));
+
+ RigidBodyControl pole1=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,1.25f,0.2f)),0);
+ pole1Node.addControl(pole1);
+ RigidBodyControl pole2=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,1.25f,0.2f)),0);
+ pole2Node.addControl(pole2);
+ bridge=new RigidBodyControl(new BoxCollisionShape(new Vector3f(2.5f,0.2f,0.2f)));
+ bridgeNode.addControl(bridge);
+
+ rootNode.attachChild(pole1Node);
+ rootNode.attachChild(pole2Node);
+ rootNode.attachChild(bridgeNode);
+ getPhysicsSpace().add(pole1);
+ getPhysicsSpace().add(pole2);
+ getPhysicsSpace().add(bridge);
+
+ }
+
+ @Override
+ public void simpleUpdate(float tpf) {
+ Quaternion quat=new Quaternion();
+ cam.lookAt(vehicle.getPhysicsLocation(), Vector3f.UNIT_Y);
+ }
+
+ public void onAction(String binding, boolean value, float tpf) {
+ if (binding.equals("Lefts")) {
+ if (value) {
+ steeringValue += .5f;
+ } else {
+ steeringValue += -.5f;
+ }
+ vehicle.steer(steeringValue);
+ } else if (binding.equals("Rights")) {
+ if (value) {
+ steeringValue += -.5f;
+ } else {
+ steeringValue += .5f;
+ }
+ vehicle.steer(steeringValue);
+ } else if (binding.equals("Ups")) {
+ if (value) {
+ accelerationValue += accelerationForce;
+ } else {
+ accelerationValue -= accelerationForce;
+ }
+ vehicle.accelerate(accelerationValue);
+ } else if (binding.equals("Downs")) {
+ if (value) {
+ vehicle.brake(brakeForce);
+ } else {
+ vehicle.brake(0f);
+ }
+ } else if (binding.equals("Space")) {
+ if (value) {
+ getPhysicsSpace().remove(slider);
+ slider.destroy();
+ vehicle.applyImpulse(jumpForce, Vector3f.ZERO);
+ }
+ } else if (binding.equals("Reset")) {
+ if (value) {
+ System.out.println("Reset");
+ vehicle.setPhysicsLocation(new Vector3f(0, 0, 0));
+ vehicle.setPhysicsRotation(new Matrix3f());
+ vehicle.setLinearVelocity(Vector3f.ZERO);
+ vehicle.setAngularVelocity(Vector3f.ZERO);
+ vehicle.resetSuspension();
+ bridge.setPhysicsLocation(new Vector3f(0,1.4f,4));
+ bridge.setPhysicsRotation(Quaternion.DIRECTION_Z.toRotationMatrix());
+ }
+ }
+ }
+}