package fr.lyrgard.hexScape.camera; import com.jme3.input.InputManager; import com.jme3.input.KeyInput; import com.jme3.input.MouseInput; import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.AnalogListener; import com.jme3.input.controls.KeyTrigger; import com.jme3.input.controls.MouseAxisTrigger; import com.jme3.input.controls.MouseButtonTrigger; import com.jme3.math.Matrix3f; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; import fr.lyrgard.hexScape.HexScapeCore; import fr.lyrgard.hexScape.model.map.Direction; public class PointOfViewCamera implements AnalogListener, ActionListener { public static final String POVCAM_Left = "POVCAM_Left"; public static final String POVCAM_Right = "POVCAM_Right"; public static final String POVCAM_Up = "POVCAM_Up"; public static final String POVCAM_Down = "POVCAM_Down"; public static final String POVCAM_Mouse_Left = "POVCAM_Mouse_Left"; public static final String POVCAM_Mouse_Right = "POVCAM_Mouse_Right"; public static final String POVCAM_Mouse_Up = "POVCAM_Mouse_Up"; public static final String POVCAM_Mouse_Down = "POVCAM_Mouse_Down"; public static final String POVCAM_RotateDrag = "POVCAM_RotateDrag"; public static final String POVCAM_Exit = "POVCAM_Exit"; private Camera cam; private Vector3f initialUpVec; private float rotationSpeed = 1f; private boolean dragToRotate = true; private boolean canRotate = false; private InputManager inputManager; /** * Creates a new FlyByCamera to control the given Camera object. * @param cam */ public PointOfViewCamera(Camera cam){ this.cam = cam; initialUpVec = new Vector3f(0, 1, 0);//cam.getUp().clone(); } /** * Sets the rotation speed. * @param rotationSpeed */ public void setRotationSpeed(float rotationSpeed){ this.rotationSpeed = rotationSpeed; } /** * @return If drag to rotate feature is enabled. * * @see FlyByCamera#setDragToRotate(boolean) */ public boolean isDragToRotate() { return dragToRotate; } /** * @param dragToRotate When true, the user must hold the mouse button * and drag over the screen to rotate the camera, and the cursor is * visible until dragged. Otherwise, the cursor is invisible at all times * and holding the mouse button is not needed to rotate the camera. * This feature is disabled by default. */ public void setDragToRotate(boolean dragToRotate) { this.dragToRotate = dragToRotate; inputManager.setCursorVisible(dragToRotate); } /** * Registers the FlyByCamera to receive input events from the provided * Dispatcher. * @param dispacher */ public void registerWithInput(InputManager inputManager){ this.inputManager = inputManager; String[] mappings = new String[]{ POVCAM_Left, POVCAM_Right, POVCAM_Up, POVCAM_Down, POVCAM_Mouse_Left, POVCAM_Mouse_Right, POVCAM_Mouse_Up, POVCAM_Mouse_Down, POVCAM_RotateDrag, POVCAM_Exit }; // button only - exit inputManager.addMapping(POVCAM_Exit, new KeyTrigger(KeyInput.KEY_ESCAPE)); // both mouse and button - rotation of cam inputManager.addMapping(POVCAM_Left, new KeyTrigger(KeyInput.KEY_LEFT)); inputManager.addMapping(POVCAM_Right, new KeyTrigger(KeyInput.KEY_RIGHT)); inputManager.addMapping(POVCAM_Up, new KeyTrigger(KeyInput.KEY_UP)); inputManager.addMapping(POVCAM_Down, new KeyTrigger(KeyInput.KEY_DOWN)); inputManager.addMapping(POVCAM_Mouse_Left, new MouseAxisTrigger(0, true)); inputManager.addMapping(POVCAM_Mouse_Right, new MouseAxisTrigger(0, false)); inputManager.addMapping(POVCAM_Mouse_Up, new MouseAxisTrigger(1, false)); inputManager.addMapping(POVCAM_Mouse_Down, new MouseAxisTrigger(1, true)); // mouse only - zoom in/out with wheel, and rotate drag inputManager.addMapping(POVCAM_RotateDrag, new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); inputManager.addListener(this, mappings); inputManager.setCursorVisible(dragToRotate); } public void unregisterFromInput(){ if (this.inputManager == null) { return; } String[] mappings = {POVCAM_Left, POVCAM_Right, POVCAM_Up, POVCAM_Down, POVCAM_Mouse_Left, POVCAM_Mouse_Right, POVCAM_Mouse_Up, POVCAM_Mouse_Down, POVCAM_RotateDrag, POVCAM_Exit}; for (String s : mappings) { if (this.inputManager.hasMapping(s)) { this.inputManager.deleteMapping(s); } } this.inputManager.removeListener(this); } private void rotateCamera(float value, Vector3f axis){ Matrix3f mat = new Matrix3f(); mat.fromAngleNormalAxis(rotationSpeed * value, axis); Vector3f up = cam.getUp(); Vector3f left = cam.getLeft(); Vector3f dir = cam.getDirection(); mat.mult(up, up); mat.mult(left, left); mat.mult(dir, dir); Quaternion q = new Quaternion(); q.fromAxes(left, up, dir); q.normalizeLocal(); cam.setAxes(q); } public void onAnalog(String name, float value, float tpf) { if (name.equals(POVCAM_Left)){ rotateCamera(value, initialUpVec); }else if (name.equals(POVCAM_Right)){ rotateCamera(-value, initialUpVec); }else if (name.equals(POVCAM_Up)){ rotateCamera(-value, cam.getLeft()); }else if (name.equals(POVCAM_Down)){ rotateCamera(value, cam.getLeft()); } else if (name.equals(POVCAM_Exit)) { HexScapeCore.getInstance().getHexScapeJme3Application().lookAtTheMap(); } else if (canRotate) { if (name.equals(POVCAM_Mouse_Left)){ rotateCamera(value, initialUpVec); }else if (name.equals(POVCAM_Mouse_Right)){ rotateCamera(-value, initialUpVec); }else if (name.equals(POVCAM_Mouse_Up)){ rotateCamera(-value, cam.getLeft()); }else if (name.equals(POVCAM_Mouse_Down)){ rotateCamera(value, cam.getLeft()); } } } public void onAction(String name, boolean value, float tpf) { if (name.equals(POVCAM_RotateDrag)){ canRotate = value; inputManager.setCursorVisible(!value); } } public void setPosition(Vector3f pos, Direction dir) { //cam.setLocation(new Vector3f(0, 100, 0)); cam.setLocation(pos); cam.lookAt(new Vector3f(0, 0, 0), new Vector3f(0, 1, 0)); // cam.lookAt(new Vector3f(x, y, z), initialUpVec); } }