aboutsummaryrefslogtreecommitdiff
path: root/engine/src/core/com/jme3/input
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/core/com/jme3/input')
-rw-r--r--engine/src/core/com/jme3/input/ChaseCamera.java875
-rw-r--r--engine/src/core/com/jme3/input/FlyByCamera.java364
-rw-r--r--engine/src/core/com/jme3/input/Input.java82
-rw-r--r--engine/src/core/com/jme3/input/InputManager.java881
-rw-r--r--engine/src/core/com/jme3/input/JoyInput.java66
-rw-r--r--engine/src/core/com/jme3/input/Joystick.java136
-rw-r--r--engine/src/core/com/jme3/input/KeyInput.java543
-rw-r--r--engine/src/core/com/jme3/input/KeyNames.java153
-rw-r--r--engine/src/core/com/jme3/input/MouseInput.java83
-rw-r--r--engine/src/core/com/jme3/input/RawInputListener.java99
-rw-r--r--engine/src/core/com/jme3/input/TouchInput.java92
-rw-r--r--engine/src/core/com/jme3/input/controls/ActionListener.java58
-rw-r--r--engine/src/core/com/jme3/input/controls/AnalogListener.java53
-rw-r--r--engine/src/core/com/jme3/input/controls/InputListener.java42
-rw-r--r--engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java77
-rw-r--r--engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java73
-rw-r--r--engine/src/core/com/jme3/input/controls/KeyTrigger.java72
-rw-r--r--engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java90
-rw-r--r--engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java79
-rw-r--r--engine/src/core/com/jme3/input/controls/TouchListener.java49
-rw-r--r--engine/src/core/com/jme3/input/controls/TouchTrigger.java73
-rw-r--r--engine/src/core/com/jme3/input/controls/Trigger.java52
-rw-r--r--engine/src/core/com/jme3/input/controls/package.html19
-rw-r--r--engine/src/core/com/jme3/input/dummy/DummyInput.java78
-rw-r--r--engine/src/core/com/jme3/input/dummy/DummyKeyInput.java52
-rw-r--r--engine/src/core/com/jme3/input/dummy/DummyMouseInput.java54
-rw-r--r--engine/src/core/com/jme3/input/dummy/package.html14
-rw-r--r--engine/src/core/com/jme3/input/event/InputEvent.java84
-rw-r--r--engine/src/core/com/jme3/input/event/JoyAxisEvent.java85
-rw-r--r--engine/src/core/com/jme3/input/event/JoyButtonEvent.java89
-rw-r--r--engine/src/core/com/jme3/input/event/KeyInputEvent.java117
-rw-r--r--engine/src/core/com/jme3/input/event/MouseButtonEvent.java111
-rw-r--r--engine/src/core/com/jme3/input/event/MouseMotionEvent.java110
-rw-r--r--engine/src/core/com/jme3/input/event/TouchEvent.java209
-rw-r--r--engine/src/core/com/jme3/input/event/package.html13
-rw-r--r--engine/src/core/com/jme3/input/package.html38
36 files changed, 5165 insertions, 0 deletions
diff --git a/engine/src/core/com/jme3/input/ChaseCamera.java b/engine/src/core/com/jme3/input/ChaseCamera.java
new file mode 100644
index 0000000..b3b649d
--- /dev/null
+++ b/engine/src/core/com/jme3/input/ChaseCamera.java
@@ -0,0 +1,875 @@
+/*
+ * Copyright (c) 2009-2012 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.input;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.input.controls.*;
+import com.jme3.math.FastMath;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.Control;
+import java.io.IOException;
+
+/**
+ * A camera that follows a spatial and can turn around it by dragging the mouse
+ * @author nehon
+ */
+public class ChaseCamera implements ActionListener, AnalogListener, Control {
+
+ protected Spatial target = null;
+ protected float minVerticalRotation = 0.00f;
+ protected float maxVerticalRotation = FastMath.PI / 2;
+ protected float minDistance = 1.0f;
+ protected float maxDistance = 40.0f;
+ protected float distance = 20;
+ protected float zoomSpeed = 2f;
+ protected float rotationSpeed = 1.0f;
+ protected float rotation = 0;
+ protected float trailingRotationInertia = 0.05f;
+ protected float zoomSensitivity = 5f;
+ protected float rotationSensitivity = 5f;
+ protected float chasingSensitivity = 5f;
+ protected float trailingSensitivity = 0.5f;
+ protected float vRotation = FastMath.PI / 6;
+ protected boolean smoothMotion = false;
+ protected boolean trailingEnabled = true;
+ protected float rotationLerpFactor = 0;
+ protected float trailingLerpFactor = 0;
+ protected boolean rotating = false;
+ protected boolean vRotating = false;
+ protected float targetRotation = rotation;
+ protected InputManager inputManager;
+ protected Vector3f initialUpVec;
+ protected float targetVRotation = vRotation;
+ protected float vRotationLerpFactor = 0;
+ protected float targetDistance = distance;
+ protected float distanceLerpFactor = 0;
+ protected boolean zooming = false;
+ protected boolean trailing = false;
+ protected boolean chasing = false;
+ protected boolean canRotate;
+ protected float offsetDistance = 0.002f;
+ protected Vector3f prevPos;
+ protected boolean targetMoves = false;
+ protected boolean enabled = true;
+ protected Camera cam = null;
+ protected final Vector3f targetDir = new Vector3f();
+ protected float previousTargetRotation;
+ protected final Vector3f pos = new Vector3f();
+ protected Vector3f targetLocation = new Vector3f(0, 0, 0);
+ protected boolean dragToRotate = true;
+ protected Vector3f lookAtOffset = new Vector3f(0, 0, 0);
+ protected boolean leftClickRotate = true;
+ protected boolean rightClickRotate = true;
+ protected Vector3f temp = new Vector3f(0, 0, 0);
+ protected boolean invertYaxis = false;
+ protected boolean invertXaxis = false;
+ protected final static String ChaseCamDown = "ChaseCamDown";
+ protected final static String ChaseCamUp = "ChaseCamUp";
+ protected final static String ChaseCamZoomIn = "ChaseCamZoomIn";
+ protected final static String ChaseCamZoomOut = "ChaseCamZoomOut";
+ protected final static String ChaseCamMoveLeft = "ChaseCamMoveLeft";
+ protected final static String ChaseCamMoveRight = "ChaseCamMoveRight";
+ protected final static String ChaseCamToggleRotate = "ChaseCamToggleRotate";
+
+ /**
+ * Constructs the chase camera
+ * @param cam the application camera
+ * @param target the spatial to follow
+ */
+ public ChaseCamera(Camera cam, final Spatial target) {
+ this(cam);
+ target.addControl(this);
+ }
+
+ /**
+ * Constructs the chase camera
+ * if you use this constructor you have to attach the cam later to a spatial
+ * doing spatial.addControl(chaseCamera);
+ * @param cam the application camera
+ */
+ public ChaseCamera(Camera cam) {
+ this.cam = cam;
+ initialUpVec = cam.getUp().clone();
+ }
+
+ /**
+ * Constructs the chase camera, and registers inputs
+ * if you use this constructor you have to attach the cam later to a spatial
+ * doing spatial.addControl(chaseCamera);
+ * @param cam the application camera
+ * @param inputManager the inputManager of the application to register inputs
+ */
+ public ChaseCamera(Camera cam, InputManager inputManager) {
+ this(cam);
+ registerWithInput(inputManager);
+ }
+
+ /**
+ * Constructs the chase camera, and registers inputs
+ * @param cam the application camera
+ * @param target the spatial to follow
+ * @param inputManager the inputManager of the application to register inputs
+ */
+ public ChaseCamera(Camera cam, final Spatial target, InputManager inputManager) {
+ this(cam, target);
+ registerWithInput(inputManager);
+ }
+
+ public void onAction(String name, boolean keyPressed, float tpf) {
+ if (dragToRotate) {
+ if (name.equals(ChaseCamToggleRotate) && enabled) {
+ if (keyPressed) {
+ canRotate = true;
+ inputManager.setCursorVisible(false);
+ } else {
+ canRotate = false;
+ inputManager.setCursorVisible(true);
+ }
+ }
+ }
+
+ }
+ private boolean zoomin;
+
+ public void onAnalog(String name, float value, float tpf) {
+ if (name.equals(ChaseCamMoveLeft)) {
+ rotateCamera(-value);
+ } else if (name.equals(ChaseCamMoveRight)) {
+ rotateCamera(value);
+ } else if (name.equals(ChaseCamUp)) {
+ vRotateCamera(value);
+ } else if (name.equals(ChaseCamDown)) {
+ vRotateCamera(-value);
+ } else if (name.equals(ChaseCamZoomIn)) {
+ zoomCamera(-value);
+ if (zoomin == false) {
+ distanceLerpFactor = 0;
+ }
+ zoomin = true;
+ } else if (name.equals(ChaseCamZoomOut)) {
+ zoomCamera(+value);
+ if (zoomin == true) {
+ distanceLerpFactor = 0;
+ }
+ zoomin = false;
+ }
+ }
+
+ /**
+ * Registers inputs with the input manager
+ * @param inputManager
+ */
+ public final void registerWithInput(InputManager inputManager) {
+
+ String[] inputs = {ChaseCamToggleRotate,
+ ChaseCamDown,
+ ChaseCamUp,
+ ChaseCamMoveLeft,
+ ChaseCamMoveRight,
+ ChaseCamZoomIn,
+ ChaseCamZoomOut};
+
+ this.inputManager = inputManager;
+ if (!invertYaxis) {
+ inputManager.addMapping(ChaseCamDown, new MouseAxisTrigger(MouseInput.AXIS_Y, true));
+ inputManager.addMapping(ChaseCamUp, new MouseAxisTrigger(MouseInput.AXIS_Y, false));
+ } else {
+ inputManager.addMapping(ChaseCamDown, new MouseAxisTrigger(MouseInput.AXIS_Y, false));
+ inputManager.addMapping(ChaseCamUp, new MouseAxisTrigger(MouseInput.AXIS_Y, true));
+ }
+ inputManager.addMapping(ChaseCamZoomIn, new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false));
+ inputManager.addMapping(ChaseCamZoomOut, new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true));
+ if(!invertXaxis){
+ inputManager.addMapping(ChaseCamMoveLeft, new MouseAxisTrigger(MouseInput.AXIS_X, true));
+ inputManager.addMapping(ChaseCamMoveRight, new MouseAxisTrigger(MouseInput.AXIS_X, false));
+ }else{
+ inputManager.addMapping(ChaseCamMoveLeft, new MouseAxisTrigger(MouseInput.AXIS_X, false));
+ inputManager.addMapping(ChaseCamMoveRight, new MouseAxisTrigger(MouseInput.AXIS_X, true));
+ }
+ inputManager.addMapping(ChaseCamToggleRotate, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
+ inputManager.addMapping(ChaseCamToggleRotate, new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
+
+ inputManager.addListener(this, inputs);
+ }
+
+ /**
+ * Sets custom triggers for toggleing the rotation of the cam
+ * deafult are
+ * new MouseButtonTrigger(MouseInput.BUTTON_LEFT) left mouse button
+ * new MouseButtonTrigger(MouseInput.BUTTON_RIGHT) right mouse button
+ * @param triggers
+ */
+ public void setToggleRotationTrigger(Trigger... triggers) {
+ inputManager.deleteMapping(ChaseCamToggleRotate);
+ inputManager.addMapping(ChaseCamToggleRotate, triggers);
+ inputManager.addListener(this, ChaseCamToggleRotate);
+ }
+
+ /**
+ * Sets custom triggers for zomming in the cam
+ * default is
+ * new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true) mouse wheel up
+ * @param triggers
+ */
+ public void setZoomInTrigger(Trigger... triggers) {
+ inputManager.deleteMapping(ChaseCamZoomIn);
+ inputManager.addMapping(ChaseCamZoomIn, triggers);
+ inputManager.addListener(this, ChaseCamZoomIn);
+ }
+
+ /**
+ * Sets custom triggers for zomming out the cam
+ * default is
+ * new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false) mouse wheel down
+ * @param triggers
+ */
+ public void setZoomOutTrigger(Trigger... triggers) {
+ inputManager.deleteMapping(ChaseCamZoomOut);
+ inputManager.addMapping(ChaseCamZoomOut, triggers);
+ inputManager.addListener(this, ChaseCamZoomOut);
+ }
+
+ private void computePosition() {
+
+ float hDistance = (distance) * FastMath.sin((FastMath.PI / 2) - vRotation);
+ pos.set(hDistance * FastMath.cos(rotation), (distance) * FastMath.sin(vRotation), hDistance * FastMath.sin(rotation));
+ pos.addLocal(target.getWorldTranslation());
+ }
+
+ //rotate the camera around the target on the horizontal plane
+ private void rotateCamera(float value) {
+ if (!canRotate || !enabled) {
+ return;
+ }
+ rotating = true;
+ targetRotation += value * rotationSpeed;
+
+
+ }
+
+ //move the camera toward or away the target
+ private void zoomCamera(float value) {
+ if (!enabled) {
+ return;
+ }
+
+ zooming = true;
+ targetDistance += value * zoomSpeed;
+ if (targetDistance > maxDistance) {
+ targetDistance = maxDistance;
+ }
+ if (targetDistance < minDistance) {
+ targetDistance = minDistance;
+ }
+ if ((targetVRotation < minVerticalRotation) && (targetDistance > (minDistance + 1.0f))) {
+ targetVRotation = minVerticalRotation;
+ }
+ }
+
+ //rotate the camera around the target on the vertical plane
+ private void vRotateCamera(float value) {
+ if (!canRotate || !enabled) {
+ return;
+ }
+ vRotating = true;
+ targetVRotation += value * rotationSpeed;
+ if (targetVRotation > maxVerticalRotation) {
+ targetVRotation = maxVerticalRotation;
+ }
+ if ((targetVRotation < minVerticalRotation) && (targetDistance > (minDistance + 1.0f))) {
+ targetVRotation = minVerticalRotation;
+ }
+ }
+
+ /**
+ * Updates the camera, should only be called internally
+ */
+ protected void updateCamera(float tpf) {
+ if (enabled) {
+ targetLocation.set(target.getWorldTranslation()).addLocal(lookAtOffset);
+ if (smoothMotion) {
+
+ //computation of target direction
+ targetDir.set(targetLocation).subtractLocal(prevPos);
+ float dist = targetDir.length();
+
+ //Low pass filtering on the target postition to avoid shaking when physics are enabled.
+ if (offsetDistance < dist) {
+ //target moves, start chasing.
+ chasing = true;
+ //target moves, start trailing if it has to.
+ if (trailingEnabled) {
+ trailing = true;
+ }
+ //target moves...
+ targetMoves = true;
+ } else {
+ //if target was moving, we compute a slight offset in rotation to avoid a rought stop of the cam
+ //We do not if the player is rotationg the cam
+ if (targetMoves && !canRotate) {
+ if (targetRotation - rotation > trailingRotationInertia) {
+ targetRotation = rotation + trailingRotationInertia;
+ } else if (targetRotation - rotation < -trailingRotationInertia) {
+ targetRotation = rotation - trailingRotationInertia;
+ }
+ }
+ //Target stops
+ targetMoves = false;
+ }
+
+ //the user is rotating the cam by dragging the mouse
+ if (canRotate) {
+ //reseting the trailing lerp factor
+ trailingLerpFactor = 0;
+ //stop trailing user has the control
+ trailing = false;
+ }
+
+
+ if (trailingEnabled && trailing) {
+ if (targetMoves) {
+ //computation if the inverted direction of the target
+ Vector3f a = targetDir.negate().normalizeLocal();
+ //the x unit vector
+ Vector3f b = Vector3f.UNIT_X;
+ //2d is good enough
+ a.y = 0;
+ //computation of the rotation angle between the x axis and the trail
+ if (targetDir.z > 0) {
+ targetRotation = FastMath.TWO_PI - FastMath.acos(a.dot(b));
+ } else {
+ targetRotation = FastMath.acos(a.dot(b));
+ }
+ if (targetRotation - rotation > FastMath.PI || targetRotation - rotation < -FastMath.PI) {
+ targetRotation -= FastMath.TWO_PI;
+ }
+
+ //if there is an important change in the direction while trailing reset of the lerp factor to avoid jumpy movements
+ if (targetRotation != previousTargetRotation && FastMath.abs(targetRotation - previousTargetRotation) > FastMath.PI / 8) {
+ trailingLerpFactor = 0;
+ }
+ previousTargetRotation = targetRotation;
+ }
+ //computing lerp factor
+ trailingLerpFactor = Math.min(trailingLerpFactor + tpf * tpf * trailingSensitivity, 1);
+ //computing rotation by linear interpolation
+ rotation = FastMath.interpolateLinear(trailingLerpFactor, rotation, targetRotation);
+
+ //if the rotation is near the target rotation we're good, that's over
+ if (targetRotation + 0.01f >= rotation && targetRotation - 0.01f <= rotation) {
+ trailing = false;
+ trailingLerpFactor = 0;
+ }
+ }
+
+ //linear interpolation of the distance while chasing
+ if (chasing) {
+ distance = temp.set(targetLocation).subtractLocal(cam.getLocation()).length();
+ distanceLerpFactor = Math.min(distanceLerpFactor + (tpf * tpf * chasingSensitivity * 0.05f), 1);
+ distance = FastMath.interpolateLinear(distanceLerpFactor, distance, targetDistance);
+ if (targetDistance + 0.01f >= distance && targetDistance - 0.01f <= distance) {
+ distanceLerpFactor = 0;
+ chasing = false;
+ }
+ }
+
+ //linear interpolation of the distance while zooming
+ if (zooming) {
+ distanceLerpFactor = Math.min(distanceLerpFactor + (tpf * tpf * zoomSensitivity), 1);
+ distance = FastMath.interpolateLinear(distanceLerpFactor, distance, targetDistance);
+ if (targetDistance + 0.1f >= distance && targetDistance - 0.1f <= distance) {
+ zooming = false;
+ distanceLerpFactor = 0;
+ }
+ }
+
+ //linear interpolation of the rotation while rotating horizontally
+ if (rotating) {
+ rotationLerpFactor = Math.min(rotationLerpFactor + tpf * tpf * rotationSensitivity, 1);
+ rotation = FastMath.interpolateLinear(rotationLerpFactor, rotation, targetRotation);
+ if (targetRotation + 0.01f >= rotation && targetRotation - 0.01f <= rotation) {
+ rotating = false;
+ rotationLerpFactor = 0;
+ }
+ }
+
+ //linear interpolation of the rotation while rotating vertically
+ if (vRotating) {
+ vRotationLerpFactor = Math.min(vRotationLerpFactor + tpf * tpf * rotationSensitivity, 1);
+ vRotation = FastMath.interpolateLinear(vRotationLerpFactor, vRotation, targetVRotation);
+ if (targetVRotation + 0.01f >= vRotation && targetVRotation - 0.01f <= vRotation) {
+ vRotating = false;
+ vRotationLerpFactor = 0;
+ }
+ }
+ //computing the position
+ computePosition();
+ //setting the position at last
+ cam.setLocation(pos.addLocal(lookAtOffset));
+ } else {
+ //easy no smooth motion
+ vRotation = targetVRotation;
+ rotation = targetRotation;
+ distance = targetDistance;
+ computePosition();
+ cam.setLocation(pos.addLocal(lookAtOffset));
+ }
+ //keeping track on the previous position of the target
+ prevPos.set(targetLocation);
+
+ //the cam looks at the target
+ cam.lookAt(targetLocation, initialUpVec);
+
+ }
+ }
+
+ /**
+ * Return the enabled/disabled state of the camera
+ * @return true if the camera is enabled
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Enable or disable the camera
+ * @param enabled true to enable
+ */
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ if (!enabled) {
+ canRotate = false; // reset this flag in-case it was on before
+ }
+ }
+
+ /**
+ * Returns the max zoom distance of the camera (default is 40)
+ * @return maxDistance
+ */
+ public float getMaxDistance() {
+ return maxDistance;
+ }
+
+ /**
+ * Sets the max zoom distance of the camera (default is 40)
+ * @param maxDistance
+ */
+ public void setMaxDistance(float maxDistance) {
+ this.maxDistance = maxDistance;
+ }
+
+ /**
+ * Returns the min zoom distance of the camera (default is 1)
+ * @return minDistance
+ */
+ public float getMinDistance() {
+ return minDistance;
+ }
+
+ /**
+ * Sets the min zoom distance of the camera (default is 1)
+ * @return minDistance
+ */
+ public void setMinDistance(float minDistance) {
+ this.minDistance = minDistance;
+ }
+
+ /**
+ * clone this camera for a spatial
+ * @param spatial
+ * @return
+ */
+ public Control cloneForSpatial(Spatial spatial) {
+ ChaseCamera cc = new ChaseCamera(cam, spatial, inputManager);
+ cc.setMaxDistance(getMaxDistance());
+ cc.setMinDistance(getMinDistance());
+ return cc;
+ }
+
+ /**
+ * Sets the spacial for the camera control, should only be used internally
+ * @param spatial
+ */
+ public void setSpatial(Spatial spatial) {
+ target = spatial;
+ if (spatial == null) {
+ return;
+ }
+ computePosition();
+ prevPos = new Vector3f(target.getWorldTranslation());
+ cam.setLocation(pos);
+ }
+
+ /**
+ * update the camera control, should only be used internally
+ * @param tpf
+ */
+ public void update(float tpf) {
+ updateCamera(tpf);
+ }
+
+ /**
+ * renders the camera control, should only be used internally
+ * @param rm
+ * @param vp
+ */
+ public void render(RenderManager rm, ViewPort vp) {
+ //nothing to render
+ }
+
+ /**
+ * Write the camera
+ * @param ex the exporter
+ * @throws IOException
+ */
+ public void write(JmeExporter ex) throws IOException {
+ OutputCapsule capsule = ex.getCapsule(this);
+ capsule.write(maxDistance, "maxDistance", 40);
+ capsule.write(minDistance, "minDistance", 1);
+ }
+
+ /**
+ * Read the camera
+ * @param im
+ * @throws IOException
+ */
+ public void read(JmeImporter im) throws IOException {
+ InputCapsule ic = im.getCapsule(this);
+ maxDistance = ic.readFloat("maxDistance", 40);
+ minDistance = ic.readFloat("minDistance", 1);
+ }
+
+ /**
+ * returns the maximal vertical rotation angle of the camera around the target
+ * @return
+ */
+ public float getMaxVerticalRotation() {
+ return maxVerticalRotation;
+ }
+
+ /**
+ * sets the maximal vertical rotation angle of the camera around the target default is Pi/2;
+ * @param maxVerticalRotation
+ */
+ public void setMaxVerticalRotation(float maxVerticalRotation) {
+ this.maxVerticalRotation = maxVerticalRotation;
+ }
+
+ /**
+ * returns the minimal vertical rotation angle of the camera around the target
+ * @return
+ */
+ public float getMinVerticalRotation() {
+ return minVerticalRotation;
+ }
+
+ /**
+ * sets the minimal vertical rotation angle of the camera around the target default is 0;
+ * @param minHeight
+ */
+ public void setMinVerticalRotation(float minHeight) {
+ this.minVerticalRotation = minHeight;
+ }
+
+ /**
+ * returns true is smmoth motion is enabled for this chase camera
+ * @return
+ */
+ public boolean isSmoothMotion() {
+ return smoothMotion;
+ }
+
+ /**
+ * Enables smooth motion for this chase camera
+ * @param smoothMotion
+ */
+ public void setSmoothMotion(boolean smoothMotion) {
+ this.smoothMotion = smoothMotion;
+ }
+
+ /**
+ * returns the chasing sensitivity
+ * @return
+ */
+ public float getChasingSensitivity() {
+ return chasingSensitivity;
+ }
+
+ /**
+ *
+ * Sets the chasing sensitivity, the lower the value the slower the camera will follow the target when it moves
+ * default is 5
+ * Only has an effect if smoothMotion is set to true and trailing is enabled
+ * @param chasingSensitivity
+ */
+ public void setChasingSensitivity(float chasingSensitivity) {
+ this.chasingSensitivity = chasingSensitivity;
+ }
+
+ /**
+ * Returns the rotation sensitivity
+ * @return
+ */
+ public float getRotationSensitivity() {
+ return rotationSensitivity;
+ }
+
+ /**
+ * Sets the rotation sensitivity, the lower the value the slower the camera will rotates around the target when draging with the mouse
+ * default is 5, values over 5 should have no effect.
+ * If you want a significant slow down try values below 1.
+ * Only has an effect if smoothMotion is set to true
+ * @param rotationSensitivity
+ */
+ public void setRotationSensitivity(float rotationSensitivity) {
+ this.rotationSensitivity = rotationSensitivity;
+ }
+
+ /**
+ * returns true if the trailing is enabled
+ * @return
+ */
+ public boolean isTrailingEnabled() {
+ return trailingEnabled;
+ }
+
+ /**
+ * Enable the camera trailing : The camera smoothly go in the targets trail when it moves.
+ * Only has an effect if smoothMotion is set to true
+ * @param trailingEnabled
+ */
+ public void setTrailingEnabled(boolean trailingEnabled) {
+ this.trailingEnabled = trailingEnabled;
+ }
+
+ /**
+ *
+ * returns the trailing rotation inertia
+ * @return
+ */
+ public float getTrailingRotationInertia() {
+ return trailingRotationInertia;
+ }
+
+ /**
+ * Sets the trailing rotation inertia : default is 0.1. This prevent the camera to roughtly stop when the target stops moving
+ * before the camera reached the trail position.
+ * Only has an effect if smoothMotion is set to true and trailing is enabled
+ * @param trailingRotationInertia
+ */
+ public void setTrailingRotationInertia(float trailingRotationInertia) {
+ this.trailingRotationInertia = trailingRotationInertia;
+ }
+
+ /**
+ * returns the trailing sensitivity
+ * @return
+ */
+ public float getTrailingSensitivity() {
+ return trailingSensitivity;
+ }
+
+ /**
+ * Only has an effect if smoothMotion is set to true and trailing is enabled
+ * Sets the trailing sensitivity, the lower the value, the slower the camera will go in the target trail when it moves.
+ * default is 0.5;
+ * @param trailingSensitivity
+ */
+ public void setTrailingSensitivity(float trailingSensitivity) {
+ this.trailingSensitivity = trailingSensitivity;
+ }
+
+ /**
+ * returns the zoom sensitivity
+ * @return
+ */
+ public float getZoomSensitivity() {
+ return zoomSensitivity;
+ }
+
+ /**
+ * Sets the zoom sensitivity, the lower the value, the slower the camera will zoom in and out.
+ * default is 5.
+ * @param zoomSensitivity
+ */
+ public void setZoomSensitivity(float zoomSensitivity) {
+ this.zoomSensitivity = zoomSensitivity;
+ }
+
+ /**
+ * Sets the default distance at start of applicaiton
+ * @param defaultDistance
+ */
+ public void setDefaultDistance(float defaultDistance) {
+ distance = defaultDistance;
+ targetDistance = distance;
+ }
+
+ /**
+ * sets the default horizontal rotation of the camera at start of the application
+ * @param angle
+ */
+ public void setDefaultHorizontalRotation(float angle) {
+ rotation = angle;
+ targetRotation = angle;
+ }
+
+ /**
+ * sets the default vertical rotation of the camera at start of the application
+ * @param angle
+ */
+ public void setDefaultVerticalRotation(float angle) {
+ vRotation = angle;
+ targetVRotation = angle;
+ }
+
+ /**
+ * @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;
+ this.canRotate = !dragToRotate;
+ inputManager.setCursorVisible(dragToRotate);
+ }
+
+ /**
+ * return the current distance from the camera to the target
+ * @return
+ */
+ public float getDistanceToTarget() {
+ return distance;
+ }
+
+ /**
+ * returns the current horizontal rotation around the target in radians
+ * @return
+ */
+ public float getHorizontalRotation() {
+ return rotation;
+ }
+
+ /**
+ * returns the current vertical rotation around the target in radians.
+ * @return
+ */
+ public float getVerticalRotation() {
+ return vRotation;
+ }
+
+ /**
+ * returns the offset from the target's position where the camera looks at
+ * @return
+ */
+ public Vector3f getLookAtOffset() {
+ return lookAtOffset;
+ }
+
+ /**
+ * Sets the offset from the target's position where the camera looks at
+ * @param lookAtOffset
+ */
+ public void setLookAtOffset(Vector3f lookAtOffset) {
+ this.lookAtOffset = lookAtOffset;
+ }
+
+ /**
+ * Sets the up vector of the camera used for the lookAt on the target
+ * @param up
+ */
+ public void setUpVector(Vector3f up){
+ initialUpVec=up;
+ }
+
+ /**
+ * Returns the up vector of the camera used for the lookAt on the target
+ * @return
+ */
+ public Vector3f getUpVector(){
+ return initialUpVec;
+ }
+
+ /**
+ * invert the vertical axis movement of the mouse
+ * @param invertYaxis
+ */
+ public void setInvertVerticalAxis(boolean invertYaxis) {
+ this.invertYaxis = invertYaxis;
+ inputManager.deleteMapping(ChaseCamDown);
+ inputManager.deleteMapping(ChaseCamUp);
+ if (!invertYaxis) {
+ inputManager.addMapping(ChaseCamDown, new MouseAxisTrigger(MouseInput.AXIS_Y, true));
+ inputManager.addMapping(ChaseCamUp, new MouseAxisTrigger(MouseInput.AXIS_Y, false));
+ } else {
+ inputManager.addMapping(ChaseCamDown, new MouseAxisTrigger(MouseInput.AXIS_Y, false));
+ inputManager.addMapping(ChaseCamUp, new MouseAxisTrigger(MouseInput.AXIS_Y, true));
+ }
+ inputManager.addListener(this, ChaseCamDown, ChaseCamUp);
+ }
+
+ /**
+ * invert the Horizontal axis movement of the mouse
+ * @param invertXaxis
+ */
+ public void setInvertHorizontalAxis(boolean invertXaxis) {
+ this.invertXaxis = invertXaxis;
+ inputManager.deleteMapping(ChaseCamMoveLeft);
+ inputManager.deleteMapping(ChaseCamMoveRight);
+ if(!invertXaxis){
+ inputManager.addMapping(ChaseCamMoveLeft, new MouseAxisTrigger(MouseInput.AXIS_X, true));
+ inputManager.addMapping(ChaseCamMoveRight, new MouseAxisTrigger(MouseInput.AXIS_X, false));
+ }else{
+ inputManager.addMapping(ChaseCamMoveLeft, new MouseAxisTrigger(MouseInput.AXIS_X, false));
+ inputManager.addMapping(ChaseCamMoveRight, new MouseAxisTrigger(MouseInput.AXIS_X, true));
+ }
+ inputManager.addListener(this, ChaseCamMoveLeft, ChaseCamMoveRight);
+ }
+}
diff --git a/engine/src/core/com/jme3/input/FlyByCamera.java b/engine/src/core/com/jme3/input/FlyByCamera.java
new file mode 100644
index 0000000..7b439ef
--- /dev/null
+++ b/engine/src/core/com/jme3/input/FlyByCamera.java
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2009-2012 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.input;
+
+import com.jme3.collision.MotionAllowedListener;
+import com.jme3.input.controls.*;
+import com.jme3.math.FastMath;
+import com.jme3.math.Matrix3f;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.Camera;
+
+/**
+ * A first person view camera controller.
+ * After creation, you must register the camera controller with the
+ * dispatcher using #registerWithDispatcher().
+ *
+ * Controls:
+ * - Move the mouse to rotate the camera
+ * - Mouse wheel for zooming in or out
+ * - WASD keys for moving forward/backward and strafing
+ * - QZ keys raise or lower the camera
+ */
+public class FlyByCamera implements AnalogListener, ActionListener {
+
+ private static String[] mappings = new String[]{
+ "FLYCAM_Left",
+ "FLYCAM_Right",
+ "FLYCAM_Up",
+ "FLYCAM_Down",
+
+ "FLYCAM_StrafeLeft",
+ "FLYCAM_StrafeRight",
+ "FLYCAM_Forward",
+ "FLYCAM_Backward",
+
+ "FLYCAM_ZoomIn",
+ "FLYCAM_ZoomOut",
+ "FLYCAM_RotateDrag",
+
+ "FLYCAM_Rise",
+ "FLYCAM_Lower"
+ };
+
+ protected Camera cam;
+ protected Vector3f initialUpVec;
+ protected float rotationSpeed = 1f;
+ protected float moveSpeed = 3f;
+ protected MotionAllowedListener motionAllowed = null;
+ protected boolean enabled = true;
+ protected boolean dragToRotate = false;
+ protected boolean canRotate = false;
+ protected InputManager inputManager;
+
+ /**
+ * Creates a new FlyByCamera to control the given Camera object.
+ * @param cam
+ */
+ public FlyByCamera(Camera cam){
+ this.cam = cam;
+ initialUpVec = cam.getUp().clone();
+ }
+
+ /**
+ * Sets the up vector that should be used for the camera.
+ * @param upVec
+ */
+ public void setUpVector(Vector3f upVec) {
+ initialUpVec.set(upVec);
+ }
+
+ public void setMotionAllowedListener(MotionAllowedListener listener){
+ this.motionAllowed = listener;
+ }
+
+ /**
+ * Sets the move speed. The speed is given in world units per second.
+ * @param moveSpeed
+ */
+ public void setMoveSpeed(float moveSpeed){
+ this.moveSpeed = moveSpeed;
+ }
+
+ /**
+ * Sets the rotation speed.
+ * @param rotationSpeed
+ */
+ public void setRotationSpeed(float rotationSpeed){
+ this.rotationSpeed = rotationSpeed;
+ }
+
+ /**
+ * @param enable If false, the camera will ignore input.
+ */
+ public void setEnabled(boolean enable){
+ if (enabled && !enable){
+ if (inputManager!= null && (!dragToRotate || (dragToRotate && canRotate))){
+ inputManager.setCursorVisible(true);
+ }
+ }
+ enabled = enable;
+ }
+
+ /**
+ * @return If enabled
+ * @see FlyByCamera#setEnabled(boolean)
+ */
+ public boolean isEnabled(){
+ return enabled;
+ }
+
+ /**
+ * @return If drag to rotate feature is enabled.
+ *
+ * @see FlyByCamera#setDragToRotate(boolean)
+ */
+ public boolean isDragToRotate() {
+ return dragToRotate;
+ }
+
+ /**
+ * Set if drag to rotate mode is enabled.
+ *
+ * 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.
+ *
+ * @param dragToRotate True if drag to rotate mode is enabled.
+ */
+ public void setDragToRotate(boolean dragToRotate) {
+ this.dragToRotate = dragToRotate;
+ if (inputManager != null) {
+ inputManager.setCursorVisible(dragToRotate);
+ }
+ }
+
+ /**
+ * Registers the FlyByCamera to receive input events from the provided
+ * Dispatcher.
+ * @param inputManager
+ */
+ public void registerWithInput(InputManager inputManager){
+ this.inputManager = inputManager;
+
+ // both mouse and button - rotation of cam
+ inputManager.addMapping("FLYCAM_Left", new MouseAxisTrigger(MouseInput.AXIS_X, true),
+ new KeyTrigger(KeyInput.KEY_LEFT));
+
+ inputManager.addMapping("FLYCAM_Right", new MouseAxisTrigger(MouseInput.AXIS_X, false),
+ new KeyTrigger(KeyInput.KEY_RIGHT));
+
+ inputManager.addMapping("FLYCAM_Up", new MouseAxisTrigger(MouseInput.AXIS_Y, false),
+ new KeyTrigger(KeyInput.KEY_UP));
+
+ inputManager.addMapping("FLYCAM_Down", new MouseAxisTrigger(MouseInput.AXIS_Y, true),
+ new KeyTrigger(KeyInput.KEY_DOWN));
+
+ // mouse only - zoom in/out with wheel, and rotate drag
+ inputManager.addMapping("FLYCAM_ZoomIn", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false));
+ inputManager.addMapping("FLYCAM_ZoomOut", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true));
+ inputManager.addMapping("FLYCAM_RotateDrag", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
+
+ // keyboard only WASD for movement and WZ for rise/lower height
+ inputManager.addMapping("FLYCAM_StrafeLeft", new KeyTrigger(KeyInput.KEY_A));
+ inputManager.addMapping("FLYCAM_StrafeRight", new KeyTrigger(KeyInput.KEY_D));
+ inputManager.addMapping("FLYCAM_Forward", new KeyTrigger(KeyInput.KEY_W));
+ inputManager.addMapping("FLYCAM_Backward", new KeyTrigger(KeyInput.KEY_S));
+ inputManager.addMapping("FLYCAM_Rise", new KeyTrigger(KeyInput.KEY_Q));
+ inputManager.addMapping("FLYCAM_Lower", new KeyTrigger(KeyInput.KEY_Z));
+
+ inputManager.addListener(this, mappings);
+ inputManager.setCursorVisible(dragToRotate || !isEnabled());
+
+ Joystick[] joysticks = inputManager.getJoysticks();
+ if (joysticks != null && joysticks.length > 0){
+ Joystick joystick = joysticks[0];
+ joystick.assignAxis("FLYCAM_StrafeRight", "FLYCAM_StrafeLeft", JoyInput.AXIS_POV_X);
+ joystick.assignAxis("FLYCAM_Forward", "FLYCAM_Backward", JoyInput.AXIS_POV_Y);
+ joystick.assignAxis("FLYCAM_Right", "FLYCAM_Left", joystick.getXAxisIndex());
+ joystick.assignAxis("FLYCAM_Down", "FLYCAM_Up", joystick.getYAxisIndex());
+ }
+ }
+
+ /**
+ * Registers the FlyByCamera to receive input events from the provided
+ * Dispatcher.
+ * @param inputManager
+ */
+ public void unregisterInput(){
+
+ if (inputManager == null) {
+ return;
+ }
+
+ for (String s : mappings) {
+ if (inputManager.hasMapping(s)) {
+ inputManager.deleteMapping( s );
+ }
+ }
+
+ inputManager.removeListener(this);
+ inputManager.setCursorVisible(!dragToRotate);
+
+ Joystick[] joysticks = inputManager.getJoysticks();
+ if (joysticks != null && joysticks.length > 0){
+ Joystick joystick = joysticks[0];
+
+ // No way to unassing axis
+ }
+ }
+
+ protected void rotateCamera(float value, Vector3f axis){
+ if (dragToRotate){
+ if (canRotate){
+// value = -value;
+ }else{
+ return;
+ }
+ }
+
+ 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.normalize();
+
+ cam.setAxes(q);
+ }
+
+ protected void zoomCamera(float value){
+ // derive fovY value
+ float h = cam.getFrustumTop();
+ float w = cam.getFrustumRight();
+ float aspect = w / h;
+
+ float near = cam.getFrustumNear();
+
+ float fovY = FastMath.atan(h / near)
+ / (FastMath.DEG_TO_RAD * .5f);
+ fovY += value * 0.1f;
+
+ h = FastMath.tan( fovY * FastMath.DEG_TO_RAD * .5f) * near;
+ w = h * aspect;
+
+ cam.setFrustumTop(h);
+ cam.setFrustumBottom(-h);
+ cam.setFrustumLeft(-w);
+ cam.setFrustumRight(w);
+ }
+
+ protected void riseCamera(float value){
+ Vector3f vel = new Vector3f(0, value * moveSpeed, 0);
+ Vector3f pos = cam.getLocation().clone();
+
+ if (motionAllowed != null)
+ motionAllowed.checkMotionAllowed(pos, vel);
+ else
+ pos.addLocal(vel);
+
+ cam.setLocation(pos);
+ }
+
+ protected void moveCamera(float value, boolean sideways){
+ Vector3f vel = new Vector3f();
+ Vector3f pos = cam.getLocation().clone();
+
+ if (sideways){
+ cam.getLeft(vel);
+ }else{
+ cam.getDirection(vel);
+ }
+ vel.multLocal(value * moveSpeed);
+
+ if (motionAllowed != null)
+ motionAllowed.checkMotionAllowed(pos, vel);
+ else
+ pos.addLocal(vel);
+
+ cam.setLocation(pos);
+ }
+
+ public void onAnalog(String name, float value, float tpf) {
+ if (!enabled)
+ return;
+
+ if (name.equals("FLYCAM_Left")){
+ rotateCamera(value, initialUpVec);
+ }else if (name.equals("FLYCAM_Right")){
+ rotateCamera(-value, initialUpVec);
+ }else if (name.equals("FLYCAM_Up")){
+ rotateCamera(-value, cam.getLeft());
+ }else if (name.equals("FLYCAM_Down")){
+ rotateCamera(value, cam.getLeft());
+ }else if (name.equals("FLYCAM_Forward")){
+ moveCamera(value, false);
+ }else if (name.equals("FLYCAM_Backward")){
+ moveCamera(-value, false);
+ }else if (name.equals("FLYCAM_StrafeLeft")){
+ moveCamera(value, true);
+ }else if (name.equals("FLYCAM_StrafeRight")){
+ moveCamera(-value, true);
+ }else if (name.equals("FLYCAM_Rise")){
+ riseCamera(value);
+ }else if (name.equals("FLYCAM_Lower")){
+ riseCamera(-value);
+ }else if (name.equals("FLYCAM_ZoomIn")){
+ zoomCamera(value);
+ }else if (name.equals("FLYCAM_ZoomOut")){
+ zoomCamera(-value);
+ }
+ }
+
+ public void onAction(String name, boolean value, float tpf) {
+ if (!enabled)
+ return;
+
+ if (name.equals("FLYCAM_RotateDrag") && dragToRotate){
+ canRotate = value;
+ inputManager.setCursorVisible(!value);
+ }
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/Input.java b/engine/src/core/com/jme3/input/Input.java
new file mode 100644
index 0000000..1cece68
--- /dev/null
+++ b/engine/src/core/com/jme3/input/Input.java
@@ -0,0 +1,82 @@
+/*
+ * 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.input;
+
+/**
+ * Abstract interface for an input device.
+ *
+ * @see MouseInput
+ * @see KeyInput
+ * @see JoyInput
+ */
+public interface Input {
+
+ /**
+ * Initializes the native side to listen into events from the device.
+ */
+ public void initialize();
+
+ /**
+ * Queries the device for input. All events should be sent to the
+ * RawInputListener set with setInputListener.
+ *
+ * @see #setInputListener(com.jme3.input.RawInputListener)
+ */
+ public void update();
+
+ /**
+ * Ceases listening to events from the device.
+ */
+ public void destroy();
+
+ /**
+ * @return True if the device has been initialized and not destroyed.
+ * @see #initialize()
+ * @see #destroy()
+ */
+ public boolean isInitialized();
+
+ /**
+ * Sets the input listener to receive events from this device. The
+ * appropriate events should be dispatched through the callbacks
+ * in RawInputListener.
+ * @param listener
+ */
+ public void setInputListener(RawInputListener listener);
+
+ /**
+ * @return The current absolute time as nanoseconds. This time is expected
+ * to be relative to the time given in InputEvents time property.
+ */
+ public long getInputTimeNanos();
+}
diff --git a/engine/src/core/com/jme3/input/InputManager.java b/engine/src/core/com/jme3/input/InputManager.java
new file mode 100644
index 0000000..23f2988
--- /dev/null
+++ b/engine/src/core/com/jme3/input/InputManager.java
@@ -0,0 +1,881 @@
+/*
+ * Copyright (c) 2009-2012 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.input;
+
+import com.jme3.app.Application;
+import com.jme3.input.controls.*;
+import com.jme3.input.event.*;
+import com.jme3.math.FastMath;
+import com.jme3.math.Vector2f;
+import com.jme3.util.IntMap;
+import com.jme3.util.IntMap.Entry;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * The <code>InputManager</code> is responsible for converting input events
+ * received from the Key, Mouse and Joy Input implementations into an
+ * abstract, input device independent representation that user code can use.
+ * <p>
+ * By default an <code>InputManager</code> is included with every Application instance for use
+ * in user code to query input, unless the Application is created as headless
+ * or with input explicitly disabled.
+ * <p>
+ * The input manager has two concepts, a {@link Trigger} and a mapping.
+ * A trigger represents a specific input trigger, such as a key button,
+ * or a mouse axis. A mapping represents a link onto one or several triggers,
+ * when the appropriate trigger is activated (e.g. a key is pressed), the
+ * mapping will be invoked. Any listeners registered to receive an event
+ * from the mapping will have an event raised.
+ * <p>
+ * There are two types of events that {@link InputListener input listeners}
+ * can receive, one is {@link ActionListener#onAction(java.lang.String, boolean, float) action}
+ * events and another is {@link AnalogListener#onAnalog(java.lang.String, float, float) analog}
+ * events.
+ * <p>
+ * <code>onAction</code> events are raised when the specific input
+ * activates or deactivates. For a digital input such as key press, the <code>onAction()</code>
+ * event will be raised with the <code>isPressed</code> argument equal to true,
+ * when the key is released, <code>onAction</code> is called again but this time
+ * with the <code>isPressed</code> argument set to false.
+ * For analog inputs, the <code>onAction</code> method will be called any time
+ * the input is non-zero, however an exception to this is for joystick axis inputs,
+ * which are only called when the input is above the {@link InputManager#setAxisDeadZone(float) dead zone}.
+ * <p>
+ * <code>onAnalog</code> events are raised every frame while the input is activated.
+ * For digital inputs, every frame that the input is active will cause the
+ * <code>onAnalog</code> method to be called, the argument <code>value</code>
+ * argument will equal to the frame's time per frame (TPF) value but only
+ * for digital inputs. For analog inputs however, the <code>value</code> argument
+ * will equal the actual analog value.
+ */
+public class InputManager implements RawInputListener {
+
+ private static final Logger logger = Logger.getLogger(InputManager.class.getName());
+ private final KeyInput keys;
+ private final MouseInput mouse;
+ private final JoyInput joystick;
+ private final TouchInput touch;
+ private float frameTPF;
+ private long lastLastUpdateTime = 0;
+ private long lastUpdateTime = 0;
+ private long frameDelta = 0;
+ private long firstTime = 0;
+ private boolean eventsPermitted = false;
+ private boolean mouseVisible = true;
+ private boolean safeMode = false;
+ private float axisDeadZone = 0.05f;
+ private Vector2f cursorPos = new Vector2f();
+ private Joystick[] joysticks;
+ private final IntMap<ArrayList<Mapping>> bindings = new IntMap<ArrayList<Mapping>>();
+ private final HashMap<String, Mapping> mappings = new HashMap<String, Mapping>();
+ private final IntMap<Long> pressedButtons = new IntMap<Long>();
+ private final IntMap<Float> axisValues = new IntMap<Float>();
+ private ArrayList<RawInputListener> rawListeners = new ArrayList<RawInputListener>();
+ private RawInputListener[] rawListenerArray = null;
+ private ArrayList<InputEvent> inputQueue = new ArrayList<InputEvent>();
+
+ private static class Mapping {
+
+ private final String name;
+ private final ArrayList<Integer> triggers = new ArrayList<Integer>();
+ private final ArrayList<InputListener> listeners = new ArrayList<InputListener>();
+
+ public Mapping(String name) {
+ this.name = name;
+ }
+ }
+
+ /**
+ * Initializes the InputManager.
+ *
+ * <p>This should only be called internally in {@link Application}.
+ *
+ * @param mouse
+ * @param keys
+ * @param joystick
+ * @param touch
+ * @throws IllegalArgumentException If either mouseInput or keyInput are null.
+ */
+ public InputManager(MouseInput mouse, KeyInput keys, JoyInput joystick, TouchInput touch) {
+ if (keys == null || mouse == null) {
+ throw new NullPointerException("Mouse or keyboard cannot be null");
+ }
+
+ this.keys = keys;
+ this.mouse = mouse;
+ this.joystick = joystick;
+ this.touch = touch;
+
+ keys.setInputListener(this);
+ mouse.setInputListener(this);
+ if (joystick != null) {
+ joystick.setInputListener(this);
+ joysticks = joystick.loadJoysticks(this);
+ }
+ if (touch != null) {
+ touch.setInputListener(this);
+ }
+
+ firstTime = keys.getInputTimeNanos();
+ }
+
+ private void invokeActions(int hash, boolean pressed) {
+ ArrayList<Mapping> maps = bindings.get(hash);
+ if (maps == null) {
+ return;
+ }
+
+ int size = maps.size();
+ for (int i = size - 1; i >= 0; i--) {
+ Mapping mapping = maps.get(i);
+ ArrayList<InputListener> listeners = mapping.listeners;
+ int listenerSize = listeners.size();
+ for (int j = listenerSize - 1; j >= 0; j--) {
+ InputListener listener = listeners.get(j);
+ if (listener instanceof ActionListener) {
+ ((ActionListener) listener).onAction(mapping.name, pressed, frameTPF);
+ }
+ }
+ }
+ }
+
+ private float computeAnalogValue(long timeDelta) {
+ if (safeMode || frameDelta == 0) {
+ return 1f;
+ } else {
+ return FastMath.clamp((float) timeDelta / (float) frameDelta, 0, 1);
+ }
+ }
+
+ private void invokeTimedActions(int hash, long time, boolean pressed) {
+ if (!bindings.containsKey(hash)) {
+ return;
+ }
+
+ if (pressed) {
+ pressedButtons.put(hash, time);
+ } else {
+ Long pressTimeObj = pressedButtons.remove(hash);
+ if (pressTimeObj == null) {
+ return; // under certain circumstances it can be null, ignore
+ } // the event then.
+
+ long pressTime = pressTimeObj;
+ long lastUpdate = lastLastUpdateTime;
+ long releaseTime = time;
+ long timeDelta = releaseTime - Math.max(pressTime, lastUpdate);
+
+ if (timeDelta > 0) {
+ invokeAnalogs(hash, computeAnalogValue(timeDelta), false);
+ }
+ }
+ }
+
+ private void invokeUpdateActions() {
+ for (Entry<Long> pressedButton : pressedButtons) {
+ int hash = pressedButton.getKey();
+
+ long pressTime = pressedButton.getValue();
+ long timeDelta = lastUpdateTime - Math.max(lastLastUpdateTime, pressTime);
+
+ if (timeDelta > 0) {
+ invokeAnalogs(hash, computeAnalogValue(timeDelta), false);
+ }
+ }
+
+ for (Entry<Float> axisValue : axisValues) {
+ int hash = axisValue.getKey();
+ float value = axisValue.getValue();
+ invokeAnalogs(hash, value * frameTPF, true);
+ }
+ }
+
+ private void invokeAnalogs(int hash, float value, boolean isAxis) {
+ ArrayList<Mapping> maps = bindings.get(hash);
+ if (maps == null) {
+ return;
+ }
+
+ if (!isAxis) {
+ value *= frameTPF;
+ }
+
+ int size = maps.size();
+ for (int i = size - 1; i >= 0; i--) {
+ Mapping mapping = maps.get(i);
+ ArrayList<InputListener> listeners = mapping.listeners;
+ int listenerSize = listeners.size();
+ for (int j = listenerSize - 1; j >= 0; j--) {
+ InputListener listener = listeners.get(j);
+ if (listener instanceof AnalogListener) {
+ // NOTE: multiply by TPF for any button bindings
+ ((AnalogListener) listener).onAnalog(mapping.name, value, frameTPF);
+ }
+ }
+ }
+ }
+
+ private void invokeAnalogsAndActions(int hash, float value, boolean applyTpf) {
+ if (value < axisDeadZone) {
+ invokeAnalogs(hash, value, !applyTpf);
+ return;
+ }
+
+ ArrayList<Mapping> maps = bindings.get(hash);
+ if (maps == null) {
+ return;
+ }
+
+ boolean valueChanged = !axisValues.containsKey(hash);
+ if (applyTpf) {
+ value *= frameTPF;
+ }
+
+ int size = maps.size();
+ for (int i = size - 1; i >= 0; i--) {
+ Mapping mapping = maps.get(i);
+ ArrayList<InputListener> listeners = mapping.listeners;
+ int listenerSize = listeners.size();
+ for (int j = listenerSize - 1; j >= 0; j--) {
+ InputListener listener = listeners.get(j);
+
+ if (listener instanceof ActionListener && valueChanged) {
+ ((ActionListener) listener).onAction(mapping.name, true, frameTPF);
+ }
+
+ if (listener instanceof AnalogListener) {
+ ((AnalogListener) listener).onAnalog(mapping.name, value, frameTPF);
+ }
+
+ }
+ }
+ }
+
+ /**
+ * Callback from RawInputListener. Do not use.
+ */
+ public void beginInput() {
+ }
+
+ /**
+ * Callback from RawInputListener. Do not use.
+ */
+ public void endInput() {
+ }
+
+ private void onJoyAxisEventQueued(JoyAxisEvent evt) {
+// for (int i = 0; i < rawListeners.size(); i++){
+// rawListeners.get(i).onJoyAxisEvent(evt);
+// }
+
+ int joyId = evt.getJoyIndex();
+ int axis = evt.getAxisIndex();
+ float value = evt.getValue();
+ if (value < axisDeadZone && value > -axisDeadZone) {
+ int hash1 = JoyAxisTrigger.joyAxisHash(joyId, axis, true);
+ int hash2 = JoyAxisTrigger.joyAxisHash(joyId, axis, false);
+
+ Float val1 = axisValues.get(hash1);
+ Float val2 = axisValues.get(hash2);
+
+ if (val1 != null && val1.floatValue() > axisDeadZone) {
+ invokeActions(hash1, false);
+ }
+ if (val2 != null && val2.floatValue() > axisDeadZone) {
+ invokeActions(hash2, false);
+ }
+
+ axisValues.remove(hash1);
+ axisValues.remove(hash2);
+
+ } else if (value < 0) {
+ int hash = JoyAxisTrigger.joyAxisHash(joyId, axis, true);
+ int otherHash = JoyAxisTrigger.joyAxisHash(joyId, axis, false);
+ invokeAnalogsAndActions(hash, -value, true);
+ axisValues.put(hash, -value);
+ axisValues.remove(otherHash);
+ } else {
+ int hash = JoyAxisTrigger.joyAxisHash(joyId, axis, false);
+ int otherHash = JoyAxisTrigger.joyAxisHash(joyId, axis, true);
+ invokeAnalogsAndActions(hash, value, true);
+ axisValues.put(hash, value);
+ axisValues.remove(otherHash);
+ }
+ }
+
+ /**
+ * Callback from RawInputListener. Do not use.
+ */
+ public void onJoyAxisEvent(JoyAxisEvent evt) {
+ if (!eventsPermitted) {
+ throw new UnsupportedOperationException("JoyInput has raised an event at an illegal time.");
+ }
+
+ inputQueue.add(evt);
+ }
+
+ private void onJoyButtonEventQueued(JoyButtonEvent evt) {
+// for (int i = 0; i < rawListeners.size(); i++){
+// rawListeners.get(i).onJoyButtonEvent(evt);
+// }
+
+ int hash = JoyButtonTrigger.joyButtonHash(evt.getJoyIndex(), evt.getButtonIndex());
+ invokeActions(hash, evt.isPressed());
+ invokeTimedActions(hash, evt.getTime(), evt.isPressed());
+ }
+
+ /**
+ * Callback from RawInputListener. Do not use.
+ */
+ public void onJoyButtonEvent(JoyButtonEvent evt) {
+ if (!eventsPermitted) {
+ throw new UnsupportedOperationException("JoyInput has raised an event at an illegal time.");
+ }
+
+ inputQueue.add(evt);
+ }
+
+ private void onMouseMotionEventQueued(MouseMotionEvent evt) {
+// for (int i = 0; i < rawListeners.size(); i++){
+// rawListeners.get(i).onMouseMotionEvent(evt);
+// }
+
+ if (evt.getDX() != 0) {
+ float val = Math.abs(evt.getDX()) / 1024f;
+ invokeAnalogsAndActions(MouseAxisTrigger.mouseAxisHash(MouseInput.AXIS_X, evt.getDX() < 0), val, false);
+ }
+ if (evt.getDY() != 0) {
+ float val = Math.abs(evt.getDY()) / 1024f;
+ invokeAnalogsAndActions(MouseAxisTrigger.mouseAxisHash(MouseInput.AXIS_Y, evt.getDY() < 0), val, false);
+ }
+ if (evt.getDeltaWheel() != 0) {
+ float val = Math.abs(evt.getDeltaWheel()) / 100f;
+ invokeAnalogsAndActions(MouseAxisTrigger.mouseAxisHash(MouseInput.AXIS_WHEEL, evt.getDeltaWheel() < 0), val, false);
+ }
+ }
+
+ /**
+ * Callback from RawInputListener. Do not use.
+ */
+ public void onMouseMotionEvent(MouseMotionEvent evt) {
+ if (!eventsPermitted) {
+ throw new UnsupportedOperationException("MouseInput has raised an event at an illegal time.");
+ }
+
+ cursorPos.set(evt.getX(), evt.getY());
+ inputQueue.add(evt);
+ }
+
+ private void onMouseButtonEventQueued(MouseButtonEvent evt) {
+ int hash = MouseButtonTrigger.mouseButtonHash(evt.getButtonIndex());
+ invokeActions(hash, evt.isPressed());
+ invokeTimedActions(hash, evt.getTime(), evt.isPressed());
+ }
+
+ /**
+ * Callback from RawInputListener. Do not use.
+ */
+ public void onMouseButtonEvent(MouseButtonEvent evt) {
+ if (!eventsPermitted) {
+ throw new UnsupportedOperationException("MouseInput has raised an event at an illegal time.");
+ }
+ //updating cursor pos on click, so that non android touch events can properly update cursor position.
+ cursorPos.set(evt.getX(), evt.getY());
+ inputQueue.add(evt);
+ }
+
+ private void onKeyEventQueued(KeyInputEvent evt) {
+ if (evt.isRepeating()) {
+ return; // repeat events not used for bindings
+ }
+
+ int hash = KeyTrigger.keyHash(evt.getKeyCode());
+ invokeActions(hash, evt.isPressed());
+ invokeTimedActions(hash, evt.getTime(), evt.isPressed());
+ }
+
+ /**
+ * Callback from RawInputListener. Do not use.
+ */
+ public void onKeyEvent(KeyInputEvent evt) {
+ if (!eventsPermitted) {
+ throw new UnsupportedOperationException("KeyInput has raised an event at an illegal time.");
+ }
+
+ inputQueue.add(evt);
+ }
+
+ /**
+ * Set the deadzone for joystick axes.
+ *
+ * <p>{@link ActionListener#onAction(java.lang.String, boolean, float) }
+ * events will only be raised if the joystick axis value is greater than
+ * the <code>deadZone</code>.
+ *
+ * @param deadZone the deadzone for joystick axes.
+ */
+ public void setAxisDeadZone(float deadZone) {
+ this.axisDeadZone = deadZone;
+ }
+
+ /**
+ * Returns the deadzone for joystick axes.
+ *
+ * @return the deadzone for joystick axes.
+ */
+ public float getAxisDeadZone() {
+ return axisDeadZone;
+ }
+
+ /**
+ * Adds a new listener to receive events on the given mappings.
+ *
+ * <p>The given InputListener will be registered to receive events
+ * on the specified mapping names. When a mapping raises an event, the
+ * listener will have its appropriate method invoked, either
+ * {@link ActionListener#onAction(java.lang.String, boolean, float) }
+ * or {@link AnalogListener#onAnalog(java.lang.String, float, float) }
+ * depending on which interface the <code>listener</code> implements.
+ * If the listener implements both interfaces, then it will receive the
+ * appropriate event for each method.
+ *
+ * @param listener The listener to register to receive input events.
+ * @param mappingNames The mapping names which the listener will receive
+ * events from.
+ *
+ * @see InputManager#removeListener(com.jme3.input.controls.InputListener)
+ */
+ public void addListener(InputListener listener, String... mappingNames) {
+ for (String mappingName : mappingNames) {
+ Mapping mapping = mappings.get(mappingName);
+ if (mapping == null) {
+ mapping = new Mapping(mappingName);
+ mappings.put(mappingName, mapping);
+ }
+ if (!mapping.listeners.contains(listener)) {
+ mapping.listeners.add(listener);
+ }
+ }
+ }
+
+ /**
+ * Removes a listener from receiving events.
+ *
+ * <p>This will unregister the listener from any mappings that it
+ * was previously registered with via
+ * {@link InputManager#addListener(com.jme3.input.controls.InputListener, java.lang.String[]) }.
+ *
+ * @param listener The listener to unregister.
+ *
+ * @see InputManager#addListener(com.jme3.input.controls.InputListener, java.lang.String[])
+ */
+ public void removeListener(InputListener listener) {
+ for (Mapping mapping : mappings.values()) {
+ mapping.listeners.remove(listener);
+ }
+ }
+
+ /**
+ * Create a new mapping to the given triggers.
+ *
+ * <p>
+ * The given mapping will be assigned to the given triggers, when
+ * any of the triggers given raise an event, the listeners
+ * registered to the mappings will receive appropriate events.
+ *
+ * @param mappingName The mapping name to assign.
+ * @param triggers The triggers to which the mapping is to be registered.
+ *
+ * @see InputManager#deleteMapping(java.lang.String)
+ */
+ public void addMapping(String mappingName, Trigger... triggers) {
+ Mapping mapping = mappings.get(mappingName);
+ if (mapping == null) {
+ mapping = new Mapping(mappingName);
+ mappings.put(mappingName, mapping);
+ }
+
+ for (Trigger trigger : triggers) {
+ int hash = trigger.triggerHashCode();
+ ArrayList<Mapping> names = bindings.get(hash);
+ if (names == null) {
+ names = new ArrayList<Mapping>();
+ bindings.put(hash, names);
+ }
+ if (!names.contains(mapping)) {
+ names.add(mapping);
+ mapping.triggers.add(hash);
+ } else {
+ logger.log(Level.WARNING, "Attempted to add mapping \"{0}\" twice to trigger.", mappingName);
+ }
+ }
+ }
+
+ /**
+ * Returns true if this InputManager has a mapping registered
+ * for the given mappingName.
+ *
+ * @param mappingName The mapping name to check.
+ *
+ * @see InputManager#addMapping(java.lang.String, com.jme3.input.controls.Trigger[])
+ * @see InputManager#deleteMapping(java.lang.String)
+ */
+ public boolean hasMapping(String mappingName) {
+ return mappings.containsKey(mappingName);
+ }
+
+ /**
+ * Deletes a mapping from receiving trigger events.
+ *
+ * <p>
+ * The given mapping will no longer be assigned to receive trigger
+ * events.
+ *
+ * @param mappingName The mapping name to unregister.
+ *
+ * @see InputManager#addMapping(java.lang.String, com.jme3.input.controls.Trigger[])
+ */
+ public void deleteMapping(String mappingName) {
+ Mapping mapping = mappings.remove(mappingName);
+ if (mapping == null) {
+ throw new IllegalArgumentException("Cannot find mapping: " + mappingName);
+ }
+
+ ArrayList<Integer> triggers = mapping.triggers;
+ for (int i = triggers.size() - 1; i >= 0; i--) {
+ int hash = triggers.get(i);
+ ArrayList<Mapping> maps = bindings.get(hash);
+ maps.remove(mapping);
+ }
+ }
+
+ /**
+ * Deletes a specific trigger registered to a mapping.
+ *
+ * <p>
+ * The given mapping will no longer receive events raised by the
+ * trigger.
+ *
+ * @param mappingName The mapping name to cease receiving events from the
+ * trigger.
+ * @param trigger The trigger to no longer invoke events on the mapping.
+ */
+ public void deleteTrigger(String mappingName, Trigger trigger) {
+ Mapping mapping = mappings.get(mappingName);
+ if (mapping == null) {
+ throw new IllegalArgumentException("Cannot find mapping: " + mappingName);
+ }
+
+ ArrayList<Mapping> maps = bindings.get(trigger.triggerHashCode());
+ maps.remove(mapping);
+
+ }
+
+ /**
+ * Clears all the input mappings from this InputManager.
+ * Consequently, also clears all of the
+ * InputListeners as well.
+ */
+ public void clearMappings() {
+ mappings.clear();
+ bindings.clear();
+ reset();
+ }
+
+ /**
+ * Do not use.
+ * Called to reset pressed keys or buttons when focus is restored.
+ */
+ public void reset() {
+ pressedButtons.clear();
+ axisValues.clear();
+ }
+
+ /**
+ * Returns whether the mouse cursor is visible or not.
+ *
+ * <p>By default the cursor is visible.
+ *
+ * @return whether the mouse cursor is visible or not.
+ *
+ * @see InputManager#setCursorVisible(boolean)
+ */
+ public boolean isCursorVisible() {
+ return mouseVisible;
+ }
+
+ /**
+ * Set whether the mouse cursor should be visible or not.
+ *
+ * @param visible whether the mouse cursor should be visible or not.
+ */
+ public void setCursorVisible(boolean visible) {
+ if (mouseVisible != visible) {
+ mouseVisible = visible;
+ mouse.setCursorVisible(mouseVisible);
+ }
+ }
+
+ /**
+ * Returns the current cursor position. The position is relative to the
+ * bottom-left of the screen and is in pixels.
+ *
+ * @return the current cursor position
+ */
+ public Vector2f getCursorPosition() {
+ return cursorPos;
+ }
+
+ /**
+ * Returns an array of all joysticks installed on the system.
+ *
+ * @return an array of all joysticks installed on the system.
+ */
+ public Joystick[] getJoysticks() {
+ return joysticks;
+ }
+
+ /**
+ * Adds a {@link RawInputListener} to receive raw input events.
+ *
+ * <p>
+ * Any raw input listeners registered to this <code>InputManager</code>
+ * will receive raw input events first, before they get handled
+ * by the <code>InputManager</code> itself. The listeners are
+ * each processed in the order they were added, e.g. FIFO.
+ * <p>
+ * If a raw input listener has handled the event and does not wish
+ * other listeners down the list to process the event, it may set the
+ * {@link InputEvent#setConsumed() consumed flag} to indicate the
+ * event was consumed and shouldn't be processed any further.
+ * The listener may do this either at each of the event callbacks
+ * or at the {@link RawInputListener#endInput() } method.
+ *
+ * @param listener A listener to receive raw input events.
+ *
+ * @see RawInputListener
+ */
+ public void addRawInputListener(RawInputListener listener) {
+ rawListeners.add(listener);
+ rawListenerArray = null;
+ }
+
+ /**
+ * Removes a {@link RawInputListener} so that it no longer
+ * receives raw input events.
+ *
+ * @param listener The listener to cease receiving raw input events.
+ *
+ * @see InputManager#addRawInputListener(com.jme3.input.RawInputListener)
+ */
+ public void removeRawInputListener(RawInputListener listener) {
+ rawListeners.remove(listener);
+ rawListenerArray = null;
+ }
+
+ /**
+ * Clears all {@link RawInputListener}s.
+ *
+ * @see InputManager#addRawInputListener(com.jme3.input.RawInputListener)
+ */
+ public void clearRawInputListeners() {
+ rawListeners.clear();
+ rawListenerArray = null;
+ }
+
+ private RawInputListener[] getRawListenerArray() {
+ if (rawListenerArray == null)
+ rawListenerArray = rawListeners.toArray(new RawInputListener[rawListeners.size()]);
+ return rawListenerArray;
+ }
+
+ /**
+ * Enable simulation of mouse events. Used for touchscreen input only.
+ *
+ * @param value True to enable simulation of mouse events
+ */
+ public void setSimulateMouse(boolean value) {
+ if (touch != null) {
+ touch.setSimulateMouse(value);
+ }
+ }
+
+ /**
+ * Enable simulation of keyboard events. Used for touchscreen input only.
+ *
+ * @param value True to enable simulation of keyboard events
+ */
+ public void setSimulateKeyboard(boolean value) {
+ if (touch != null) {
+ touch.setSimulateKeyboard(value);
+ }
+ }
+
+ private void processQueue() {
+ int queueSize = inputQueue.size();
+ RawInputListener[] array = getRawListenerArray();
+
+ for (RawInputListener listener : array) {
+ listener.beginInput();
+
+ for (int j = 0; j < queueSize; j++) {
+ InputEvent event = inputQueue.get(j);
+ if (event.isConsumed()) {
+ continue;
+ }
+
+ if (event instanceof MouseMotionEvent) {
+ listener.onMouseMotionEvent((MouseMotionEvent) event);
+ } else if (event instanceof KeyInputEvent) {
+ listener.onKeyEvent((KeyInputEvent) event);
+ } else if (event instanceof MouseButtonEvent) {
+ listener.onMouseButtonEvent((MouseButtonEvent) event);
+ } else if (event instanceof JoyAxisEvent) {
+ listener.onJoyAxisEvent((JoyAxisEvent) event);
+ } else if (event instanceof JoyButtonEvent) {
+ listener.onJoyButtonEvent((JoyButtonEvent) event);
+ } else if (event instanceof TouchEvent) {
+ listener.onTouchEvent((TouchEvent) event);
+ } else {
+ assert false;
+ }
+ }
+
+ listener.endInput();
+ }
+
+ for (int i = 0; i < queueSize; i++) {
+ InputEvent event = inputQueue.get(i);
+ if (event.isConsumed()) {
+ continue;
+ }
+
+ if (event instanceof MouseMotionEvent) {
+ onMouseMotionEventQueued((MouseMotionEvent) event);
+ } else if (event instanceof KeyInputEvent) {
+ onKeyEventQueued((KeyInputEvent) event);
+ } else if (event instanceof MouseButtonEvent) {
+ onMouseButtonEventQueued((MouseButtonEvent) event);
+ } else if (event instanceof JoyAxisEvent) {
+ onJoyAxisEventQueued((JoyAxisEvent) event);
+ } else if (event instanceof JoyButtonEvent) {
+ onJoyButtonEventQueued((JoyButtonEvent) event);
+ } else if (event instanceof TouchEvent) {
+ onTouchEventQueued((TouchEvent) event);
+ } else {
+ assert false;
+ }
+ // larynx, 2011.06.10 - flag event as reusable because
+ // the android input uses a non-allocating ringbuffer which
+ // needs to know when the event is not anymore in inputQueue
+ // and therefor can be reused.
+ event.setConsumed();
+ }
+
+ inputQueue.clear();
+ }
+
+ /**
+ * Updates the <code>InputManager</code>.
+ * This will query current input devices and send
+ * appropriate events to registered listeners.
+ *
+ * @param tpf Time per frame value.
+ */
+ public void update(float tpf) {
+ frameTPF = tpf;
+
+ // Activate safemode if the TPF value is so small
+ // that rounding errors are inevitable
+ safeMode = tpf < 0.015f;
+
+ long currentTime = keys.getInputTimeNanos();
+ frameDelta = currentTime - lastUpdateTime;
+
+ eventsPermitted = true;
+
+ keys.update();
+ mouse.update();
+ if (joystick != null) {
+ joystick.update();
+ }
+ if (touch != null) {
+ touch.update();
+ }
+
+ eventsPermitted = false;
+
+ processQueue();
+ invokeUpdateActions();
+
+ lastLastUpdateTime = lastUpdateTime;
+ lastUpdateTime = currentTime;
+ }
+
+ /**
+ * Dispatches touch events to touch listeners
+ * @param evt The touch event to be dispatched to all onTouch listeners
+ */
+ public void onTouchEventQueued(TouchEvent evt) {
+ ArrayList<Mapping> maps = bindings.get(TouchTrigger.touchHash(evt.getKeyCode()));
+ if (maps == null) {
+ return;
+ }
+
+ int size = maps.size();
+ for (int i = size - 1; i >= 0; i--) {
+ Mapping mapping = maps.get(i);
+ ArrayList<InputListener> listeners = mapping.listeners;
+ int listenerSize = listeners.size();
+ for (int j = listenerSize - 1; j >= 0; j--) {
+ InputListener listener = listeners.get(j);
+ if (listener instanceof TouchListener) {
+ ((TouchListener) listener).onTouch(mapping.name, evt, frameTPF);
+ }
+ }
+ }
+ }
+
+ /**
+ * Callback from RawInputListener. Do not use.
+ */
+ @Override
+ public void onTouchEvent(TouchEvent evt) {
+ if (!eventsPermitted) {
+ throw new UnsupportedOperationException("TouchInput has raised an event at an illegal time.");
+ }
+ inputQueue.add(evt);
+ }
+}
diff --git a/engine/src/core/com/jme3/input/JoyInput.java b/engine/src/core/com/jme3/input/JoyInput.java
new file mode 100644
index 0000000..77c5539
--- /dev/null
+++ b/engine/src/core/com/jme3/input/JoyInput.java
@@ -0,0 +1,66 @@
+/*
+ * 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.input;
+
+/**
+ * A specific API for interfacing with joysticks or gaming controllers.
+ */
+public interface JoyInput extends Input {
+
+ /**
+ * The X axis for POV (point of view hat).
+ */
+ public static final int AXIS_POV_X = 254;
+
+ /**
+ * The Y axis for POV (point of view hat).
+ */
+ public static final int AXIS_POV_Y = 255;
+
+ /**
+ * Causes the joystick at <code>joyId</code> index to rumble with
+ * the given amount.
+ *
+ * @param joyId The joystick index
+ * @param amount Rumble amount. Should be between 0 and 1.
+ */
+ public void setJoyRumble(int joyId, float amount);
+
+ /**
+ * Loads a list of joysticks from the system.
+ *
+ * @param inputManager The input manager requesting to load joysticks
+ * @return A list of joysticks that are installed.
+ */
+ public Joystick[] loadJoysticks(InputManager inputManager);
+}
diff --git a/engine/src/core/com/jme3/input/Joystick.java b/engine/src/core/com/jme3/input/Joystick.java
new file mode 100644
index 0000000..658781f
--- /dev/null
+++ b/engine/src/core/com/jme3/input/Joystick.java
@@ -0,0 +1,136 @@
+package com.jme3.input;
+
+import com.jme3.input.controls.JoyAxisTrigger;
+import com.jme3.input.controls.JoyButtonTrigger;
+
+/**
+ * A joystick represents a single joystick that is installed in the system.
+ *
+ * @author Kirill Vainer
+ */
+public final class Joystick {
+
+ private InputManager inputManager;
+ private JoyInput joyInput;
+ private int joyId;
+ private int buttonCount;
+ private int axisCount;
+ private int axisXIndex, axisYIndex;
+ private String name;
+
+ /**
+ * Creates a new joystick instance. Only used internally.
+ */
+ public Joystick(InputManager inputManager, JoyInput joyInput,
+ int joyId, String name, int buttonCount, int axisCount,
+ int xAxis, int yAxis){
+ this.inputManager = inputManager;
+ this.joyInput = joyInput;
+ this.joyId = joyId;
+ this.name = name;
+ this.buttonCount = buttonCount;
+ this.axisCount = axisCount;
+
+ this.axisXIndex = xAxis;
+ this.axisYIndex = yAxis;
+ }
+
+ /**
+ * Rumbles the joystick for the given amount/magnitude.
+ *
+ * @param amount The amount to rumble. Should be between 0 and 1.
+ */
+ public void rumble(float amount){
+ joyInput.setJoyRumble(joyId, amount);
+ }
+
+ /**
+ * Assign the mapping name to receive events from the given button index
+ * on the joystick.
+ *
+ * @param mappingName The mapping to receive joystick button events.
+ * @param buttonId The button index.
+ *
+ * @see Joystick#getButtonCount()
+ */
+ public void assignButton(String mappingName, int buttonId){
+ if (buttonId < 0 || buttonId >= buttonCount)
+ throw new IllegalArgumentException();
+
+ inputManager.addMapping(mappingName, new JoyButtonTrigger(joyId, buttonId));
+ }
+
+ /**
+ * Assign the mappings to receive events from the given joystick axis.
+ *
+ * @param positiveMapping The mapping to receive events when the axis is negative
+ * @param negativeMapping The mapping to receive events when the axis is positive
+ * @param axisId The axis index.
+ *
+ * @see Joystick#getAxisCount()
+ */
+ public void assignAxis(String positiveMapping, String negativeMapping, int axisId){
+ inputManager.addMapping(positiveMapping, new JoyAxisTrigger(joyId, axisId, false));
+ inputManager.addMapping(negativeMapping, new JoyAxisTrigger(joyId, axisId, true));
+ }
+
+ /**
+ * Gets the index number for the X axis on the joystick.
+ *
+ * <p>E.g. for most gamepads, the left control stick X axis will be returned.
+ *
+ * @return The axis index for the X axis for this joystick.
+ *
+ * @see Joystick#assignAxis(java.lang.String, java.lang.String, int)
+ */
+ public int getXAxisIndex(){
+ return axisXIndex;
+ }
+
+ /**
+ * Gets the index number for the Y axis on the joystick.
+ *
+ * <p>E.g. for most gamepads, the left control stick Y axis will be returned.
+ *
+ * @return The axis index for the Y axis for this joystick.
+ *
+ * @see Joystick#assignAxis(java.lang.String, java.lang.String, int)
+ */
+ public int getYAxisIndex(){
+ return axisYIndex;
+ }
+
+ /**
+ * Returns the number of axes on this joystick.
+ *
+ * @return the number of axes on this joystick.
+ */
+ public int getAxisCount() {
+ return axisCount;
+ }
+
+ /**
+ * Returns the number of buttons on this joystick.
+ *
+ * @return the number of buttons on this joystick.
+ */
+ public int getButtonCount() {
+ return buttonCount;
+ }
+
+ /**
+ * Returns the name of this joystick.
+ *
+ * @return the name of this joystick.
+ */
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString(){
+ return "Joystick[name=" + name + ", id=" + joyId + ", buttons=" + buttonCount
+ + ", axes=" + axisCount + "]";
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/KeyInput.java b/engine/src/core/com/jme3/input/KeyInput.java
new file mode 100644
index 0000000..a26d23a
--- /dev/null
+++ b/engine/src/core/com/jme3/input/KeyInput.java
@@ -0,0 +1,543 @@
+/*
+ * 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.input;
+
+/**
+ * A specific API for interfacing with the keyboard.
+ */
+public interface KeyInput extends Input {
+
+ /**
+ * escape key.
+ */
+ public static final int KEY_ESCAPE = 0x01;
+ /**
+ * 1 key.
+ */
+ public static final int KEY_1 = 0x02;
+ /**
+ * 2 key.
+ */
+ public static final int KEY_2 = 0x03;
+ /**
+ * 3 key.
+ */
+ public static final int KEY_3 = 0x04;
+ /**
+ * 4 key.
+ */
+ public static final int KEY_4 = 0x05;
+ /**
+ * 5 key.
+ */
+ public static final int KEY_5 = 0x06;
+ /**
+ * 6 key.
+ */
+ public static final int KEY_6 = 0x07;
+ /**
+ * 7 key.
+ */
+ public static final int KEY_7 = 0x08;
+ /**
+ * 8 key.
+ */
+ public static final int KEY_8 = 0x09;
+ /**
+ * 9 key.
+ */
+ public static final int KEY_9 = 0x0A;
+ /**
+ * 0 key.
+ */
+ public static final int KEY_0 = 0x0B;
+ /**
+ * - key.
+ */
+ public static final int KEY_MINUS = 0x0C;
+ /**
+ * = key.
+ */
+ public static final int KEY_EQUALS = 0x0D;
+ /**
+ * back key.
+ */
+ public static final int KEY_BACK = 0x0E;
+ /**
+ * tab key.
+ */
+ public static final int KEY_TAB = 0x0F;
+ /**
+ * q key.
+ */
+ public static final int KEY_Q = 0x10;
+ /**
+ * w key.
+ */
+ public static final int KEY_W = 0x11;
+ /**
+ * e key.
+ */
+ public static final int KEY_E = 0x12;
+ /**
+ * r key.
+ */
+ public static final int KEY_R = 0x13;
+ /**
+ * t key.
+ */
+ public static final int KEY_T = 0x14;
+ /**
+ * y key.
+ */
+ public static final int KEY_Y = 0x15;
+ /**
+ * u key.
+ */
+ public static final int KEY_U = 0x16;
+ /**
+ * i key.
+ */
+ public static final int KEY_I = 0x17;
+ /**
+ * o key.
+ */
+ public static final int KEY_O = 0x18;
+ /**
+ * p key.
+ */
+ public static final int KEY_P = 0x19;
+ /**
+ * [ key.
+ */
+ public static final int KEY_LBRACKET = 0x1A;
+ /**
+ * ] key.
+ */
+ public static final int KEY_RBRACKET = 0x1B;
+ /**
+ * enter (main keyboard) key.
+ */
+ public static final int KEY_RETURN = 0x1C;
+ /**
+ * left control key.
+ */
+ public static final int KEY_LCONTROL = 0x1D;
+ /**
+ * a key.
+ */
+ public static final int KEY_A = 0x1E;
+ /**
+ * s key.
+ */
+ public static final int KEY_S = 0x1F;
+ /**
+ * d key.
+ */
+ public static final int KEY_D = 0x20;
+ /**
+ * f key.
+ */
+ public static final int KEY_F = 0x21;
+ /**
+ * g key.
+ */
+ public static final int KEY_G = 0x22;
+ /**
+ * h key.
+ */
+ public static final int KEY_H = 0x23;
+ /**
+ * j key.
+ */
+ public static final int KEY_J = 0x24;
+ /**
+ * k key.
+ */
+ public static final int KEY_K = 0x25;
+ /**
+ * l key.
+ */
+ public static final int KEY_L = 0x26;
+ /**
+ * ; key.
+ */
+ public static final int KEY_SEMICOLON = 0x27;
+ /**
+ * ' key.
+ */
+ public static final int KEY_APOSTROPHE = 0x28;
+ /**
+ * ` key.
+ */
+ public static final int KEY_GRAVE = 0x29;
+ /**
+ * left shift key.
+ */
+ public static final int KEY_LSHIFT = 0x2A;
+ /**
+ * \ key.
+ */
+ public static final int KEY_BACKSLASH = 0x2B;
+ /**
+ * z key.
+ */
+ public static final int KEY_Z = 0x2C;
+ /**
+ * x key.
+ */
+ public static final int KEY_X = 0x2D;
+ /**
+ * c key.
+ */
+ public static final int KEY_C = 0x2E;
+ /**
+ * v key.
+ */
+ public static final int KEY_V = 0x2F;
+ /**
+ * b key.
+ */
+ public static final int KEY_B = 0x30;
+ /**
+ * n key.
+ */
+ public static final int KEY_N = 0x31;
+ /**
+ * m key.
+ */
+ public static final int KEY_M = 0x32;
+ /**
+ * , key.
+ */
+ public static final int KEY_COMMA = 0x33;
+ /**
+ * . key (main keyboard).
+ */
+ public static final int KEY_PERIOD = 0x34;
+ /**
+ * / key (main keyboard).
+ */
+ public static final int KEY_SLASH = 0x35;
+ /**
+ * right shift key.
+ */
+ public static final int KEY_RSHIFT = 0x36;
+ /**
+ * * key (on keypad).
+ */
+ public static final int KEY_MULTIPLY = 0x37;
+ /**
+ * left alt key.
+ */
+ public static final int KEY_LMENU = 0x38;
+ /**
+ * space key.
+ */
+ public static final int KEY_SPACE = 0x39;
+ /**
+ * caps lock key.
+ */
+ public static final int KEY_CAPITAL = 0x3A;
+ /**
+ * F1 key.
+ */
+ public static final int KEY_F1 = 0x3B;
+ /**
+ * F2 key.
+ */
+ public static final int KEY_F2 = 0x3C;
+ /**
+ * F3 key.
+ */
+ public static final int KEY_F3 = 0x3D;
+ /**
+ * F4 key.
+ */
+ public static final int KEY_F4 = 0x3E;
+ /**
+ * F5 key.
+ */
+ public static final int KEY_F5 = 0x3F;
+ /**
+ * F6 key.
+ */
+ public static final int KEY_F6 = 0x40;
+ /**
+ * F7 key.
+ */
+ public static final int KEY_F7 = 0x41;
+ /**
+ * F8 key.
+ */
+ public static final int KEY_F8 = 0x42;
+ /**
+ * F9 key.
+ */
+ public static final int KEY_F9 = 0x43;
+ /**
+ * F10 key.
+ */
+ public static final int KEY_F10 = 0x44;
+ /**
+ * NumLK key.
+ */
+ public static final int KEY_NUMLOCK = 0x45;
+ /**
+ * Scroll lock key.
+ */
+ public static final int KEY_SCROLL = 0x46;
+ /**
+ * 7 key (num pad).
+ */
+ public static final int KEY_NUMPAD7 = 0x47;
+ /**
+ * 8 key (num pad).
+ */
+ public static final int KEY_NUMPAD8 = 0x48;
+ /**
+ * 9 key (num pad).
+ */
+ public static final int KEY_NUMPAD9 = 0x49;
+ /**
+ * - key (num pad).
+ */
+ public static final int KEY_SUBTRACT = 0x4A;
+ /**
+ * 4 key (num pad).
+ */
+ public static final int KEY_NUMPAD4 = 0x4B;
+ /**
+ * 5 key (num pad).
+ */
+ public static final int KEY_NUMPAD5 = 0x4C;
+ /**
+ * 6 key (num pad).
+ */
+ public static final int KEY_NUMPAD6 = 0x4D;
+ /**
+ * + key (num pad).
+ */
+ public static final int KEY_ADD = 0x4E;
+ /**
+ * 1 key (num pad).
+ */
+ public static final int KEY_NUMPAD1 = 0x4F;
+ /**
+ * 2 key (num pad).
+ */
+ public static final int KEY_NUMPAD2 = 0x50;
+ /**
+ * 3 key (num pad).
+ */
+ public static final int KEY_NUMPAD3 = 0x51;
+ /**
+ * 0 key (num pad).
+ */
+ public static final int KEY_NUMPAD0 = 0x52;
+ /**
+ * . key (num pad).
+ */
+ public static final int KEY_DECIMAL = 0x53;
+ /**
+ * F11 key.
+ */
+ public static final int KEY_F11 = 0x57;
+ /**
+ * F12 key.
+ */
+ public static final int KEY_F12 = 0x58;
+ /**
+ * F13 key.
+ */
+ public static final int KEY_F13 = 0x64;
+ /**
+ * F14 key.
+ */
+ public static final int KEY_F14 = 0x65;
+ /**
+ * F15 key.
+ */
+ public static final int KEY_F15 = 0x66;
+ /**
+ * kana key (Japanese).
+ */
+ public static final int KEY_KANA = 0x70;
+ /**
+ * convert key (Japanese).
+ */
+ public static final int KEY_CONVERT = 0x79;
+ /**
+ * noconvert key (Japanese).
+ */
+ public static final int KEY_NOCONVERT = 0x7B;
+ /**
+ * yen key (Japanese).
+ */
+ public static final int KEY_YEN = 0x7D;
+ /**
+ * = on num pad (NEC PC98).
+ */
+ public static final int KEY_NUMPADEQUALS = 0x8D;
+ /**
+ * circum flex key (Japanese).
+ */
+ public static final int KEY_CIRCUMFLEX = 0x90;
+ /**
+ * &#064; key (NEC PC98).
+ */
+ public static final int KEY_AT = 0x91;
+ /**
+ * : key (NEC PC98)
+ */
+ public static final int KEY_COLON = 0x92;
+ /**
+ * _ key (NEC PC98).
+ */
+ public static final int KEY_UNDERLINE = 0x93;
+ /**
+ * kanji key (Japanese).
+ */
+ public static final int KEY_KANJI = 0x94;
+ /**
+ * stop key (NEC PC98).
+ */
+ public static final int KEY_STOP = 0x95;
+ /**
+ * ax key (Japanese).
+ */
+ public static final int KEY_AX = 0x96;
+ /**
+ * (J3100).
+ */
+ public static final int KEY_UNLABELED = 0x97;
+ /**
+ * Enter key (num pad).
+ */
+ public static final int KEY_NUMPADENTER = 0x9C;
+ /**
+ * right control key.
+ */
+ public static final int KEY_RCONTROL = 0x9D;
+ /**
+ * , key on num pad (NEC PC98).
+ */
+ public static final int KEY_NUMPADCOMMA = 0xB3;
+ /**
+ * / key (num pad).
+ */
+ public static final int KEY_DIVIDE = 0xB5;
+ /**
+ * SysRq key.
+ */
+ public static final int KEY_SYSRQ = 0xB7;
+ /**
+ * right alt key.
+ */
+ public static final int KEY_RMENU = 0xB8;
+ /**
+ * pause key.
+ */
+ public static final int KEY_PAUSE = 0xC5;
+ /**
+ * home key.
+ */
+ public static final int KEY_HOME = 0xC7;
+ /**
+ * up arrow key.
+ */
+ public static final int KEY_UP = 0xC8;
+ /**
+ * PgUp key.
+ */
+ public static final int KEY_PRIOR = 0xC9;
+ /**
+ * PgUp key.
+ */
+ public static final int KEY_PGUP = KEY_PRIOR;
+
+ /**
+ * left arrow key.
+ */
+ public static final int KEY_LEFT = 0xCB;
+ /**
+ * right arrow key.
+ */
+ public static final int KEY_RIGHT = 0xCD;
+ /**
+ * end key.
+ */
+ public static final int KEY_END = 0xCF;
+ /**
+ * down arrow key.
+ */
+ public static final int KEY_DOWN = 0xD0;
+ /**
+ * PgDn key.
+ */
+ public static final int KEY_NEXT = 0xD1;
+ /**
+ * PgDn key.
+ */
+ public static final int KEY_PGDN = KEY_NEXT;
+
+ /**
+ * insert key.
+ */
+ public static final int KEY_INSERT = 0xD2;
+ /**
+ * delete key.
+ */
+ public static final int KEY_DELETE = 0xD3;
+
+ /**
+ * Left "Windows" key on PC keyboards, left "Option" key on Mac keyboards.
+ */
+ public static final int KEY_LMETA = 0xDB;
+
+ /**
+ * Right "Windows" key on PC keyboards, right "Option" key on Mac keyboards.
+ */
+ public static final int KEY_RMETA = 0xDC;
+
+ public static final int KEY_APPS = 0xDD;
+ /**
+ * power key.
+ */
+ public static final int KEY_POWER = 0xDE;
+ /**
+ * sleep key.
+ */
+ public static final int KEY_SLEEP = 0xDF;
+
+}
diff --git a/engine/src/core/com/jme3/input/KeyNames.java b/engine/src/core/com/jme3/input/KeyNames.java
new file mode 100644
index 0000000..89490c0
--- /dev/null
+++ b/engine/src/core/com/jme3/input/KeyNames.java
@@ -0,0 +1,153 @@
+package com.jme3.input;
+
+import static com.jme3.input.KeyInput.*;
+
+public class KeyNames {
+
+ private static final String[] KEY_NAMES = new String[0xFF];
+
+ static {
+ KEY_NAMES[KEY_0] = "0";
+ KEY_NAMES[KEY_1] = "1";
+ KEY_NAMES[KEY_2] = "2";
+ KEY_NAMES[KEY_3] = "3";
+ KEY_NAMES[KEY_4] = "4";
+ KEY_NAMES[KEY_5] = "5";
+ KEY_NAMES[KEY_6] = "6";
+ KEY_NAMES[KEY_7] = "7";
+ KEY_NAMES[KEY_8] = "8";
+ KEY_NAMES[KEY_9] = "9";
+
+ KEY_NAMES[KEY_Q] = "Q";
+ KEY_NAMES[KEY_W] = "W";
+ KEY_NAMES[KEY_E] = "E";
+ KEY_NAMES[KEY_R] = "R";
+ KEY_NAMES[KEY_T] = "T";
+ KEY_NAMES[KEY_Y] = "Y";
+ KEY_NAMES[KEY_U] = "U";
+ KEY_NAMES[KEY_I] = "I";
+ KEY_NAMES[KEY_O] = "O";
+ KEY_NAMES[KEY_P] = "P";
+ KEY_NAMES[KEY_A] = "A";
+ KEY_NAMES[KEY_S] = "S";
+ KEY_NAMES[KEY_D] = "D";
+ KEY_NAMES[KEY_F] = "F";
+ KEY_NAMES[KEY_G] = "G";
+ KEY_NAMES[KEY_H] = "H";
+ KEY_NAMES[KEY_J] = "J";
+ KEY_NAMES[KEY_K] = "K";
+ KEY_NAMES[KEY_L] = "L";
+ KEY_NAMES[KEY_Z] = "Z";
+ KEY_NAMES[KEY_X] = "X";
+ KEY_NAMES[KEY_C] = "C";
+ KEY_NAMES[KEY_V] = "V";
+ KEY_NAMES[KEY_B] = "B";
+ KEY_NAMES[KEY_N] = "N";
+ KEY_NAMES[KEY_M] = "M";
+
+ KEY_NAMES[KEY_F1] = "F1";
+ KEY_NAMES[KEY_F2] = "F2";
+ KEY_NAMES[KEY_F3] = "F3";
+ KEY_NAMES[KEY_F4] = "F4";
+ KEY_NAMES[KEY_F5] = "F5";
+ KEY_NAMES[KEY_F6] = "F6";
+ KEY_NAMES[KEY_F7] = "F7";
+ KEY_NAMES[KEY_F8] = "F8";
+ KEY_NAMES[KEY_F9] = "F9";
+ KEY_NAMES[KEY_F10] = "F10";
+ KEY_NAMES[KEY_F11] = "F11";
+ KEY_NAMES[KEY_F12] = "F12";
+ KEY_NAMES[KEY_F13] = "F13";
+ KEY_NAMES[KEY_F14] = "F14";
+ KEY_NAMES[KEY_F15] = "F15";
+
+ KEY_NAMES[KEY_NUMPAD0] = "Numpad 0";
+ KEY_NAMES[KEY_NUMPAD1] = "Numpad 1";
+ KEY_NAMES[KEY_NUMPAD2] = "Numpad 2";
+ KEY_NAMES[KEY_NUMPAD3] = "Numpad 3";
+ KEY_NAMES[KEY_NUMPAD4] = "Numpad 4";
+ KEY_NAMES[KEY_NUMPAD5] = "Numpad 5";
+ KEY_NAMES[KEY_NUMPAD6] = "Numpad 6";
+ KEY_NAMES[KEY_NUMPAD7] = "Numpad 7";
+ KEY_NAMES[KEY_NUMPAD8] = "Numpad 8";
+ KEY_NAMES[KEY_NUMPAD9] = "Numpad 9";
+
+ KEY_NAMES[KEY_NUMPADEQUALS] = "Numpad =";
+ KEY_NAMES[KEY_NUMPADENTER] = "Numpad Enter";
+ KEY_NAMES[KEY_NUMPADCOMMA] = "Numpad .";
+ KEY_NAMES[KEY_DIVIDE] = "Numpad /";
+
+
+ KEY_NAMES[KEY_LMENU] = "Left Alt";
+ KEY_NAMES[KEY_RMENU] = "Right Alt";
+
+ KEY_NAMES[KEY_LCONTROL] = "Left Ctrl";
+ KEY_NAMES[KEY_RCONTROL] = "Right Ctrl";
+
+ KEY_NAMES[KEY_LSHIFT] = "Left Shift";
+ KEY_NAMES[KEY_RSHIFT] = "Right Shift";
+
+ KEY_NAMES[KEY_LMETA] = "Left Option";
+ KEY_NAMES[KEY_RMETA] = "Right Option";
+
+ KEY_NAMES[KEY_MINUS] = "-";
+ KEY_NAMES[KEY_EQUALS] = "=";
+ KEY_NAMES[KEY_LBRACKET] = "[";
+ KEY_NAMES[KEY_RBRACKET] = "]";
+ KEY_NAMES[KEY_SEMICOLON] = ";";
+ KEY_NAMES[KEY_APOSTROPHE] = "'";
+ KEY_NAMES[KEY_GRAVE] = "`";
+ KEY_NAMES[KEY_BACKSLASH] = "\\";
+ KEY_NAMES[KEY_COMMA] = ",";
+ KEY_NAMES[KEY_PERIOD] = ".";
+ KEY_NAMES[KEY_SLASH] = "/";
+ KEY_NAMES[KEY_MULTIPLY] = "*";
+ KEY_NAMES[KEY_ADD] = "+";
+ KEY_NAMES[KEY_COLON] = ":";
+ KEY_NAMES[KEY_UNDERLINE] = "_";
+ KEY_NAMES[KEY_AT] = "@";
+
+ KEY_NAMES[KEY_APPS] = "Apps";
+ KEY_NAMES[KEY_POWER] = "Power";
+ KEY_NAMES[KEY_SLEEP] = "Sleep";
+
+ KEY_NAMES[KEY_STOP] = "Stop";
+ KEY_NAMES[KEY_ESCAPE] = "Esc";
+ KEY_NAMES[KEY_RETURN] = "Enter";
+ KEY_NAMES[KEY_SPACE] = "Space";
+ KEY_NAMES[KEY_BACK] = "Backspace";
+ KEY_NAMES[KEY_TAB] = "Tab";
+
+ KEY_NAMES[KEY_SYSRQ] = "SysEq";
+ KEY_NAMES[KEY_PAUSE] = "Pause";
+
+ KEY_NAMES[KEY_HOME] = "Home";
+ KEY_NAMES[KEY_PGUP] = "Page Up";
+ KEY_NAMES[KEY_PGDN] = "Page Down";
+ KEY_NAMES[KEY_END] = "End";
+ KEY_NAMES[KEY_INSERT] = "Insert";
+ KEY_NAMES[KEY_DELETE] = "Delete";
+
+ KEY_NAMES[KEY_UP] = "Up";
+ KEY_NAMES[KEY_LEFT] = "Left";
+ KEY_NAMES[KEY_RIGHT] = "Right";
+ KEY_NAMES[KEY_DOWN] = "Down";
+
+ KEY_NAMES[KEY_NUMLOCK] = "Num Lock";
+ KEY_NAMES[KEY_CAPITAL] = "Caps Lock";
+ KEY_NAMES[KEY_SCROLL] = "Scroll Lock";
+
+ KEY_NAMES[KEY_KANA] = "Kana";
+ KEY_NAMES[KEY_CONVERT] = "Convert";
+ KEY_NAMES[KEY_NOCONVERT] = "No Convert";
+ KEY_NAMES[KEY_YEN] = "Yen";
+ KEY_NAMES[KEY_CIRCUMFLEX] = "Circumflex";
+ KEY_NAMES[KEY_KANJI] = "Kanji";
+ KEY_NAMES[KEY_AX] = "Ax";
+ KEY_NAMES[KEY_UNLABELED] = "Unlabeled";
+ }
+
+ public String getName(int keyId){
+ return KEY_NAMES[keyId];
+ }
+}
diff --git a/engine/src/core/com/jme3/input/MouseInput.java b/engine/src/core/com/jme3/input/MouseInput.java
new file mode 100644
index 0000000..f4a1f36
--- /dev/null
+++ b/engine/src/core/com/jme3/input/MouseInput.java
@@ -0,0 +1,83 @@
+/*
+ * 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.input;
+
+/**
+ * A specific API for interfacing with the mouse.
+ */
+public interface MouseInput extends Input {
+
+ /**
+ * Mouse X axis.
+ */
+ public static final int AXIS_X = 0;
+
+ /**
+ * Mouse Y axis.
+ */
+ public static final int AXIS_Y = 1;
+
+ /**
+ * Mouse wheel axis.
+ */
+ public static final int AXIS_WHEEL = 2;
+
+ /**
+ * Left mouse button.
+ */
+ public static final int BUTTON_LEFT = 0;
+
+ /**
+ * Right mouse button.
+ */
+ public static final int BUTTON_RIGHT = 1;
+
+ /**
+ * Middle mouse button.
+ */
+ public static final int BUTTON_MIDDLE = 2;
+
+ /**
+ * Set whether the mouse cursor should be visible or not.
+ *
+ * @param visible Whether the mouse cursor should be visible or not.
+ */
+ public void setCursorVisible(boolean visible);
+
+ /**
+ * Returns the number of buttons the mouse has. Typically 3 for most mice.
+ *
+ * @return the number of buttons the mouse has.
+ */
+ public int getButtonCount();
+}
diff --git a/engine/src/core/com/jme3/input/RawInputListener.java b/engine/src/core/com/jme3/input/RawInputListener.java
new file mode 100644
index 0000000..dfdd69e
--- /dev/null
+++ b/engine/src/core/com/jme3/input/RawInputListener.java
@@ -0,0 +1,99 @@
+/*
+ * 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.input;
+
+import com.jme3.input.event.*;
+
+/**
+ * An interface used for receiving raw input from devices.
+ */
+public interface RawInputListener {
+
+ /**
+ * Called before a batch of input will be sent to this
+ * <code>RawInputListener</code>.
+ */
+ public void beginInput();
+
+ /**
+ * Called after a batch of input was sent to this
+ * <code>RawInputListener</code>.
+ *
+ * The listener should set the {@link InputEvent#setConsumed() consumed flag}
+ * on any events that have been consumed either at this call or previous calls.
+ */
+ public void endInput();
+
+ /**
+ * Invoked on joystick axis events.
+ *
+ * @param evt
+ */
+ public void onJoyAxisEvent(JoyAxisEvent evt);
+
+ /**
+ * Invoked on joystick button presses.
+ *
+ * @param evt
+ */
+ public void onJoyButtonEvent(JoyButtonEvent evt);
+
+ /**
+ * Invoked on mouse movement/motion events.
+ *
+ * @param evt
+ */
+ public void onMouseMotionEvent(MouseMotionEvent evt);
+
+ /**
+ * Invoked on mouse button events.
+ *
+ * @param evt
+ */
+ public void onMouseButtonEvent(MouseButtonEvent evt);
+
+ /**
+ * Invoked on keyboard key press or release events.
+ *
+ * @param evt
+ */
+ public void onKeyEvent(KeyInputEvent evt);
+
+
+ /**
+ * Invoked on touchscreen touch events.
+ *
+ * @param evt
+ */
+ public void onTouchEvent(TouchEvent evt);
+}
diff --git a/engine/src/core/com/jme3/input/TouchInput.java b/engine/src/core/com/jme3/input/TouchInput.java
new file mode 100644
index 0000000..2f45b44
--- /dev/null
+++ b/engine/src/core/com/jme3/input/TouchInput.java
@@ -0,0 +1,92 @@
+/*
+ * 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.input;
+
+/**
+ * A specific API for interfacing with smartphone touch devices
+ */
+public interface TouchInput extends Input {
+
+ /**
+ * No filter, get all events
+ */
+ public static final int ALL = 0x00;
+ /**
+ * Home key
+ */
+ public static final int KEYCODE_HOME = 0x03;
+ /**
+ * Escape key.
+ */
+ public static final int KEYCODE_BACK = 0x04;
+ /**
+ * Context Menu key.
+ */
+ public static final int KEYCODE_MENU = 0x52;
+ /**
+ * Search key.
+ */
+ public static final int KEYCODE_SEARCH = 0x54;
+ /**
+ * Volume up key.
+ */
+ public static final int KEYCODE_VOLUME_UP = 0x18;
+ /**
+ * Volume down key.
+ */
+ public static final int KEYCODE_VOLUME_DOWN = 0x19;
+
+
+ /**
+ * Set if mouse events should be generated
+ *
+ * @param simulate if mouse events should be generated
+ */
+ public void setSimulateMouse(boolean simulate);
+
+ /**
+ * Set if keyboard events should be generated
+ *
+ * @param simulate if keyboard events should be generated
+ */
+ public void setSimulateKeyboard(boolean simulate);
+
+ /**
+ * Set if historic android events should be transmitted, can be used to get better performance and less mem
+ * @see <a href="http://developer.android.com/reference/android/view/MotionEvent.html#getHistoricalX%28int,%20int%29">
+ * http://developer.android.com/reference/android/view/MotionEvent.html#getHistoricalX%28int,%20int%29</a>
+ * @param dontSendHistory turn of historic events if true, false else and default
+ */
+ public void setOmitHistoricEvents(boolean dontSendHistory);
+
+} \ No newline at end of file
diff --git a/engine/src/core/com/jme3/input/controls/ActionListener.java b/engine/src/core/com/jme3/input/controls/ActionListener.java
new file mode 100644
index 0000000..8deed3c
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/ActionListener.java
@@ -0,0 +1,58 @@
+/*
+ * 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.input.controls;
+
+/**
+ * <code>ActionListener</code> is used to receive input events in "digital" style.
+ * <p>
+ * Generally all button inputs, such as keyboard, mouse button, and joystick button,
+ * will be represented exactly. Analog inputs will be converted into digital.
+ * <p>
+ * When an action listener is registered to a natively digital input, such as a button,
+ * the event will be invoked when the button is pressed, with <code>value</code>
+ * set to <code>true</code>, and will be invoked again when the button is released,
+ * with <code>value</code> set to <code>false</code>.
+ *
+ * @author Kirill Vainer
+ */
+public interface ActionListener extends InputListener {
+
+ /**
+ * Called when an input to which this listener is registered to is invoked.
+ *
+ * @param name The name of the mapping that was invoked
+ * @param isPressed True if the action is "pressed", false otherwise
+ * @param tpf The time per frame value.
+ */
+ public void onAction(String name, boolean isPressed, float tpf);
+}
diff --git a/engine/src/core/com/jme3/input/controls/AnalogListener.java b/engine/src/core/com/jme3/input/controls/AnalogListener.java
new file mode 100644
index 0000000..b28796a
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/AnalogListener.java
@@ -0,0 +1,53 @@
+/*
+ * 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.input.controls;
+
+/**
+ * <code>AnalogListener</code> is used to receive events of inputs
+ * in analog format.
+ *
+ * @author Kirill Vainer
+ */
+public interface AnalogListener extends InputListener {
+ /**
+ * Called to notify the implementation that an analog event has occurred.
+ *
+ * The results of KeyTrigger and MouseButtonTrigger events will have tpf
+ * == value.
+ *
+ * @param name The name of the mapping that was invoked
+ * @param value Value of the axis, from 0 to 1.
+ * @param tpf The time per frame value.
+ */
+ public void onAnalog(String name, float value, float tpf);
+}
diff --git a/engine/src/core/com/jme3/input/controls/InputListener.java b/engine/src/core/com/jme3/input/controls/InputListener.java
new file mode 100644
index 0000000..ce140a9
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/InputListener.java
@@ -0,0 +1,42 @@
+/*
+ * 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.input.controls;
+
+/**
+ * A generic interface for input listeners, the {@link AnalogListener} and
+ * {@link ActionListener} interfaces extend this interface.
+ *
+ * @author Kirill Vainer
+ */
+public interface InputListener {
+}
diff --git a/engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java b/engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java
new file mode 100644
index 0000000..539d83e
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java
@@ -0,0 +1,77 @@
+/*
+ * 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.input.controls;
+
+import com.jme3.input.Joystick;
+
+public class JoyAxisTrigger implements Trigger {
+
+ private final int joyId, axisId;
+ private final boolean negative;
+
+ /**
+ * Use {@link Joystick#assignAxis(java.lang.String, java.lang.String, int) }
+ * instead.
+ */
+ public JoyAxisTrigger(int joyId, int axisId, boolean negative) {
+ this.joyId = joyId;
+ this.axisId = axisId;
+ this.negative = negative;
+ }
+
+ public static int joyAxisHash(int joyId, int joyAxis, boolean negative){
+ assert joyAxis >= 0 && joyAxis <= 255;
+ return (2048 * joyId) | (negative ? 1280 : 1024) | (joyAxis & 0xff);
+ }
+
+ public int getAxisId() {
+ return axisId;
+ }
+
+ public int getJoyId() {
+ return joyId;
+ }
+
+ public boolean isNegative() {
+ return negative;
+ }
+
+ public String getName() {
+ return "JoyAxis[joyId="+joyId+", axisId="+axisId+", neg="+negative+"]";
+ }
+
+ public int triggerHashCode() {
+ return joyAxisHash(joyId, axisId, negative);
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java b/engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java
new file mode 100644
index 0000000..5e2cfd6
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java
@@ -0,0 +1,73 @@
+/*
+ * 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.input.controls;
+
+import com.jme3.input.Joystick;
+
+public class JoyButtonTrigger implements Trigger {
+
+ private final int joyId, buttonId;
+
+ /**
+ * Use {@link Joystick#assignButton(java.lang.String, int) } instead.
+ *
+ * @param joyId
+ * @param axisId
+ */
+ public JoyButtonTrigger(int joyId, int axisId) {
+ this.joyId = joyId;
+ this.buttonId = axisId;
+ }
+
+ public static int joyButtonHash(int joyId, int joyButton){
+ assert joyButton >= 0 && joyButton <= 255;
+ return (2048 * joyId) | 1536 | (joyButton & 0xff);
+ }
+
+ public int getAxisId() {
+ return buttonId;
+ }
+
+ public int getJoyId() {
+ return joyId;
+ }
+
+ public String getName() {
+ return "JoyButton[joyId="+joyId+", axisId="+buttonId+"]";
+ }
+
+ public int triggerHashCode() {
+ return joyButtonHash(joyId, buttonId);
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/controls/KeyTrigger.java b/engine/src/core/com/jme3/input/controls/KeyTrigger.java
new file mode 100644
index 0000000..993b4e7
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/KeyTrigger.java
@@ -0,0 +1,72 @@
+/*
+ * 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.input.controls;
+
+import com.jme3.input.KeyInput;
+
+/**
+ * A <code>KeyTrigger</code> is used as a mapping to keyboard keys.
+ *
+ * @author Kirill Vainer
+ */
+public class KeyTrigger implements Trigger {
+
+ private final int keyCode;
+
+ /**
+ * Create a new <code>KeyTrigger</code> for the given keycode.
+ *
+ * @param keyCode the code for the key, see constants in {@link KeyInput}.
+ */
+ public KeyTrigger(int keyCode){
+ this.keyCode = keyCode;
+ }
+
+ public String getName() {
+ return "KeyCode " + keyCode;
+ }
+
+ public int getKeyCode(){
+ return keyCode;
+ }
+
+ public static int keyHash(int keyCode){
+ assert keyCode >= 0 && keyCode <= 255;
+ return keyCode & 0xff;
+ }
+
+ public int triggerHashCode() {
+ return keyHash(keyCode);
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java b/engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java
new file mode 100644
index 0000000..49de745
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java
@@ -0,0 +1,90 @@
+/*
+ * 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.input.controls;
+
+import com.jme3.input.MouseInput;
+
+/**
+ * A <code>MouseAxisTrigger</code> is used as a mapping to mouse axis,
+ * a mouse axis is movement along the X axis (left/right), Y axis (up/down)
+ * and the mouse wheel (scroll up/down).
+ *
+ * @author Kirill Vainer
+ */
+public class MouseAxisTrigger implements Trigger {
+
+ private int mouseAxis;
+ private boolean negative;
+
+ /**
+ * Create a new <code>MouseAxisTrigger</code>.
+ * <p>
+ * @param mouseAxis Mouse axis. See AXIS_*** constants in {@link MouseInput}
+ * @param negative True if listen to negative axis events, false if
+ * listen to positive axis events.
+ */
+ public MouseAxisTrigger(int mouseAxis, boolean negative){
+ if (mouseAxis < 0 || mouseAxis > 2)
+ throw new IllegalArgumentException("Mouse Axis must be between 0 and 2");
+
+ this.mouseAxis = mouseAxis;
+ this.negative = negative;
+ }
+
+ public int getMouseAxis(){
+ return mouseAxis;
+ }
+
+ public boolean isNegative() {
+ return negative;
+ }
+
+ public String getName() {
+ String sign = negative ? "Negative" : "Positive";
+ switch (mouseAxis){
+ case MouseInput.AXIS_X: return "Mouse X Axis " + sign;
+ case MouseInput.AXIS_Y: return "Mouse Y Axis " + sign;
+ case MouseInput.AXIS_WHEEL: return "Mouse Wheel " + sign;
+ default: throw new AssertionError();
+ }
+ }
+
+ public static int mouseAxisHash(int mouseAxis, boolean negative){
+ assert mouseAxis >= 0 && mouseAxis <= 255;
+ return (negative ? 768 : 512) | (mouseAxis & 0xff);
+ }
+
+ public int triggerHashCode() {
+ return mouseAxisHash(mouseAxis, negative);
+ }
+}
diff --git a/engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java b/engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java
new file mode 100644
index 0000000..ff013d6
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java
@@ -0,0 +1,79 @@
+/*
+ * 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.input.controls;
+
+import com.jme3.input.MouseInput;
+
+/**
+ * A <code>MouseButtonTrigger</code> is used as a mapping to receive events
+ * from mouse buttons. It is generally expected for a mouse to have at least
+ * a left and right mouse button, but some mice may have a lot more buttons
+ * than that.
+ *
+ * @author Kirill Vainer
+ */
+public class MouseButtonTrigger implements Trigger {
+
+ private final int mouseButton;
+
+ /**
+ * Create a new <code>MouseButtonTrigger</code> to receive mouse button events.
+ *
+ * @param mouseButton Mouse button index. See BUTTON_*** constants in
+ * {@link MouseInput}.
+ */
+ public MouseButtonTrigger(int mouseButton) {
+ if (mouseButton < 0)
+ throw new IllegalArgumentException("Mouse Button cannot be negative");
+
+ this.mouseButton = mouseButton;
+ }
+
+ public int getMouseButton() {
+ return mouseButton;
+ }
+
+ public String getName() {
+ return "Mouse Button " + mouseButton;
+ }
+
+ public static int mouseButtonHash(int mouseButton){
+ assert mouseButton >= 0 && mouseButton <= 255;
+ return 256 | (mouseButton & 0xff);
+ }
+
+ public int triggerHashCode() {
+ return mouseButtonHash(mouseButton);
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/controls/TouchListener.java b/engine/src/core/com/jme3/input/controls/TouchListener.java
new file mode 100644
index 0000000..21c100f
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/TouchListener.java
@@ -0,0 +1,49 @@
+/*
+ * 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.input.controls;
+
+import com.jme3.input.event.TouchEvent;
+
+/**
+ * <code>TouchListener</code> is used to receive events of inputs from smartphone touch devices
+ *
+ * @author larynx
+ */
+public interface TouchListener extends InputListener {
+ /**
+ * @param name the name of the event
+ * @param event the touch event
+ * @param tpf how much time has passed since the last frame
+ */
+ public void onTouch(String name, TouchEvent event, float tpf);
+} \ No newline at end of file
diff --git a/engine/src/core/com/jme3/input/controls/TouchTrigger.java b/engine/src/core/com/jme3/input/controls/TouchTrigger.java
new file mode 100644
index 0000000..25124ab
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/TouchTrigger.java
@@ -0,0 +1,73 @@
+/*
+ * 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.input.controls;
+
+/**
+ * Class to trigger TouchEvents, keycode can be TouchInput.ALL(=0) or TouchInput.KEYCODE_*
+ * @author larynx
+ *
+ */
+public class TouchTrigger implements Trigger {
+
+ private final int keyCode;
+
+ /**
+ * Constructor
+ * @param keyCode can be zero to get all events or TouchInput.KEYCODE_*
+ */
+ public TouchTrigger(int keyCode) {
+ super();
+ this.keyCode = keyCode;
+ }
+
+ @Override
+ public String getName() {
+ if (keyCode != 0)
+ return "TouchInput";
+ else
+ return "TouchInput KeyCode " + keyCode;
+ }
+
+ public static int touchHash(int keyCode){
+ assert keyCode >= 0 && keyCode <= 255;
+ return 0xfedcba98 + keyCode;
+ }
+
+ public int triggerHashCode() {
+ return touchHash(keyCode);
+ }
+
+ public int getKeyCode(){
+ return keyCode;
+ }
+}
diff --git a/engine/src/core/com/jme3/input/controls/Trigger.java b/engine/src/core/com/jme3/input/controls/Trigger.java
new file mode 100644
index 0000000..9f059e8
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/Trigger.java
@@ -0,0 +1,52 @@
+/*
+ * 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.input.controls;
+
+/**
+ * A trigger represents a physical input, such as a keyboard key, a mouse
+ * button, or joystick axis.
+ */
+public interface Trigger {
+
+ /**
+ * @return A user friendly name for the trigger.
+ */
+ public String getName();
+
+ /**
+ * Returns the hash code for the trigger.
+ *
+ * @return the hash code for the trigger.
+ */
+ public int triggerHashCode();
+}
diff --git a/engine/src/core/com/jme3/input/controls/package.html b/engine/src/core/com/jme3/input/controls/package.html
new file mode 100644
index 0000000..2303ea9
--- /dev/null
+++ b/engine/src/core/com/jme3/input/controls/package.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+<title></title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body>
+
+The <code>com.jme3.input.controls</code> package allows user code to listen
+to input events regardless of the type of input used.
+<p>
+Users will receive input in one of two forms, either
+{@link com.jme3.input.controls.AnalogListener analog input} or
+{@link com.jme3.input.controls.Action digital/action input}.
+
+
+</body>
+</html>
diff --git a/engine/src/core/com/jme3/input/dummy/DummyInput.java b/engine/src/core/com/jme3/input/dummy/DummyInput.java
new file mode 100644
index 0000000..3ecb509
--- /dev/null
+++ b/engine/src/core/com/jme3/input/dummy/DummyInput.java
@@ -0,0 +1,78 @@
+/*
+ * 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.input.dummy;
+
+import com.jme3.input.Input;
+import com.jme3.input.RawInputListener;
+
+/**
+ * DummyInput as an implementation of <code>Input</code> that raises no
+ * input events.
+ *
+ * @author Kirill Vainer.
+ */
+public class DummyInput implements Input {
+
+ protected boolean inited = false;
+
+ public void initialize() {
+ if (inited)
+ throw new IllegalStateException("Input already initialized.");
+
+ inited = true;
+ }
+
+ public void update() {
+ if (!inited)
+ throw new IllegalStateException("Input not initialized.");
+ }
+
+ public void destroy() {
+ if (!inited)
+ throw new IllegalStateException("Input not initialized.");
+
+ inited = false;
+ }
+
+ public boolean isInitialized() {
+ return inited;
+ }
+
+ public void setInputListener(RawInputListener listener) {
+ }
+
+ public long getInputTimeNanos() {
+ return System.currentTimeMillis() * 1000000;
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/dummy/DummyKeyInput.java b/engine/src/core/com/jme3/input/dummy/DummyKeyInput.java
new file mode 100644
index 0000000..4d4efcb
--- /dev/null
+++ b/engine/src/core/com/jme3/input/dummy/DummyKeyInput.java
@@ -0,0 +1,52 @@
+/*
+ * 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.input.dummy;
+
+import com.jme3.input.KeyInput;
+
+/**
+ * DummyKeyInput as an implementation of <code>KeyInput</code> that raises no
+ * input events.
+ *
+ * @author Kirill Vainer.
+ */
+public class DummyKeyInput extends DummyInput implements KeyInput {
+
+ public int getKeyCount() {
+ if (!inited)
+ throw new IllegalStateException("Input not initialized.");
+
+ return 0;
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/dummy/DummyMouseInput.java b/engine/src/core/com/jme3/input/dummy/DummyMouseInput.java
new file mode 100644
index 0000000..b862061
--- /dev/null
+++ b/engine/src/core/com/jme3/input/dummy/DummyMouseInput.java
@@ -0,0 +1,54 @@
+/*
+ * 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.input.dummy;
+
+import com.jme3.input.MouseInput;
+
+/**
+ * DummyMouseInput as an implementation of <code>MouseInput</code> that raises no
+ * input events.
+ *
+ * @author Kirill Vainer.
+ */
+public class DummyMouseInput extends DummyInput implements MouseInput {
+
+ public void setCursorVisible(boolean visible) {
+ if (!inited)
+ throw new IllegalStateException("Input not initialized.");
+ }
+
+ public int getButtonCount() {
+ return 0;
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/dummy/package.html b/engine/src/core/com/jme3/input/dummy/package.html
new file mode 100644
index 0000000..13f5c55
--- /dev/null
+++ b/engine/src/core/com/jme3/input/dummy/package.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+<title></title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body>
+
+The <code>com.jme3.input.dummy</code> package provides "dummy" or "null"
+implementations of the input interfaces.
+
+</body>
+</html>
diff --git a/engine/src/core/com/jme3/input/event/InputEvent.java b/engine/src/core/com/jme3/input/event/InputEvent.java
new file mode 100644
index 0000000..bb3867d
--- /dev/null
+++ b/engine/src/core/com/jme3/input/event/InputEvent.java
@@ -0,0 +1,84 @@
+/*
+ * 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.input.event;
+
+import com.jme3.input.Input;
+
+/**
+ * An abstract input event.
+ */
+public abstract class InputEvent {
+
+ protected long time;
+
+
+ protected boolean consumed = false;
+
+ /**
+ * The time when the event occurred. This is relative to
+ * {@link Input#getInputTimeNanos() }.
+ *
+ * @return time when the event occured
+ */
+ public long getTime(){
+ return time;
+ }
+
+ /**
+ * Set the time when the event occurred.
+ *
+ * @param time time when the event occurred.
+ */
+ public void setTime(long time){
+ this.time = time;
+ }
+
+ /**
+ * Returns true if the input event has been consumed, meaning it is no longer valid
+ * and should not be forwarded to input listeners.
+ *
+ * @return true if the input event has been consumed
+ */
+ public boolean isConsumed() {
+ return consumed;
+ }
+
+ /**
+ * Call to mark this input event as consumed, meaning it is no longer valid
+ * and should not be forwarded to input listeners.
+ */
+ public void setConsumed() {
+ this.consumed = true;
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/event/JoyAxisEvent.java b/engine/src/core/com/jme3/input/event/JoyAxisEvent.java
new file mode 100644
index 0000000..2896b0b
--- /dev/null
+++ b/engine/src/core/com/jme3/input/event/JoyAxisEvent.java
@@ -0,0 +1,85 @@
+/*
+ * 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.input.event;
+
+import com.jme3.input.InputManager;
+import com.jme3.input.Joystick;
+
+/**
+ * Joystick axis event.
+ *
+ * @author Kirill Vainer
+ */
+public class JoyAxisEvent extends InputEvent {
+
+ private int joyIdx;
+ private int axisIdx;
+ private float value;
+
+ public JoyAxisEvent(int joyIdx, int axisIdx, float value) {
+ this.joyIdx = joyIdx;
+ this.axisIdx = axisIdx;
+ this.value = value;
+ }
+
+ /**
+ * Returns the joystick axis index.
+ *
+ * @return joystick axis index.
+ *
+ * @see Joystick#assignAxis(java.lang.String, java.lang.String, int)
+ */
+ public int getAxisIndex() {
+ return axisIdx;
+ }
+
+ /**
+ * The joystick index.
+ *
+ * @return joystick index.
+ *
+ * @see InputManager#getJoysticks()
+ */
+ public int getJoyIndex() {
+ return joyIdx;
+ }
+
+ /**
+ * The value of the axis.
+ *
+ * @return value of the axis.
+ */
+ public float getValue() {
+ return value;
+ }
+}
diff --git a/engine/src/core/com/jme3/input/event/JoyButtonEvent.java b/engine/src/core/com/jme3/input/event/JoyButtonEvent.java
new file mode 100644
index 0000000..906847f
--- /dev/null
+++ b/engine/src/core/com/jme3/input/event/JoyButtonEvent.java
@@ -0,0 +1,89 @@
+/*
+ * 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.input.event;
+
+import com.jme3.input.Joystick;
+
+/**
+ * Joystick button event.
+ *
+ * @author Kirill Vainer
+ */
+public class JoyButtonEvent extends InputEvent {
+
+ private int joyIdx;
+ private int btnIdx;
+ private boolean pressed;
+
+ public JoyButtonEvent(int joyIdx, int btnIdx, boolean pressed) {
+ this.joyIdx = joyIdx;
+ this.btnIdx = btnIdx;
+ this.pressed = pressed;
+ }
+
+ /**
+ * The button index.
+ *
+ * @return button index.
+ *
+ * @see Joystick#assignButton(java.lang.String, int)
+ */
+ public int getButtonIndex() {
+ return btnIdx;
+ }
+
+ /**
+ * The joystick index.
+ *
+ * @return joystick index.
+ *
+ * @see InputManager#getJoysticks()
+ */
+ public int getJoyIndex() {
+ return joyIdx;
+ }
+
+ /**
+ * Returns true if the event was a button press,
+ * returns false if the event was a button release.
+ *
+ * @return true if the event was a button press,
+ * false if the event was a button release.
+ */
+ public boolean isPressed() {
+ return pressed;
+ }
+
+
+
+}
diff --git a/engine/src/core/com/jme3/input/event/KeyInputEvent.java b/engine/src/core/com/jme3/input/event/KeyInputEvent.java
new file mode 100644
index 0000000..403635c
--- /dev/null
+++ b/engine/src/core/com/jme3/input/event/KeyInputEvent.java
@@ -0,0 +1,117 @@
+/*
+ * 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.input.event;
+
+import com.jme3.input.KeyInput;
+
+/**
+ * Keyboard key event.
+ *
+ * @author Kirill Vainer
+ */
+public class KeyInputEvent extends InputEvent {
+
+ private int keyCode;
+ private char keyChar;
+ private boolean pressed;
+ private boolean repeating;
+
+ public KeyInputEvent(int keyCode, char keyChar, boolean pressed, boolean repeating) {
+ this.keyCode = keyCode;
+ this.keyChar = keyChar;
+ this.pressed = pressed;
+ this.repeating = repeating;
+ }
+
+ /**
+ * Returns the key character. Returns 0 if the key has no character.
+ *
+ * @return the key character. 0 if the key has no character.
+ */
+ public char getKeyChar() {
+ return keyChar;
+ }
+
+ /**
+ * The key code.
+ * <p>
+ * See KEY_*** constants in {@link KeyInput}.
+ *
+ * @return key code.
+ */
+ public int getKeyCode() {
+ return keyCode;
+ }
+
+ /**
+ * Returns true if this event is key press, false is it was a key release.
+ *
+ * @return true if this event is key press, false is it was a key release.
+ */
+ public boolean isPressed() {
+ return pressed;
+ }
+
+ /**
+ * Returns true if this event is a repeat event. Not used anymore.
+ *
+ * @return true if this event is a repeat event
+ */
+ public boolean isRepeating() {
+ return repeating;
+ }
+
+ /**
+ * Returns true if this event is a key release, false if it was a key press.
+ *
+ * @return true if this event is a key release, false if it was a key press.
+ */
+ public boolean isReleased() {
+ return !pressed;
+ }
+
+ @Override
+ public String toString(){
+ String str = "Key(CODE="+keyCode;
+ if (keyChar != '\0')
+ str = str + ", CHAR=" + keyChar;
+
+ if (repeating){
+ return str + ", REPEATING)";
+ }else if (pressed){
+ return str + ", PRESSED)";
+ }else{
+ return str + ", RELEASED)";
+ }
+ }
+}
diff --git a/engine/src/core/com/jme3/input/event/MouseButtonEvent.java b/engine/src/core/com/jme3/input/event/MouseButtonEvent.java
new file mode 100644
index 0000000..66af54d
--- /dev/null
+++ b/engine/src/core/com/jme3/input/event/MouseButtonEvent.java
@@ -0,0 +1,111 @@
+/*
+ * 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.input.event;
+
+import com.jme3.input.MouseInput;
+
+/**
+ * Mouse button press/release event.
+ *
+ * @author Kirill Vainer
+ */
+public class MouseButtonEvent extends InputEvent {
+
+ private int x;
+ private int y;
+ private int btnIndex;
+ private boolean pressed;
+
+ public MouseButtonEvent(int btnIndex, boolean pressed, int x, int y) {
+ this.btnIndex = btnIndex;
+ this.pressed = pressed;
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Returns the mouse button index.
+ * <p>
+ * See constants in {@link MouseInput}.
+ *
+ * @return the mouse button index.
+ */
+ public int getButtonIndex() {
+ return btnIndex;
+ }
+
+ /**
+ * Returns true if the mouse button was pressed, false if it was released.
+ *
+ * @return true if the mouse button was pressed, false if it was released.
+ */
+ public boolean isPressed() {
+ return pressed;
+ }
+
+ /**
+ * Returns true if the mouse button was released, false if it was pressed.
+ *
+ * @return true if the mouse button was released, false if it was pressed.
+ */
+ public boolean isReleased() {
+ return !pressed;
+ }
+
+ /**
+ * The X coordinate of the mouse when the event was generated.
+ * @return X coordinate of the mouse when the event was generated.
+ */
+ public int getX() {
+ return x;
+ }
+
+ /**
+ * The Y coordinate of the mouse when the event was generated.
+ * @return Y coordinate of the mouse when the event was generated.
+ */
+ public int getY() {
+ return y;
+ }
+
+ @Override
+ public String toString(){
+ String str = "MouseButton(BTN="+btnIndex;
+ if (pressed){
+ return str + ", PRESSED)";
+ }else{
+ return str + ", RELEASED)";
+ }
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/event/MouseMotionEvent.java b/engine/src/core/com/jme3/input/event/MouseMotionEvent.java
new file mode 100644
index 0000000..7439ecc
--- /dev/null
+++ b/engine/src/core/com/jme3/input/event/MouseMotionEvent.java
@@ -0,0 +1,110 @@
+/*
+ * 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.input.event;
+
+/**
+ * Mouse movement event.
+ * <p>
+ * Movement events are only generated if the mouse is on-screen.
+ *
+ * @author Kirill Vainer
+ */
+public class MouseMotionEvent extends InputEvent {
+
+ private int x, y, dx, dy, wheel, deltaWheel;
+
+ public MouseMotionEvent(int x, int y, int dx, int dy, int wheel, int deltaWheel) {
+ this.x = x;
+ this.y = y;
+ this.dx = dx;
+ this.dy = dy;
+ this.wheel = wheel;
+ this.deltaWheel = deltaWheel;
+ }
+
+ /**
+ * The change in wheel rotation.
+ *
+ * @return change in wheel rotation.
+ */
+ public int getDeltaWheel() {
+ return deltaWheel;
+ }
+
+ /**
+ * The change in X coordinate
+ * @return change in X coordinate
+ */
+ public int getDX() {
+ return dx;
+ }
+
+ /**
+ * The change in Y coordinate
+ *
+ * @return change in Y coordinate
+ */
+ public int getDY() {
+ return dy;
+ }
+
+ /**
+ * Current mouse wheel value
+ * @return Current mouse wheel value
+ */
+ public int getWheel() {
+ return wheel;
+ }
+
+ /**
+ * Current X coordinate
+ * @return Current X coordinate
+ */
+ public int getX() {
+ return x;
+ }
+
+ /**
+ * Current Y coordinate
+ * @return Current Y coordinate
+ */
+ public int getY() {
+ return y;
+ }
+
+ @Override
+ public String toString(){
+ return "MouseMotion(X="+x+", Y="+y+", DX="+dx+", DY="+dy+")";
+ }
+
+}
diff --git a/engine/src/core/com/jme3/input/event/TouchEvent.java b/engine/src/core/com/jme3/input/event/TouchEvent.java
new file mode 100644
index 0000000..8834c85
--- /dev/null
+++ b/engine/src/core/com/jme3/input/event/TouchEvent.java
@@ -0,0 +1,209 @@
+/*
+ * 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.input.event;
+
+/**
+ * <code>TouchEvent</code> represents a single event from multi-touch input devices
+ * @author larynx
+ */
+public class TouchEvent extends InputEvent {
+
+ public enum Type {
+
+ /**
+ * Touch down event, fields: posX, posY, pressure
+ */
+ DOWN,
+ /**
+ * Move/Drag event, fields: posX, posY, deltaX, deltaY, pressure
+ */
+ MOVE,
+ /**
+ * Touch up event, fields: posX, posY, pressure
+ */
+ UP,
+ /**
+ * Virtual keyboard or hardware key event down, fields: keyCode, characters
+ */
+ KEY_DOWN,
+ /**
+ * Virtual keyboard or hardware key event up, fields: keyCode, characters
+ */
+ KEY_UP,
+ // Single finger gestures
+ FLING,
+ TAP,
+ DOUBLETAP,
+ LONGPRESSED,
+ // Two finger scale events
+ /**
+ * Two finger scale event start, fields: posX/posY = getFocusX/Y, scaleFactor, scaleSpan
+ */
+ SCALE_START,
+ /**
+ * Two finger scale event, fields: posX/posY = getFocusX/Y, scaleFactor, scaleSpan
+ */
+ SCALE_MOVE,
+ /**
+ * Two finger scale event end, fields: posX/posY = getFocusX/Y, scaleFactor, scaleSpan
+ */
+ SCALE_END,
+ /**
+ * Scroll event
+ */
+ SCROLL,
+ /**
+ * The user has performed a down MotionEvent and not performed a move or up yet. This event is commonly used to provide visual feedback to the user to let them know that their action has been recognized i.e. highlight an element.
+ */
+ SHOWPRESS,
+ // Others
+ OUTSIDE,
+ IDLE
+ }
+ private Type type = Type.IDLE;
+ private int pointerId;
+ private float posX;
+ private float posY;
+ private float deltaX;
+ private float deltaY;
+ private float pressure;
+
+ // Used only with KEY* events
+ private int keyCode;
+ private String characters;
+ // Used only with SCALE* events
+ private float scaleFactor;
+ private float scaleSpan;
+
+ public TouchEvent() {
+ set(Type.IDLE, 0f, 0f, 0f, 0f);
+ }
+
+ public TouchEvent(Type type, float x, float y, float deltax, float deltay) {
+ set(type, x, y, deltax, deltay);
+ }
+
+ public void set(Type type) {
+ set(type, 0f, 0f, 0f, 0f);
+ }
+
+ public void set(Type type, float x, float y, float deltax, float deltay) {
+ this.type = type;
+ this.posX = x;
+ this.posY = y;
+ this.deltaX = deltax;
+ this.deltaY = deltay;
+ pointerId = 0;
+ pressure = 0;
+ keyCode = 0;
+ scaleFactor = 0;
+ scaleSpan = 0;
+ characters = "";
+ consumed = false;
+ }
+
+ /**
+ * Returns the type of touch event.
+ *
+ * @return the type of touch event.
+ */
+ public Type getType() {
+ return type;
+ }
+
+ public float getX() {
+ return posX;
+ }
+
+ public float getY() {
+ return posY;
+ }
+
+ public float getDeltaX() {
+ return deltaX;
+ }
+
+ public float getDeltaY() {
+ return deltaY;
+ }
+
+ public float getPressure()
+ {
+ return pressure;
+ }
+
+ public void setPressure(float pressure)
+ {
+ this.pressure = pressure;
+ }
+
+ public int getPointerId()
+ {
+ return pointerId;
+ }
+
+ public void setPointerId(int pointerId) {
+ this.pointerId = pointerId;
+ }
+
+ public int getKeyCode() {
+ return keyCode;
+ }
+
+ public void setKeyCode(int keyCode) {
+ this.keyCode = keyCode;
+ }
+
+ public String getCharacters() {
+ return characters;
+ }
+
+ public void setCharacters(String characters) {
+ this.characters = characters;
+ }
+
+ public float getScaleFactor() {
+ return scaleFactor;
+ }
+
+ public void setScaleFactor(float scaleFactor) {
+ this.scaleFactor = scaleFactor;
+ }
+
+ public float getScaleSpan() {
+ return scaleSpan;
+ }
+
+ public void setScaleSpan(float scaleSpan) {
+ this.scaleSpan = scaleSpan;
+ }
+}
diff --git a/engine/src/core/com/jme3/input/event/package.html b/engine/src/core/com/jme3/input/event/package.html
new file mode 100644
index 0000000..eaa96fb
--- /dev/null
+++ b/engine/src/core/com/jme3/input/event/package.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+<title></title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body>
+
+The <code>com.jme3.input.event</code> package contains low-level input events.
+
+</body>
+</html>
diff --git a/engine/src/core/com/jme3/input/package.html b/engine/src/core/com/jme3/input/package.html
new file mode 100644
index 0000000..998a22a
--- /dev/null
+++ b/engine/src/core/com/jme3/input/package.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+<title></title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body>
+
+The <code>com.jme3.input</code> package is used for all input handling in
+jMonkeyEngine. User code should use the {@link com.jme3.input.InputManager} to register
+for and receive input events. The <code>InputManager</code> can be
+retrieved for an application by using {@link com.jme3.app.Application#getInputManager()}.
+
+<h3>Usage</h3>
+
+<p>
+Using ActionListener:<br>
+<code>
+// Retrieve an input manager for the application "app"<br>
+InputManager inputManager = app.getInputManager();<br>
+<br>
+// Adds a new mapping "PrintHello" that will be invoked when the Return/Enter key is pressed<br>
+inputManager.addMapping("PrintHello", new KeyTrigger(KeyInput.KEY_RETURN));<br>
+// Adds a new ActionListener to get an event when enter is pressed.<br>
+inputManager.addListener(new ActionListener() {<br>
+ public void onAction(String name, boolean isPressed, float tpf) {<br>
+ // Only invoke the event when the mapping is "PrintHello" <br>
+ // and isPressed is true, meaning it was a key press and not release.<br>
+ if (name.equals("PrintHello") && isPressed){<br>
+ System.out.println("Hello!");<br>
+ }<br>
+ }<br>
+}, "PrintHello");<br>
+</code>
+
+</body>
+</html>