diff options
Diffstat (limited to 'engine/src/core/com/jme3/input')
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; + /** + * @ 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> |