Adding support for defining external (or internal in Android's case) sensors. This is still a work in progress. Major task yet to complete is defining the coordinate system to return the sensor data. 3 sensor types are defined: Magnetic, Accelerometer, Orientation. Right now the sensor data is returned in device coordinates for Magnetic and Acceleration, and World (Earth) coordinates for Orientation. Sensors use the Input Manager to define triggers and listeners like all other input types. Only Android has an implementation for SensorInput at this time. See forum post http://jmonkeyengine.org/groups/android/forum/topic/creating-engine-support-for-android-sensor-input/ for details of the operation and current status.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9610 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
pot..om 12 years ago
parent 1fbc0cc406
commit bb631ab13a
  1. 22
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 584
      engine/src/android/com/jme3/input/android/AndroidSensorInput.java
  3. 15
      engine/src/android/com/jme3/system/android/OGLESContext.java
  4. 10
      engine/src/core/com/jme3/app/Application.java
  5. 59
      engine/src/core/com/jme3/input/InputManager.java
  6. 7
      engine/src/core/com/jme3/input/RawInputListener.java
  7. 146
      engine/src/core/com/jme3/input/SensorInput.java
  8. 58
      engine/src/core/com/jme3/input/controls/MotionSensorListener.java
  9. 83
      engine/src/core/com/jme3/input/controls/SensorTrigger.java
  10. 118
      engine/src/core/com/jme3/input/event/MotionSensorEvent.java
  11. 6
      engine/src/core/com/jme3/system/JmeContext.java
  12. 5
      engine/src/core/com/jme3/system/NullContext.java
  13. 5
      engine/src/desktop/com/jme3/system/awt/AwtPanelsContext.java
  14. 5
      engine/src/lwjgl/com/jme3/system/lwjgl/LwjglAbstractDisplay.java
  15. 5
      engine/src/lwjgl/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java
  16. 3
      engine/src/niftygui/com/jme3/niftygui/InputSystemJme.java
  17. 3
      engine/src/test/jme3test/gui/TestBitmapFont.java
  18. 2
      engine/src/test/jme3test/gui/TestSoftwareMouse.java

@ -15,7 +15,9 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.jme3.audio.AudioRenderer; import com.jme3.audio.AudioRenderer;
import com.jme3.audio.android.AndroidAudioRenderer; import com.jme3.audio.android.AndroidAudioRenderer;
import com.jme3.input.SensorInput;
import com.jme3.input.TouchInput; import com.jme3.input.TouchInput;
import com.jme3.input.android.AndroidSensorInput;
import com.jme3.input.controls.TouchListener; import com.jme3.input.controls.TouchListener;
import com.jme3.input.controls.TouchTrigger; import com.jme3.input.controls.TouchTrigger;
import com.jme3.input.event.TouchEvent; import com.jme3.input.event.TouchEvent;
@ -257,6 +259,16 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
renderer.resumeAll(); renderer.resumeAll();
} }
} }
//resume the sensors
if (app.getInputManager() != null) {
SensorInput sensorInput = app.getInputManager().getSensorInput();
if (sensorInput != null) {
logger.log(Level.INFO, "resume: {0}", sensorInput.getClass().getSimpleName());
if (sensorInput instanceof AndroidSensorInput) {
((AndroidSensorInput)sensorInput).resumeSensors();
}
}
}
} }
isGLThreadPaused = false; isGLThreadPaused = false;
@ -280,6 +292,16 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
renderer.pauseAll(); renderer.pauseAll();
} }
} }
//pause the sensors
if (app.getInputManager() != null) {
SensorInput sensorInput = app.getInputManager().getSensorInput();
if (sensorInput != null) {
logger.log(Level.INFO, "pause: {0}", sensorInput.getClass().getSimpleName());
if (sensorInput instanceof AndroidSensorInput) {
((AndroidSensorInput)sensorInput).resumeSensors();
}
}
}
} }
isGLThreadPaused = true; isGLThreadPaused = true;
logger.info("onPause"); logger.info("onPause");

@ -0,0 +1,584 @@
/*
* 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.android;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
import com.jme3.input.RawInputListener;
import com.jme3.input.SensorInput;
import com.jme3.input.event.MotionSensorEvent;
import com.jme3.math.Vector3f;
import com.jme3.system.android.JmeAndroidSystem;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Android specific implementation of SensorInput.
*
* @author iwgeric
*/
public class AndroidSensorInput implements SensorInput, SensorEventListener {
private final static Logger logger = Logger.getLogger(AndroidSensorInput.class.getName());
private SensorManager sensorManager = null;
private RawInputListener listener = null;
private Map<Integer, SensorData> sensors = new HashMap<Integer, SensorData>();
private boolean initialized = false;
private WindowManager window;
private Display disp;
private final float[] curAccValues = new float[3];
private final float[] curMagValues = new float[3];
private final float[] curInclination = new float[9];
private final float[] curRotation = new float[9];
private final float[] rotatedRotation = new float[9];
private final ArrayList<MotionSensorEvent> eventQueue = new ArrayList<MotionSensorEvent>();
/**
* Internal class to enclose data for each sensor.
*/
private class SensorData {
int androidSensorType = -1;
int androidSensorSpeed = SensorManager.SENSOR_DELAY_UI;
Sensor sensor = null;
Vector3f lastValues = new Vector3f();
float minChangePercent = 0f;
boolean enabled = false;
boolean paused = false;
public SensorData(int androidSensorType, Sensor sensor) {
this.androidSensorType = androidSensorType;
this.sensor = sensor;
}
}
/**
* Pauses the active sensors to save battery. Mostly used internally so that
* the sensors can be deactivated while the game Activity is
* in the background to save battery life
*/
public void pauseSensors() {
for (Entry<Integer, SensorData> entry : sensors.entrySet()) {
SensorData sensorData = entry.getValue();
if (sensorData.sensor != null) {
unRegisterListener(entry.getKey());
sensorData.paused = true;
}
}
}
/**
* Resumes paused sensors. Mostly used internally so that
* the sensors can be reactivated when the game Activity is
* placed back onto the forefront.
*/
public void resumeSensors() {
for (Entry<Integer, SensorData> entry : sensors.entrySet()) {
SensorData sensorData = entry.getValue();
if (sensorData.sensor != null && sensorData.paused) {
if (registerListener(entry.getKey())) {
sensorData.paused = false;
}
}
}
}
/**
* Used internally by the context to reset the Sensor Manager on device rotations.
* Necessary because a new Activity is created on a device rotation, so the
* Sensor Manager needs to be reset with the new Activity.
*/
public void resetSensorManager() {
initSensorManager();
}
private void initSensorManager() {
window = JmeAndroidSystem.getActivity().getWindowManager();
disp = window.getDefaultDisplay();
sensorManager = (SensorManager) JmeAndroidSystem.getActivity().getSystemService(Context.SENSOR_SERVICE);
initSensor(SensorInput.SENSOR_TYPE_MAGNETIC_FIELD);
initSensor(SensorInput.SENSOR_TYPE_ACCELEROMETER);
initSensor(SensorInput.SENSOR_TYPE_ORIENTATION);
}
private boolean initSensor(int sensorType) {
boolean result = false;
boolean previouslyActive = false;
SensorData sensorData = sensors.get((Integer)sensorType);
if (sensorData != null) {
if (sensorData.enabled) {
previouslyActive = true;
}
unRegisterListener(sensorType);
} else {
sensorData = new SensorData(sensorType, null);
sensors.put(sensorType, sensorData);
}
switch (sensorType) {
case SensorInput.SENSOR_TYPE_MAGNETIC_FIELD:
sensorData.androidSensorType = Sensor.TYPE_MAGNETIC_FIELD;
sensorData.sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
break;
case SensorInput.SENSOR_TYPE_ACCELEROMETER:
sensorData.androidSensorType = Sensor.TYPE_ACCELEROMETER;
sensorData.sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
break;
case SensorInput.SENSOR_TYPE_ORIENTATION:
sensorData.androidSensorType = Sensor.TYPE_ORIENTATION;
//Orientation is not a sensor anymore but rather a call to SensorMangaer
// to get the current orientation based on the Magnetic and Accelerometer sensor data
sensorData.sensor = null;
break;
default:
throw new IllegalArgumentException("Invalid Sensor Type.");
}
if (sensorData.sensor != null || sensorType == SensorInput.SENSOR_TYPE_ORIENTATION) {
logger.log(Level.INFO, "Sensor Type {0} found.", sensorType);
if (previouslyActive) {
logger.log(Level.INFO, "Reactivating Sensor Type {0}.", sensorType);
registerListener(sensorType);
}
result = true;
}
return result;
}
private boolean registerListener(int sensorType) {
SensorData sensorData = sensors.get((Integer)sensorType);
if (sensorData != null) {
if (sensorData.enabled) {
logger.log(Level.INFO, "Sensor Already Active: SensorType: {0}, active: {1}",
new Object[]{sensorType, sensorData.enabled});
return true;
}
if (sensorData.sensor != null) {
if (sensorManager.registerListener(this, sensorData.sensor, sensorData.androidSensorSpeed)) {
sensorData.enabled = true;
logger.log(Level.INFO, "SensorType: {0}, active: {1}",
new Object[]{sensorType, sensorData.enabled});
logger.log(Level.INFO, "Sensor Type {0} activated.", sensorType);
return true;
} else {
sensorData.enabled = false;
logger.log(Level.INFO, "Sensor Type {0} activation failed.", sensorType);
}
} else if (sensorType == SensorInput.SENSOR_TYPE_ORIENTATION) {
logger.log(Level.INFO, "Sensor is Orientation");
if (registerListener(SensorInput.SENSOR_TYPE_MAGNETIC_FIELD) && registerListener(SensorInput.SENSOR_TYPE_ACCELEROMETER)) {
sensorData.enabled = true;
logger.log(Level.INFO, "Magnetic and Acceleration Sensors Registered and Orientation Sensor being simulated.");
return true;
}
}
sensorData.lastValues = null;
}
return false;
}
private void unRegisterListener(int sensorType) {
SensorData sensorData = sensors.get((Integer)sensorType);
if (sensorData != null) {
if (sensorData.sensor != null) {
sensorManager.unregisterListener(this, sensorData.sensor);
} else if (sensorType == SensorInput.SENSOR_TYPE_ORIENTATION) {
logger.log(Level.INFO, "Mangetic and Acceleration Sensors are being deactivated with Orientation Sensor.");
unRegisterListener(SensorInput.SENSOR_TYPE_MAGNETIC_FIELD);
unRegisterListener(SensorInput.SENSOR_TYPE_ACCELEROMETER);
}
sensorData.enabled = false;
logger.log(Level.INFO, "SensorType: {0}, active: {1}",
new Object[]{sensorType, sensorData.enabled});
logger.log(Level.INFO, "Sensor Type {0} deactivated.", sensorType);
}
}
/*
* Android remapCoordinateSystem from the Android docs
* remapCoordinateSystem(float[] inR, int X, int Y, float[] outR)
*
* @param inR the rotation matrix to be transformed. Usually it is the matrix
* returned by getRotationMatrix(float[], float[], float[], float[]).
*
* @param outR the transformed rotation matrix. inR and outR can be the same
* array, but it is not recommended for performance reason.
*
* X defines on which world axis and direction the X axis of the device is mapped.
* Y defines on which world axis and direction the Y axis of the device is mapped.
*
* @return True if successful
*/
private boolean remapCoordinates(float[] inR, float[] outR) {
int xDir = SensorManager.AXIS_X;
int yDir = SensorManager.AXIS_Y;
// logger.log(Level.INFO, "Screen Rotation: {0}", getScreenRotation());
if (getScreenRotation() == Surface.ROTATION_0) {
xDir = SensorManager.AXIS_X;
yDir = SensorManager.AXIS_Y;
}
if (getScreenRotation() == Surface.ROTATION_90) {
xDir = SensorManager.AXIS_MINUS_Y;
yDir = SensorManager.AXIS_MINUS_X;
}
if (getScreenRotation() == Surface.ROTATION_180) {
xDir = SensorManager.AXIS_MINUS_X;
yDir = SensorManager.AXIS_MINUS_Y;
}
if (getScreenRotation() == Surface.ROTATION_270) {
xDir = SensorManager.AXIS_Y;
yDir = SensorManager.AXIS_MINUS_X;
}
return SensorManager.remapCoordinateSystem(inR, xDir, yDir, outR);
}
/**
* Returns the current device rotation.
* Surface.ROTATION_0 = device in natural default rotation
* Surface.ROTATION_90 = device in rotated 90deg counterclockwise
* Surface.ROTATION_180 = device in rotated 180deg counterclockwise
* Surface.ROTATION_270 = device in rotated 270deg counterclockwise
*
* When the Manifest locks the orientation, this value will not change during
* gametime, but if the orientation of the screen is based off the sensor,
* this value will change as the device is rotated.
* @return Current device rotation amount
*/
private int getScreenRotation() {
return disp.getRotation();
}
private Integer getAndroidSensorSpeed(int sensorInputSpeed) {
Integer androidSpeed = null;
switch (sensorInputSpeed) {
case SensorInput.SENSOR_SPEED_SLOW:
androidSpeed = SensorManager.SENSOR_DELAY_UI;
break;
case SensorInput.SENSOR_SPEED_MEDIUM:
androidSpeed = SensorManager.SENSOR_DELAY_NORMAL;
break;
case SensorInput.SENSOR_SPEED_FAST:
androidSpeed = SensorManager.SENSOR_DELAY_GAME;
break;
default:
throw new IllegalArgumentException("Invalid Sensor Speed.");
}
return androidSpeed;
}
/**
* Calculates the device orientation based off the data recieved from the
* Acceleration Sensor and Mangetic Field sensor
* Values are returned relative to the Earth.
*
* From the Android Doc
*
* Computes the device's orientation based on the rotation matrix. When it returns, the array values is filled with the result:
* values[0]: azimuth, rotation around the Z axis.
* values[1]: pitch, rotation around the X axis.
* values[2]: roll, rotation around the Y axis.
*
* The reference coordinate-system used is different from the world
* coordinate-system defined for the rotation matrix:
* X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points West).
* Y is tangential to the ground at the device's current location and points towards the magnetic North Pole.
* Z points towards the center of the Earth and is perpendicular to the ground.
*
* @return
*/
private boolean updateOrientation() {
SensorData sensorData;
sensorData = sensors.get((Integer)SensorInput.SENSOR_TYPE_MAGNETIC_FIELD);
if (sensorData == null || !sensorData.enabled) {
return false;
}
sensorData = sensors.get((Integer)SensorInput.SENSOR_TYPE_ACCELEROMETER);
if (sensorData == null || !sensorData.enabled) {
return false;
}
sensorData = sensors.get((Integer)SensorInput.SENSOR_TYPE_ORIENTATION);
if (sensorData != null && sensorData.enabled) {
// create new copies so they don't get updated during the getRotationMatrix call
final float[] accValues = new float[3];
final float[] magValues = new float[3];
synchronized(curAccValues) {
accValues[0] = curAccValues[0];
accValues[1] = curAccValues[1];
accValues[2] = curAccValues[2];
}
synchronized(curMagValues) {
magValues[0] = curMagValues[0];
magValues[1] = curMagValues[1];
magValues[2] = curMagValues[2];
}
if (SensorManager.getRotationMatrix(curRotation, curInclination, accValues, magValues)) {
final float [] orientValues = new float[3];
if (remapCoordinates(curRotation, rotatedRotation)) {
SensorManager.getOrientation(rotatedRotation, orientValues);
// logger.log(Level.INFO, "Orientation Values: {0}, {1}, {2}",
// new Object[]{orientValues[0], orientValues[1], orientValues[2]});
updateEventQueue(SensorInput.SENSOR_TYPE_ORIENTATION,
orientValues[0], orientValues[1], orientValues[2], System.nanoTime());
return true;
} else {
//logger.log(Level.INFO, "remapCoordinateSystem failed");
}
} else {
//logger.log(Level.INFO, "getRotationMatrix returned false");
}
} else {
if (!sensorData.enabled) {
//logger.log(Level.INFO, "Orientation is not active");
}
}
return false;
}
private void updateEventQueue(int sensorType, float x, float y, float z, long timestamp) {
// logger.log(Level.INFO, "updateEventQueue for {0}: values: {1}, {2}, {3}",
// new Object[]{sensorType, x, y, z});
float lastX, lastY, lastZ;
float dX, dY, dZ;
SensorData sensorData = sensors.get((Integer)sensorType);
if (sensorData != null) {
// if lastValues is null, then this is the first scan after a registerListener
// so set lastValues to the current values so dX,dY,dZ are zero this pass
if (sensorData.lastValues == null) {
sensorData.lastValues = new Vector3f(x, y, z);
}
lastX = sensorData.lastValues.x;
lastY = sensorData.lastValues.y;
lastZ = sensorData.lastValues.z;
dX = x - lastX;
dY = y - lastY;
dZ = z - lastZ;
if (dX != 0 && dY != 0 && dZ != 0) {
MotionSensorEvent motionEvent = new MotionSensorEvent(sensorType, x, y, z, dX, dY, dZ);
motionEvent.setTime(timestamp);
sensorData.lastValues.x = x;
sensorData.lastValues.y = y;
sensorData.lastValues.z = z;
synchronized (eventQueue){
eventQueue.add(motionEvent);
}
} else {
//logger.log(Level.INFO, "No change in Sensor Data for: {0}", sensorType);
}
} else {
//logger.log(Level.INFO, "Sensor Data is null for: {0}", sensorType);
}
}
// Start of methods from SensorInput
public boolean isEnabled(int sensorType) {
logger.log(Level.INFO, "Checking isEnabled for type: {0}", sensorType);
SensorData sensorData = sensors.get((Integer)sensorType);
if (sensorData == null) {
// logger.log(Level.INFO, "sensor data is null, sensors size is: {0}", sensors.size());
return false;
}
return sensors.get((Integer)sensorType).enabled;
}
public void setEnable(boolean enable) {
for (Integer sensorType: sensors.keySet()) {
setEnable(sensorType, enable);
}
}
public void setEnable(int sensorType, boolean enable) {
logger.log(Level.INFO, "Setting Sensor {0} Enable to {1}",
new Object[]{sensorType, enable});
if (enable) {
// registerListener(sensorType, true);
registerListener(sensorType);
} else {
unRegisterListener(sensorType);
}
}
public void setSensorFrequency(int sensorType, int updateSpeed) {
SensorData sensorData = sensors.get((Integer)sensorType);
if (sensorData == null || sensorData.enabled) {
throw new IllegalArgumentException("Sensor Type Not Configured or is already active.");
}
sensorData.androidSensorSpeed = getAndroidSensorSpeed(updateSpeed);
}
public Set<Integer> getSensorTypes() {
return Collections.unmodifiableSet(sensors.keySet());
}
public void setSensorMinChange(int sensorType, float minChangePercent) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void initialize() {
logger.log(Level.INFO, "Doing Initialize.");
initSensorManager();
initialized = true;
}
public void update() {
updateOrientation();
synchronized (eventQueue){
// flush events to listener
for (int i = 0; i < eventQueue.size(); i++){
listener.onMotionSensorEvent(eventQueue.get(i));
}
eventQueue.clear();
}
}
public void destroy() {
for (Integer i: sensors.keySet()) {
unRegisterListener(i);
}
logger.log(Level.INFO, "Doing Destroy");
if (sensorManager != null) {
sensorManager.unregisterListener(this);
}
sensors.clear();
eventQueue.clear();
}
public boolean isInitialized() {
return initialized;
}
public void setInputListener(RawInputListener listener) {
this.listener = listener;
}
public long getInputTimeNanos() {
return System.nanoTime();
}
// End of methods from SensorInput
// Start of methods from SensorEventListener
public void onSensorChanged(SensorEvent se) {
// logger.log(Level.INFO, "onSensorChanged for {0}: values: {1}, {2}, {3}",
// new Object[]{se.sensor.getType(), se.values[0], se.values[1], se.values[2]});
SensorData sensorData;
int sensorType;
for (Entry<Integer, SensorData> entry : sensors.entrySet()) {
// if (entry.getValue().sensor == null) {
// logger.log(Level.INFO, "Sensor is null for SensorType: {0}", entry.getKey());
// }
if (entry.getValue().sensor != null && entry.getValue().sensor.equals(se.sensor)) {
sensorType = entry.getKey();
sensorData = entry.getValue();
updateEventQueue(sensorType, se.values[0], se.values[1], se.values[2], se.timestamp);
if (sensorType == SensorInput.SENSOR_TYPE_MAGNETIC_FIELD) {
synchronized(curMagValues) {
curMagValues[0] = se.values[0];
curMagValues[1] = se.values[1];
curMagValues[2] = se.values[2];
}
}
if (sensorType == SensorInput.SENSOR_TYPE_ACCELEROMETER) {
synchronized(curAccValues) {
curAccValues[0] = se.values[0];
curAccValues[1] = se.values[1];
curAccValues[2] = se.values[2];
}
}
break;
}
}
}
public void onAccuracyChanged(Sensor sensor, int i) {
logger.log(Level.INFO, "onAccuracyChanged for {0}: accuracy: {1}",
new Object[]{sensor.toString(), i});
}
// End of methods from SensorEventListener
}

@ -32,7 +32,6 @@
package com.jme3.system.android; package com.jme3.system.android;
import com.jme3.renderer.android.AndroidGLSurfaceView; import com.jme3.renderer.android.AndroidGLSurfaceView;
import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView;
@ -44,6 +43,7 @@ import android.widget.EditText;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import com.jme3.input.*; import com.jme3.input.*;
import com.jme3.input.android.AndroidInput; import com.jme3.input.android.AndroidInput;
import com.jme3.input.android.AndroidSensorInput;
import com.jme3.input.controls.SoftTextDialogInputListener; import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput; import com.jme3.input.dummy.DummyMouseInput;
@ -75,6 +75,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
protected SystemListener listener; protected SystemListener listener;
protected boolean autoFlush = true; protected boolean autoFlush = true;
protected AndroidInput androidInput; protected AndroidInput androidInput;
protected AndroidSensorInput androidSensorInput;
protected AndroidGLSurfaceView view; protected AndroidGLSurfaceView view;
protected int minFrameDuration = 0; // No FPS cap protected int minFrameDuration = 0; // No FPS cap
/** /**
@ -114,6 +115,13 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
} else { } else {
androidInput.setView(view); androidInput.setView(view);
} }
if (androidSensorInput == null) {
logger.log(Level.INFO, "Creating New SensorInput");
androidSensorInput = new AndroidSensorInput();
} else {
logger.log(Level.INFO, "Resetting SensorInput");
androidSensorInput.resetSensorManager();
}
if (configType == ConfigType.LEGACY) { if (configType == ConfigType.LEGACY) {
// Hardcoded egl setup // Hardcoded egl setup
clientOpenGLESVersion = 2; clientOpenGLESVersion = 2;
@ -277,6 +285,11 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
return androidInput; return androidInput;
} }
@Override
public SensorInput getSensorInput() {
return androidSensorInput;
}
@Override @Override
public Timer getTimer() { public Timer getTimer() {
return timer; return timer;

@ -90,6 +90,7 @@ public class Application implements SystemListener {
protected KeyInput keyInput; protected KeyInput keyInput;
protected JoyInput joyInput; protected JoyInput joyInput;
protected TouchInput touchInput; protected TouchInput touchInput;
protected SensorInput sensorInput;
protected InputManager inputManager; protected InputManager inputManager;
protected AppStateManager stateManager; protected AppStateManager stateManager;
@ -285,7 +286,11 @@ public class Application implements SystemListener {
joyInput.initialize(); joyInput.initialize();
} }
inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput); sensorInput = context.getSensorInput();
if (sensorInput != null)
sensorInput.initialize();
inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput, sensorInput);
} }
private void initStateManager(){ private void initStateManager(){
@ -626,6 +631,9 @@ public class Application implements SystemListener {
if (touchInput != null) if (touchInput != null)
touchInput.destroy(); touchInput.destroy();
if (sensorInput != null)
sensorInput.destroy();
inputManager = null; inputManager = null;
} }

@ -88,6 +88,7 @@ public class InputManager implements RawInputListener {
private final MouseInput mouse; private final MouseInput mouse;
private final JoyInput joystick; private final JoyInput joystick;
private final TouchInput touch; private final TouchInput touch;
private final SensorInput sensor;
private float frameTPF; private float frameTPF;
private long lastLastUpdateTime = 0; private long lastLastUpdateTime = 0;
private long lastUpdateTime = 0; private long lastUpdateTime = 0;
@ -127,9 +128,10 @@ public class InputManager implements RawInputListener {
* @param keys * @param keys
* @param joystick * @param joystick
* @param touch * @param touch
* @param sensor
* @throws IllegalArgumentException If either mouseInput or keyInput are null. * @throws IllegalArgumentException If either mouseInput or keyInput are null.
*/ */
public InputManager(MouseInput mouse, KeyInput keys, JoyInput joystick, TouchInput touch) { public InputManager(MouseInput mouse, KeyInput keys, JoyInput joystick, TouchInput touch, SensorInput sensor) {
if (keys == null || mouse == null) { if (keys == null || mouse == null) {
throw new NullPointerException("Mouse or keyboard cannot be null"); throw new NullPointerException("Mouse or keyboard cannot be null");
} }
@ -138,6 +140,7 @@ public class InputManager implements RawInputListener {
this.mouse = mouse; this.mouse = mouse;
this.joystick = joystick; this.joystick = joystick;
this.touch = touch; this.touch = touch;
this.sensor = sensor;
keys.setInputListener(this); keys.setInputListener(this);
mouse.setInputListener(this); mouse.setInputListener(this);
@ -148,6 +151,9 @@ public class InputManager implements RawInputListener {
if (touch != null) { if (touch != null) {
touch.setInputListener(this); touch.setInputListener(this);
} }
if (sensor != null) {
sensor.setInputListener(this);
}
firstTime = keys.getInputTimeNanos(); firstTime = keys.getInputTimeNanos();
} }
@ -442,6 +448,50 @@ public class InputManager implements RawInputListener {
inputQueue.add(evt); inputQueue.add(evt);
} }
private void onMotionSensorEventQueued(MotionSensorEvent evt) {
int hash = SensorTrigger.sensorHash(evt.getSensorType());
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 MotionSensorListener) {
((MotionSensorListener) listener).onMotionSensorChange(mapping.name, evt.getSensorType(), evt.getX(), evt.getY(), evt.getZ(), evt.getDX(), evt.getDY(), evt.getDZ());
}
}
}
}
/**
* Callback from RawInputListener. Do not use.
*/
public void onMotionSensorEvent(MotionSensorEvent evt) {
if (!eventsPermitted) {
throw new UnsupportedOperationException("SensorInput has raised an event at an illegal time.");
}
inputQueue.add(evt);
}
/**
* Returns the SensorInput implementation. Use this as an entry point to
* enable and disable various sensors as well as setting other sensor settings.
* @return The SensorInput implementation.
*/
public SensorInput getSensorInput() {
return sensor;
}
/** /**
* Set the deadzone for joystick axes. * Set the deadzone for joystick axes.
* *
@ -784,6 +834,8 @@ public class InputManager implements RawInputListener {
listener.onJoyButtonEvent((JoyButtonEvent) event); listener.onJoyButtonEvent((JoyButtonEvent) event);
} else if (event instanceof TouchEvent) { } else if (event instanceof TouchEvent) {
listener.onTouchEvent((TouchEvent) event); listener.onTouchEvent((TouchEvent) event);
} else if (event instanceof MotionSensorEvent) {
listener.onMotionSensorEvent((MotionSensorEvent) event);
} else { } else {
assert false; assert false;
} }
@ -810,6 +862,8 @@ public class InputManager implements RawInputListener {
onJoyButtonEventQueued((JoyButtonEvent) event); onJoyButtonEventQueued((JoyButtonEvent) event);
} else if (event instanceof TouchEvent) { } else if (event instanceof TouchEvent) {
onTouchEventQueued((TouchEvent) event); onTouchEventQueued((TouchEvent) event);
} else if (event instanceof MotionSensorEvent) {
onMotionSensorEventQueued((MotionSensorEvent) event);
} else { } else {
assert false; assert false;
} }
@ -850,6 +904,9 @@ public class InputManager implements RawInputListener {
if (touch != null) { if (touch != null) {
touch.update(); touch.update();
} }
if (sensor != null) {
sensor.update();
}
eventsPermitted = false; eventsPermitted = false;

@ -96,4 +96,11 @@ public interface RawInputListener {
* @param evt * @param evt
*/ */
public void onTouchEvent(TouchEvent evt); public void onTouchEvent(TouchEvent evt);
/**
* Invoked on motion sensor events.
*
* @param evt
*/
public void onMotionSensorEvent(MotionSensorEvent evt);
} }

@ -0,0 +1,146 @@
/*
* 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 java.util.Set;
/**
* A specific API for interfacing with sensors.
*
* In order to conserve battery power for handheld devices, sensors must be
* enabled before data will be sent. Use the setEnable method to enable or disable
* the sensors.
*
* Sensor speed can also be set. Constants in this class are used so that each
* platform implementation can decide what absolute update rate to use. Use the
* setSensorFrequency method to set the desired update rate.
*
* In order to minimize the amount of data sent to the application, there is a
* method available to set how much change is required between sensor readings
* before the new updated data is sent. Use the setSensorMinChange method to set
* a minimum data change percentage (percentage of max sensor range). Data will
* not be sent to the application until the data has changed by this amount.
*
*
*
*
*
* @author iwgeric
*/
public interface SensorInput extends Input {
/**
* Orientation Sensor. Values returned in the onMotionSensorChanged event
* are in radians.
*/
public static final int SENSOR_TYPE_ORIENTATION = 0;
/**
* Accelerometer Sensor. Values returned in the onMotionSensorChanged event
* are in m/s^2. Values include gravity. To get true device acceleration,
* gravity must be removed.
*/
public static final int SENSOR_TYPE_ACCELEROMETER = 1;
/**
* Magnetic Field Sensor. Values returned in the onMotionSensorChanged event
* are in micro-Tesla (uT).
*/
public static final int SENSOR_TYPE_MAGNETIC_FIELD = 2;
/**
* Slowest Sensor Update Speed
*/
public static final int SENSOR_SPEED_SLOW = 0;
/**
* Medium Sensor Update Speed
*/
public static final int SENSOR_SPEED_MEDIUM = 1;
/**
* Fastest Sensor Update Speed
*/
public static final int SENSOR_SPEED_FAST = 2;
/**
* Returns whether a sensor is enabled or not.
*
* @param sensorType The sensor type.
* @return whether a sensor is enabled or not.
*/
public boolean isEnabled(int sensorType);
/**
* Sets enable/disable for a specific sensor type.
*
* @param sensorType The sensor type.
* @param enable True to enable, False to disable.
*/
public void setEnable(int sensorType, boolean enable);
/**
* Sets enable/disable for all sensor types.
*
* @param enable True to enable, False to disable.
*/
public void setEnable(boolean enable);
/**
* Returns a list of available sensor types.
*
* @return a list of available sensor types.
*/
public Set<Integer> getSensorTypes();
/**
* Set the minimum amount of change that is required before an event
* is created for the sensor. minChangePercent is defined as a percentage
* of the maximum sensor range.
*
* @param sensorType The sensor type.
* @param minChangePercent Percentage of changed required before creating an event.
*/
public void setSensorMinChange(int sensorType, float minChangePercent);
/**
* Set the update frequency for the sensor. Use the defined constants in
* SensorInput for setting the speed becuase the actual update frequency is
* platform dependant.
*
* @param sensorType The sensor type.
* @param updateSpeed Target update speed as a constant (do not use absolute values)
*/
public void setSensorFrequency(int sensorType, int updateSpeed);
}

@ -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;
import com.jme3.input.SensorInput;
/**
* <code>MotionSensorListener</code> is used to receive events from Sensors
*
* @author iwgeric
*/
public interface MotionSensorListener extends InputListener {
/**
* Called when data from a sensor has been updated.
*
* @param name The name of the mapping that was invoked
* @param sensorType Sensor Type value from {@link SensorInput}.
* @param x X component of the new sensor data based on the sensor type.
* @param y Y component of the new sensor data based on the sensor type.
* @param z Z component of the new sensor data based on the sensor type.
* @param dX Change in the x component from the last update.
* @param dY Change in the y component from the last update.
* @param dZ Change in the z component from the last update.
*/
public void onMotionSensorChange(String name, int sensorType, float x, float y, float z, float dX, float dY, float dZ);
}

@ -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.controls;
import com.jme3.input.SensorInput;
/**
* A <code>SensorTrigger</code> is used as a mapping to receive events
* from a sensor.
*
* @author Kirill Vainer
*/
public class SensorTrigger implements Trigger {
// private final SensorInput.Type sensorType;
private final int sensorType;
/**
* Create a new <code>SensorTrigger</code> to receive sensor events.
*
* @param Sensor Type. See {@link SensorInput}.
*/
// public SensorTrigger(SensorInput.Type sensorType) {
public SensorTrigger(int sensorType) {
// if (sensorType == null)
if (sensorType < 0 || sensorType > 255)
throw new IllegalArgumentException("Invalide Sensor Type");
this.sensorType = sensorType;
}
// public SensorInput.Type getSensorType() {
public int getSensorType() {
return sensorType;
}
public String getName() {
return sensorType + " Sensor";
}
// public static int sensorHash(SensorInput.Type sensorType){
public static int sensorHash(int sensorType){
// assert sensorType != null;
// return 256 | (sensorType.ordinal() & 0xff);
assert sensorType >= 0 && sensorType <= 255;
return 1024 | (sensorType & 0xff);
}
public int triggerHashCode() {
return sensorHash(sensorType);
}
}

@ -0,0 +1,118 @@
/*
* 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;
/**
* Motion Sensor event.
*
* @author iwgeric
*/
public class MotionSensorEvent extends InputEvent {
private int sensorType;
private float x, y, z, dX, dY, dZ;
public MotionSensorEvent(int sensorType, float x, float y, float z, float dX, float dY, float dZ) {
this.sensorType = sensorType;
this.x = x;
this.y = y;
this.z = z;
this.dX = dX;
this.dY = dY;
this.dZ = dZ;
}
/**
* Sensor Type
* @return Sensor Type
*/
public int getSensorType() {
return sensorType;
}
/**
* Current X coordinate
* @return Current X coordinate
*/
public float getX() {
return x;
}
/**
* Current Y coordinate
* @return Current Y coordinate
*/
public float getY() {
return y;
}
/**
* Current Z coordinate
* @return Current Z coordinate
*/
public float getZ() {
return z;
}
/**
* The change in X coordinate
* @return change in X coordinate
*/
public float getDX() {
return dX;
}
/**
* The change in Y coordinate
*
* @return change in Y coordinate
*/
public float getDY() {
return dY;
}
/**
* The change in Z coordinate
*
* @return change in Z coordinate
*/
public float getDZ() {
return dZ;
}
@Override
public String toString(){
return "MotionSensor(Type="+sensorType+", X="+x+", Y="+y+", Z="+z+", DX="+dX+", DY="+dY+", DZ="+dZ+")";
}
}

@ -35,6 +35,7 @@ package com.jme3.system;
import com.jme3.input.JoyInput; import com.jme3.input.JoyInput;
import com.jme3.input.KeyInput; import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput; import com.jme3.input.MouseInput;
import com.jme3.input.SensorInput;
import com.jme3.input.TouchInput; import com.jme3.input.TouchInput;
import com.jme3.renderer.Renderer; import com.jme3.renderer.Renderer;
@ -131,6 +132,11 @@ public interface JmeContext {
*/ */
public TouchInput getTouchInput(); public TouchInput getTouchInput();
/**
* @return Sensor device input implementation. May be null if not available.
*/
public SensorInput getSensorInput();
/** /**
* @return The timer for this context, or null if not created yet. * @return The timer for this context, or null if not created yet.
*/ */

@ -35,6 +35,7 @@ package com.jme3.system;
import com.jme3.input.JoyInput; import com.jme3.input.JoyInput;
import com.jme3.input.KeyInput; import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput; import com.jme3.input.MouseInput;
import com.jme3.input.SensorInput;
import com.jme3.input.TouchInput; import com.jme3.input.TouchInput;
import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput; import com.jme3.input.dummy.DummyMouseInput;
@ -178,6 +179,10 @@ public class NullContext implements JmeContext, Runnable {
return null; return null;
} }
public SensorInput getSensorInput() {
return null;
}
public void setTitle(String title) { public void setTitle(String title) {
} }

@ -3,6 +3,7 @@ package com.jme3.system.awt;
import com.jme3.input.JoyInput; import com.jme3.input.JoyInput;
import com.jme3.input.KeyInput; import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput; import com.jme3.input.MouseInput;
import com.jme3.input.SensorInput;
import com.jme3.input.TouchInput; import com.jme3.input.TouchInput;
import com.jme3.input.awt.AwtKeyInput; import com.jme3.input.awt.AwtKeyInput;
import com.jme3.input.awt.AwtMouseInput; import com.jme3.input.awt.AwtMouseInput;
@ -102,6 +103,10 @@ public class AwtPanelsContext implements JmeContext {
return null; return null;
} }
public SensorInput getSensorInput() {
return null;
}
public Timer getTimer() { public Timer getTimer() {
return actualContext.getTimer(); return actualContext.getTimer();
} }

@ -35,6 +35,7 @@ package com.jme3.system.lwjgl;
import com.jme3.input.JoyInput; import com.jme3.input.JoyInput;
import com.jme3.input.KeyInput; import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput; import com.jme3.input.MouseInput;
import com.jme3.input.SensorInput;
import com.jme3.input.TouchInput; import com.jme3.input.TouchInput;
import com.jme3.input.lwjgl.JInputJoyInput; import com.jme3.input.lwjgl.JInputJoyInput;
import com.jme3.input.lwjgl.LwjglKeyInput; import com.jme3.input.lwjgl.LwjglKeyInput;
@ -258,6 +259,10 @@ public abstract class LwjglAbstractDisplay extends LwjglContext implements Runna
return null; return null;
} }
public SensorInput getSensorInput() {
return null;
}
public void setAutoFlushFrames(boolean enabled){ public void setAutoFlushFrames(boolean enabled){
this.autoFlush = enabled; this.autoFlush = enabled;
} }

@ -35,6 +35,7 @@ package com.jme3.system.lwjgl;
import com.jme3.input.JoyInput; import com.jme3.input.JoyInput;
import com.jme3.input.KeyInput; import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput; import com.jme3.input.MouseInput;
import com.jme3.input.SensorInput;
import com.jme3.input.TouchInput; import com.jme3.input.TouchInput;
import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput; import com.jme3.input.dummy.DummyMouseInput;
@ -192,6 +193,10 @@ public class LwjglOffscreenBuffer extends LwjglContext implements Runnable {
return null; return null;
} }
public SensorInput getSensorInput() {
return null;
}
public void setTitle(String title) { public void setTitle(String title) {
} }

@ -216,6 +216,9 @@ public class InputSystemJme implements InputSystem, RawInputListener {
public void onJoyButtonEvent(JoyButtonEvent evt) { public void onJoyButtonEvent(JoyButtonEvent evt) {
} }
public void onMotionSensorEvent(MotionSensorEvent evt) {
}
public void onKeyEvent(KeyInputEvent evt) { public void onKeyEvent(KeyInputEvent evt) {
inputQueue.add(evt); inputQueue.add(evt);
} }

@ -129,6 +129,9 @@ public class TestBitmapFont extends SimpleApplication {
@Override @Override
public void onTouchEvent(TouchEvent evt) { } public void onTouchEvent(TouchEvent evt) { }
@Override
public void onMotionSensorEvent(MotionSensorEvent evt) { }
}; };
} }

@ -75,6 +75,8 @@ public class TestSoftwareMouse extends SimpleApplication {
} }
public void onTouchEvent(TouchEvent evt) { public void onTouchEvent(TouchEvent evt) {
} }
public void onMotionSensorEvent(MotionSensorEvent evt) {
}
}; };
public static void main(String[] args){ public static void main(String[] args){

Loading…
Cancel
Save