Noob question. Why no collision with the terrain/scene? This is the code…
package com.tropicisland.mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.CameraNode;
import com.jme3.scene.control.CameraControl.ControlDirection;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.renderer.RenderManager;
/**
*
* This collision code uses Physics and a custom Action Listener.
* @author
*/
public class Char extends SimpleApplication
implements ActionListener {
private Spatial model;
private BulletAppState bulletAppState;
private RigidBodyControl landscape;
private CharacterControl playerCharacter;
private Node characterNode;
private CameraNode camNode;
boolean rotate = false;
private Vector3f walkDirection = new Vector3f(0,0,0);
private Vector3f viewDirection = new Vector3f(0,0,0);
boolean leftStrafe = false, rightStrafe = false, forward = false, backward = false,
leftRotate = false, rightRotate = false;
//Temporary vectors used on each frame.
//They here to avoid instanciating new vectors on each frame
private Vector3f camDir = new Vector3f();
private Vector3f camLeft = new Vector3f();
public static void main(String[] args) {
Char app = new Char();
app.start();
}
public void simpleInitApp() {
/** Set up Physics */
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//bulletAppState.setDebugEnabled(true);
setUpKeys();
setUpLight();
// We load the scene from the zip file and adjust its size.
Spatial sceneModel = assetManager.loadModel("Scenes/Terrain/desert.j3o");
sceneModel.setLocalTranslation(0, -5.2f, 0);
sceneModel.setLocalScale(2);
rootNode.attachChild(sceneModel);
// We set up collision detection for the scene by creating a
// compound collision shape and a static RigidBodyControl with mass zero.
CollisionShape sceneShape =
CollisionShapeFactory.createMeshShape(sceneModel);
landscape = new RigidBodyControl(sceneShape, 0);
sceneModel.addControl(landscape);
// We set up collision detection for the player
//
// Add a physics character to the world
playerCharacter = new CharacterControl(new CapsuleCollisionShape(0.5f, 1.8f), .1f);
playerCharacter.setPhysicsLocation(new Vector3f(0, 1, 0));
characterNode = new Node("character node");
Spatial model = assetManager.loadModel("Models/v/c.j3o");
model.scale(0.25f);
characterNode.addControl(playerCharacter);
getPhysicsSpace().add(playerCharacter);
rootNode.attachChild(characterNode);
characterNode.attachChild(model);
// We attach the scene and the player to the rootnode and the physics space,
// to make them appear in the game world.
//
// set forward camera node that follows the character
camNode = new CameraNode("CamNode", cam);
camNode.setControlDir(ControlDirection.SpatialToCamera);
camNode.setLocalTranslation(new Vector3f(0, 1, -5));
camNode.lookAt(model.getLocalTranslation(), Vector3f.UNIT_Y);
characterNode.attachChild(camNode);
//disable the default 1st-person flyCam (don't forget this!!)
flyCam.setEnabled(false);
}
private void setUpLight() {
// We add light so we see the scene
Vector3f direction = new Vector3f(-0.1f, -0.7f, -1).normalizeLocal();
DirectionalLight dl = new DirectionalLight();
dl.setDirection(direction);
dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
rootNode.addLight(dl);
}
/** We over-write some navigational key mappings here, so we can
* add physics-controlled walking and jumping: */
private void setUpKeys() {
inputManager.addMapping("Strafe Left",
new KeyTrigger(KeyInput.KEY_Q),
new KeyTrigger(KeyInput.KEY_Z));
inputManager.addMapping("Strafe Right",
new KeyTrigger(KeyInput.KEY_E),
new KeyTrigger(KeyInput.KEY_X));
inputManager.addMapping("Rotate Left",
new KeyTrigger(KeyInput.KEY_A),
new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("Rotate Right",
new KeyTrigger(KeyInput.KEY_D),
new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping("Walk Forward",
new KeyTrigger(KeyInput.KEY_W),
new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("Walk Backward",
new KeyTrigger(KeyInput.KEY_S),
new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("Jump",
new KeyTrigger(KeyInput.KEY_SPACE),
new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addMapping("Shoot",
new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(this, "Strafe Left", "Strafe Right");
inputManager.addListener(this, "Rotate Left", "Rotate Right");
inputManager.addListener(this, "Walk Forward", "Walk Backward");
inputManager.addListener(this, "Jump", "Shoot");
}
/** These are our custom actions triggered by key presses.
* We do not walk yet, we just keep track of the direction the user pressed. */
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Strafe Left")) {
if (value) {
leftStrafe = true;
} else {
leftStrafe = false;
}
} else if (binding.equals("Strafe Right")) {
if (value) {
rightStrafe = true;
} else {
rightStrafe = false;
}
} else if (binding.equals("Rotate Left")) {
if (value) {
leftRotate = true;
} else {
leftRotate = false;
}
} else if (binding.equals("Rotate Right")) {
if (value) {
rightRotate = true;
} else {
rightRotate = false;
}
} else if (binding.equals("Walk Forward")) {
if (value) {
forward = true;
} else {
forward = false;
}
} else if (binding.equals("Walk Backward")) {
if (value) {
backward = true;
} else {
backward = false;
}
} else if (binding.equals("Jump")) {
playerCharacter.jump();
}
}
/**
* This is the main event loop--walking happens here.
*
* The setWalkDirection() command is what lets a physics-controlled player walk.
* We also make sure here that the camera moves with player.
*/
@Override
public void simpleUpdate(float tpf) {
Vector3f camDir = cam.getDirection().mult(0.2f);
Vector3f camLeft = cam.getLeft().mult(0.2f);
camDir.y = 0;
camLeft.y = 0;
viewDirection.set(camDir);
walkDirection.set(0, 0, 0);
if (leftStrafe) {
walkDirection.addLocal(camLeft);
} else
if (rightStrafe) {
walkDirection.addLocal(camLeft.negate());
}
if (leftRotate) {
viewDirection.addLocal(camLeft.mult(0.02f));
} else
if (rightRotate) {
viewDirection.addLocal(camLeft.mult(0.02f).negate());
}
if (forward) {
walkDirection.addLocal(camDir);
} else
if (backward) {
walkDirection.addLocal(camDir.negate());
}
playerCharacter.setWalkDirection(walkDirection);
playerCharacter.setViewDirection(viewDirection);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}