Hello all. So I am going through the wiki and reading some books on JMonkey programming and was trying to implement a first person camera using Camera node with Mouse movement for the view. I can’t quite seem to understand why the camera view isnt working. I have WASD forward,back,strafing working but just not mouse movement. My screen still shows the mouse cursor and doesn’t move the camera when i move the mouse. Can you tell me what it is I am missing or not understanding about camera movement with a mouse and the camera node? I haven’t implemented up/down yet as I was working on Left/Right first. After this I am going to test/learn about the Chase Cam but wanted to understand this version first.
Here is the code:
public class PhysicsTown extends SimpleApplication {
private Node sceneNode;
private BulletAppState bulletAppState;
private RigidBodyControl scenePhysics;
private Node playerNode;
private BetterCharacterControl playerControl;
private CameraNode camNode;
private Vector3f walkDirection = new Vector3f(0,0,0);
private Vector3f viewDirection = new Vector3f(0,0,1);
private boolean viewLeft = false, viewRight = false, forward = false, backward = false, left = false, right = false,
viewUp = false, viewDown = false;
private float speed = 8;
private float yaw = 0;
public static void main(String[] args) {
PhysicsTown app = new PhysicsTown();
app.start();
}
@Override
public void simpleInitApp() {
//Load the Town Scene
assetManager.registerLocator("town.zip", ZipLocator.class);
sceneNode = (Node)assetManager.loadModel("main.scene");
sceneNode.scale(1.5f);
rootNode.attachChild(sceneNode);
//Create Ambient Light
AmbientLight ambient = new AmbientLight();
rootNode.addLight(ambient);
//Create Directional lighting
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(1.4f, -1.4f, -1.4f));
rootNode.addLight(sun);
//Increase Camera Speed
flyCam.setMoveSpeed(50);
//Set the sky to blue
viewPort.setBackgroundColor(ColorRGBA.Cyan);
//Add Physics to the Scene as to not clip through walls and the floor
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
scenePhysics = new RigidBodyControl(0f);
sceneNode.addControl(scenePhysics);
bulletAppState.getPhysicsSpace().add(sceneNode);
//Making the camera solid
playerNode = new Node("the player");
playerNode.setLocalTranslation(new Vector3f(0, 6, 0));
rootNode.attachChild(playerNode);
playerControl = new BetterCharacterControl(1.5f, 4, 30f);
playerControl.setJumpForce(new Vector3f(0, 300, 0));
playerControl.setGravity(new Vector3f(0, -10, 0));
playerNode.addControl(playerControl);
bulletAppState.getPhysicsSpace().add(playerControl);
camNode = new CameraNode("CamNode", cam);
camNode.setControlDir(CameraControl.ControlDirection.SpatialToCamera);
camNode.setLocalTranslation(new Vector3f(0,4,-6));
Quaternion quat = new Quaternion();
quat.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y);
camNode.setLocalRotation(quat);
playerNode.attachChild(camNode);
camNode.setEnabled(true);
flyCam.setEnabled(false);
//Create Key Mappings
inputManager.addMapping("Forward", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Back", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("View Left", new MouseAxisTrigger(MouseInput.AXIS_X, true));
inputManager.addMapping("View Right", new MouseAxisTrigger(MouseInput.AXIS_X, false));
inputManager.addMapping("View Up", new MouseAxisTrigger(MouseInput.AXIS_Y, true));
inputManager.addMapping("View Down", new MouseAxisTrigger(MouseInput.AXIS_Y, false));
//Create Listeners
inputManager.addListener(analogListener, "View Left", "View Right", "View Up", "View Down");
inputManager.addListener(actionListener, "Forward", "Back", "Jump", "Left", "Right");
initCrossHairs();
}
private ActionListener actionListener = new ActionListener() {
@Override
public void onAction(String binding, boolean isPressed, float tpf) {
if (binding.equals("Forward")) {
forward = isPressed;
} else if (binding.equals("Back")) {
backward = isPressed;
} else if (binding.equals("Jump")) {
playerControl.jump();
} else if (binding.equals("Left")) {
left = isPressed;
} else if (binding.equals("Right")) {
right = isPressed;
}
}
};
private AnalogListener analogListener = new AnalogListener() {
@Override
public void onAnalog(String name, float value, float tpf) {
if (name.equals("View Left")) {
rotate(tpf * value);
} else if (name.equals("View Right")) {
rotate(-tpf * value);
} else if(name.equals("View Up")){
} else if (name.equals("LookDown")){
} else if (name.equals("View Down")) {
speed = value * 3;
}
}
};
public void rotate(float value) {
Quaternion rotate = new Quaternion().fromAngleAxis(FastMath.PI * value, Vector3f.UNIT_Y);
rotate.multLocal(viewDirection);
playerControl.setViewDirection(viewDirection);
}
protected void lookUpDown(float value) {
yaw += value;
yaw = FastMath.clamp(yaw, -FastMath.HALF_PI, FastMath.HALF_PI);
playerControl.setViewDirection(new Vector3f(yaw, 0, 0));
}
@Override
public void simpleUpdate(float tpf) {
//Get Current foward and left vectors of the player node
Vector3f modelForwardDir = playerNode.getWorldRotation().mult(Vector3f.UNIT_Z);
Vector3f modelLateralDir = playerNode.getWorldRotation().mult(Vector3f.UNIT_X);
Vector3f modelLeftDir = playerNode.getWorldRotation().mult(Vector3f.UNIT_X);
//Determine the change in direction
walkDirection.set(0, 0, 0);
if (forward) {
walkDirection.addLocal(modelForwardDir.mult(speed));
} else if (backward) {
walkDirection.addLocal(modelForwardDir.mult(speed).negate());
} else if (right) {
walkDirection.addLocal(modelLateralDir.mult(speed).negate());
} else if (left) {
walkDirection.addLocal(modelLateralDir.mult(speed));
}
playerControl.setWalkDirection(walkDirection); //walk!
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
/** A plus sign used as crosshairs to help the player with aiming.*/
protected void initCrossHairs() {
guiNode.detachAllChildren();
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText ch = new BitmapText(guiFont, false);
ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
ch.setText("+"); // fake crosshairs :)
ch.setLocalTranslation( // center
settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
guiNode.attachChild(ch);
}
}