Adding Android Sensor support as simulated joysticks. Only orientation is supported right now, more sensor types to be added later. When device orientation changes, Joystick[0] is updated just like using an actual joystick. Users need to add "joystickEventsEnabled = true" to the MainActivity to enable the orientation joystick so battery life is conserved if sensor data is not desired. See http://jmonkeyengine.org/groups/android/forum/topic/creating-engine-support-for-android-sensor-input/ for the long history.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9700 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
iwg..om 12 years ago
parent fa426feb08
commit 39f265f50e
  1. 32
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 658
      engine/src/android/com/jme3/input/android/AndroidSensorJoyInput.java
  3. 13
      engine/src/android/com/jme3/system/android/OGLESContext.java
  4. 47
      engine/src/core/com/jme3/input/Joystick.java

@ -15,7 +15,9 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.jme3.audio.AudioRenderer;
import com.jme3.audio.android.AndroidAudioRenderer;
import com.jme3.input.JoyInput;
import com.jme3.input.TouchInput;
import com.jme3.input.android.AndroidSensorJoyInput;
import com.jme3.input.controls.TouchListener;
import com.jme3.input.controls.TouchTrigger;
import com.jme3.input.event.TouchEvent;
@ -61,6 +63,13 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
*/
protected boolean eglConfigVerboseLogging = false;
/**
* If true Android Sensors are used as simulated Joysticks
* Users can use the Android sensor feedback through the RawInputListener
* or by registering JoyAxisTriggers.
*/
protected boolean joystickEventsEnabled = false;
/**
* If true MouseEvents are generated from TouchEvents
*/
@ -215,6 +224,9 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
logger.log(Level.WARNING, "Resolution from Window: {0}, {1}", new Object[]{disp.getWidth(), disp.getHeight()});
ctx.getSettings().setResolution(disp.getWidth(), disp.getHeight());
settings.setUseJoysticks(joystickEventsEnabled);
ctx.getSettings().setUseJoysticks(joystickEventsEnabled);
// AndroidHarness wraps the app as a SystemListener.
ctx.setSystemListener(this);
layoutDisplay();
@ -257,6 +269,16 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
renderer.resumeAll();
}
}
//resume the sensors (aka joysticks)
if (app.getContext() != null) {
JoyInput joyInput = app.getContext().getJoyInput();
if (joyInput != null) {
if (joyInput instanceof AndroidSensorJoyInput) {
AndroidSensorJoyInput androidJoyInput = (AndroidSensorJoyInput) joyInput;
androidJoyInput.resumeSensors();
}
}
}
}
isGLThreadPaused = false;
@ -280,6 +302,16 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
renderer.pauseAll();
}
}
//pause the sensors (aka joysticks)
if (app.getContext() != null) {
JoyInput joyInput = app.getContext().getJoyInput();
if (joyInput != null) {
if (joyInput instanceof AndroidSensorJoyInput) {
AndroidSensorJoyInput androidJoyInput = (AndroidSensorJoyInput) joyInput;
androidJoyInput.pauseSensors();
}
}
}
}
isGLThreadPaused = true;
logger.info("onPause");

@ -0,0 +1,658 @@
/*
* 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.InputManager;
import com.jme3.input.JoyInput;
import com.jme3.input.Joystick;
import com.jme3.input.RawInputListener;
import com.jme3.input.event.JoyAxisEvent;
import com.jme3.math.FastMath;
import com.jme3.system.android.JmeAndroidSystem;
import com.jme3.util.IntMap;
import com.jme3.util.IntMap.Entry;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author iwgeric
*/
public class AndroidSensorJoyInput implements JoyInput, SensorEventListener {
private final static Logger logger = Logger.getLogger(AndroidSensorJoyInput.class.getName());
private InputManager inputManager = null;
private SensorManager sensorManager = null;
private RawInputListener listener = null;
private IntMap<SensorData> sensors = new IntMap<SensorData>();
private Joystick[] joysticks;
private boolean initialized = false;
private WindowManager window;
private Display disp;
private int lastRotation = 0;
private final float[] orientationLastValues = new float[3];
private final float[] maxOrientationValues = new float[] {FastMath.HALF_PI, FastMath.HALF_PI, FastMath.HALF_PI};
private final ArrayList<JoyAxisEvent> eventQueue = new ArrayList<JoyAxisEvent>();
/**
* Internal class to enclose data for each sensor.
*/
private class SensorData {
int androidSensorType = -1;
int androidSensorSpeed = SensorManager.SENSOR_DELAY_GAME;
Sensor sensor = null;
float maxRange = 0f;
float resolution = 0f;
float[] lastValues;
final Object valuesLock = new Object();
int joyID = -1;
String joyName = "";
boolean enabled = false;
boolean haveData = false;
boolean createJoystick = false;
public SensorData(int androidSensorType, Sensor sensor) {
this.androidSensorType = androidSensorType;
this.sensor = sensor;
}
}
private void initSensorManager() {
initWindow();
sensorManager = (SensorManager) JmeAndroidSystem.getActivity().getSystemService(Context.SENSOR_SERVICE);
initSensors();
}
/**
* Used internally. Do not use.
* Allows the context to reset the current activity for getting device rotation
*/
public void initWindow() {
window = JmeAndroidSystem.getActivity().getWindowManager();
disp = window.getDefaultDisplay();
}
private void initSensors() {
SensorData sensorData;
List<Sensor> availSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor: availSensors) {
logger.log(Level.INFO, "{0} Sensor is available, Type: {1}, Vendor: {2}, Version: {3}",
new Object[]{sensor.getName(), sensor.getType(), sensor.getVendor(), sensor.getVersion()});
}
sensorData = initSensor(Sensor.TYPE_MAGNETIC_FIELD);
if (sensorData != null) {
sensorData.joyName = "Device Direction";
sensorData.lastValues = new float[3];
sensorData.createJoystick = false;
}
sensorData = initSensor(Sensor.TYPE_ACCELEROMETER);
if (sensorData != null) {
sensorData.joyName = "Device Acceleration";
sensorData.lastValues = new float[3];
sensorData.createJoystick = false;
}
// sensorData = initSensor(Sensor.TYPE_GYROSCOPE);
// if (sensorData != null) {
// sensorData.joyName = "Device Rotation";
// sensorData.lastValues = new float[3];
// sensorData.createJoystick = false;
// }
//
// sensorData = initSensor(Sensor.TYPE_GRAVITY);
// if (sensorData != null) {
// sensorData.joyName = "Device Gravity";
// sensorData.lastValues = new float[3];
// sensorData.createJoystick = false;
// }
//
// sensorData = initSensor(Sensor.TYPE_LINEAR_ACCELERATION);
// if (sensorData != null) {
// sensorData.joyName = "Device Linear Acceleration";
// sensorData.lastValues = new float[3];
// sensorData.createJoystick = false;
// }
//
// sensorData = initSensor(Sensor.TYPE_ROTATION_VECTOR);
// if (sensorData != null) {
// sensorData.joyName = "Device Rotation Vector";
// sensorData.lastValues = new float[4];
// sensorData.createJoystick = false;
// }
//
// sensorData = initSensor(Sensor.TYPE_PROXIMITY);
// if (sensorData != null) {
// sensorData.joyName = "Device Proximity";
// sensorData.lastValues = new float[1];
// sensorData.createJoystick = false;
// }
//
// sensorData = initSensor(Sensor.TYPE_LIGHT);
// if (sensorData != null) {
// sensorData.joyName = "Device Light";
// sensorData.lastValues = new float[1];
// sensorData.createJoystick = false;
// }
//
// sensorData = initSensor(Sensor.TYPE_PRESSURE);
// if (sensorData != null) {
// sensorData.joyName = "Device Pressure";
// sensorData.lastValues = new float[1];
// sensorData.createJoystick = false;
// }
//
// sensorData = initSensor(Sensor.TYPE_TEMPERATURE);
// if (sensorData != null) {
// sensorData.joyName = "Device Temperature";
// sensorData.lastValues = new float[1];
// sensorData.createJoystick = false;
// }
}
private SensorData initSensor(int sensorType) {
boolean success = false;
SensorData sensorData = sensors.get(sensorType);
if (sensorData != null) {
unRegisterListener(sensorType);
} else {
sensorData = new SensorData(sensorType, null);
sensors.put(sensorType, sensorData);
}
sensorData.androidSensorType = sensorType;
sensorData.sensor = sensorManager.getDefaultSensor(sensorType);
if (sensorData.sensor != null) {
logger.log(Level.INFO, "Sensor Type {0} found.", sensorType);
success = registerListener(sensorType);
} else {
logger.log(Level.INFO, "Sensor Type {0} not found.", sensorType);
}
if (success) {
return sensorData;
} else {
return null;
}
}
private boolean registerListener(int sensorType) {
SensorData sensorData = sensors.get(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;
}
sensorData.haveData = false;
if (sensorData.sensor != null) {
if (sensorManager.registerListener(this, sensorData.sensor, sensorData.androidSensorSpeed)) {
sensorData.enabled = true;
logger.log(Level.INFO, "SensorType: {0}, actived: {1}",
new Object[]{sensorType, sensorData.enabled});
return true;
} else {
sensorData.enabled = false;
logger.log(Level.INFO, "Sensor Type {0} activation failed.", sensorType);
}
}
}
return false;
}
private void unRegisterListener(int sensorType) {
SensorData sensorData = sensors.get(sensorType);
if (sensorData != null) {
if (sensorData.sensor != null) {
sensorManager.unregisterListener(this, sensorData.sensor);
}
sensorData.enabled = false;
sensorData.haveData = false;
logger.log(Level.INFO, "SensorType: {0} deactivated, active: {1}",
new Object[]{sensorType, sensorData.enabled});
}
}
/**
* Pauses the sensors to save battery life if the sensors are not needed.
* Used to pause sensors when the activity pauses
*/
public void pauseSensors() {
for (Entry entry: sensors) {
unRegisterListener(entry.getKey());
}
}
/**
* Resumes the sensors.
* Used to resume sensors when the activity comes to the top of the stack
*/
public void resumeSensors() {
for (Entry entry: sensors) {
registerListener(entry.getKey());
}
}
/*
* Allows the orientation data to be rotated based on the current device
* rotation. This keeps the data aligned with the game when the user
* rotates the device during game play.
*
* 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 (Earth) axis and direction the X axis of the device is mapped.
* Y defines on which world (Earth) 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;
int curRotation = getScreenRotation();
if (lastRotation != curRotation) {
logger.log(Level.INFO, "Device Rotation changed to: {0}", curRotation);
}
lastRotation = curRotation;
// logger.log(Level.INFO, "Screen Rotation: {0}", getScreenRotation());
switch (getScreenRotation()) {
// device natural position
case Surface.ROTATION_0:
xDir = SensorManager.AXIS_X;
yDir = SensorManager.AXIS_Y;
break;
// device rotated 90 deg counterclockwise
case Surface.ROTATION_90:
xDir = SensorManager.AXIS_Y;
yDir = SensorManager.AXIS_MINUS_X;
break;
// device rotated 180 deg counterclockwise
case Surface.ROTATION_180:
xDir = SensorManager.AXIS_MINUS_X;
yDir = SensorManager.AXIS_MINUS_Y;
break;
// device rotated 270 deg counterclockwise
case Surface.ROTATION_270:
xDir = SensorManager.AXIS_MINUS_Y;
yDir = SensorManager.AXIS_X;
break;
default:
break;
}
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();
}
/**
* 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 True if Orientation was calculated
*/
private boolean updateOrientation() {
SensorData sensorData;
final float[] curInclinationMat = new float[16];
final float[] curRotationMat = new float[16];
final float[] rotatedRotationMat = new float[16];
final float[] accValues = new float[3];
final float[] magValues = new float[3];
final float[] deltaOrientation = new float[3];
// if the Gravity Sensor is available, use it for orientation, if not
// use the accelerometer
// NOTE: Seemed to work worse, so just using accelerometer
// sensorData = sensors.get(Sensor.TYPE_GRAVITY);
// if (sensorData == null) {
sensorData = sensors.get(Sensor.TYPE_ACCELEROMETER);
// }
if (sensorData == null || !sensorData.enabled || !sensorData.haveData) {
return false;
}
synchronized(sensorData.valuesLock) {
accValues[0] = sensorData.lastValues[0];
accValues[1] = sensorData.lastValues[1];
accValues[2] = sensorData.lastValues[2];
}
sensorData = sensors.get(Sensor.TYPE_MAGNETIC_FIELD);
if (sensorData == null || !sensorData.enabled || !sensorData.haveData) {
return false;
}
synchronized(sensorData.valuesLock) {
magValues[0] = sensorData.lastValues[0];
magValues[1] = sensorData.lastValues[1];
magValues[2] = sensorData.lastValues[2];
}
if (SensorManager.getRotationMatrix(curRotationMat, curInclinationMat, accValues, magValues)) {
final float [] orientValues = new float[3];
if (remapCoordinates(curRotationMat, rotatedRotationMat)) {
SensorManager.getOrientation(rotatedRotationMat, orientValues);
// logger.log(Level.INFO, "Orientation Values: {0}, {1}, {2}",
// new Object[]{orientValues[0], orientValues[1], orientValues[2]});
//values[0]: Azimuth - (the compass bearing east of magnetic north)
//values[1]: Pitch, rotation around x-axis (is the phone leaning forward or back)
//values[2]: Roll, rotation around y-axis (is the phone leaning over on its left or right side)
//Azimuth (degrees of rotation around the z axis). This is the angle between magnetic north
//and the device's y axis. For example, if the device's y axis is aligned with magnetic north
//this value is 0, and if the device's y axis is pointing south this value is 180.
//Likewise, when the y axis is pointing east this value is 90 and when it is pointing west
//this value is 270.
//Pitch (degrees of rotation around the x axis). This value is positive when the positive
//z axis rotates toward the positive y axis, and it is negative when the positive z axis
//rotates toward the negative y axis. The range of values is 180 degrees to -180 degrees.
//Roll (degrees of rotation around the y axis). This value is positive when the
//positive z axis rotates toward the positive x axis, and it is negative when the
//positive z axis rotates toward the negative x axis. The range of values
//is 90 degrees to -90 degrees.
// // Azimuth scaling
// if (orientValues[0]<0) {
// orientValues[0] += FastMath.TWO_PI;
// }
//
// // Pitch scaling
// if (orientValues[1] < -FastMath.HALF_PI) {
// orientValues[1] += (-2*(FastMath.HALF_PI+orientValues[1]));
// } else if (orientValues[1] > FastMath.HALF_PI) {
// orientValues[1] += (2*(FastMath.HALF_PI-orientValues[1]));
// }
//
// // Roll scaling
// // NOT NEEDED
// need to reorder to make it x, y, z order instead of z, x, y order
deltaOrientation[0] = orientValues[1] - orientationLastValues[1];
deltaOrientation[1] = orientValues[2] - orientationLastValues[2];
deltaOrientation[2] = orientValues[0] - orientationLastValues[0];
synchronized (eventQueue){
// only send data to inputManager if it is different than last time
// orientValues[1] is the X axis -> JoyAxisEvent Axis 0
// orientValues[2] is the Y axis -> JoyAxisEvent Axis 1
// orientValues[0] is the Z axis -> JoyAxisEvent Axis 2
if (Math.abs(deltaOrientation[0]) > FastMath.ZERO_TOLERANCE) {
eventQueue.add(new JoyAxisEvent(0, 0, orientValues[1] / maxOrientationValues[1]));
}
if (Math.abs(deltaOrientation[1]) > FastMath.ZERO_TOLERANCE) {
eventQueue.add(new JoyAxisEvent(0, 1, orientValues[2] / maxOrientationValues[2]));
}
if (Math.abs(deltaOrientation[2]) > FastMath.ZERO_TOLERANCE) {
eventQueue.add(new JoyAxisEvent(0, 2, orientValues[0] / maxOrientationValues[0]));
}
}
orientationLastValues[0] = orientValues[0];
orientationLastValues[1] = orientValues[1];
orientationLastValues[2] = orientValues[2];
return true;
} else {
//logger.log(Level.INFO, "remapCoordinateSystem failed");
}
} else {
//logger.log(Level.INFO, "getRotationMatrix returned false");
}
return false;
}
// Start of JoyInput methods
public void setJoyRumble(int joyId, float amount) {
return;
}
public Joystick[] loadJoysticks(InputManager inputManager) {
this.inputManager = inputManager;
int joyIndex = 1; // start with 1 for orientation
for (Entry entry: sensors) {
SensorData sensorData = (SensorData)entry.getValue();
if (sensorData != null) {
if (sensorData.sensor != null && sensorData.createJoystick) {
joyIndex++; // add 1 for each of the physical sensors configured and enabled
}
}
}
joysticks = new Joystick[joyIndex];
joyIndex = 0;
Joystick joystick;
// manually create a joystick for orientation since orientation
// is not an actual physical sensor
// Do the orientation joystick first so it is compatible with PC systems
// that only have a single joystick configured.
joystick = new Joystick(inputManager,
this,
joyIndex,
"Device Orientation",
0, // button count
3, // axis count
0, 1); // xAxis, yAxis
joysticks[joyIndex] = joystick;
joyIndex++;
// create a joystick for each physical sensor configured
for (Entry entry: sensors) {
SensorData sensorData = (SensorData)entry.getValue();
if (sensorData != null) {
if (sensorData.sensor != null && sensorData.createJoystick) {
sensorData.joyID = joyIndex;
joystick = new Joystick(inputManager,
this,
joyIndex,
sensorData.joyName,
0, // button count
sensorData.lastValues.length, // axis count
0, 1); // xAxis, yAxis
joysticks[joyIndex] = joystick;
joyIndex++;
}
}
}
return joysticks;
}
public void initialize() {
logger.log(Level.INFO, "Doing Initialize.");
initSensorManager();
initialized = true;
}
public void update() {
updateOrientation();
synchronized (eventQueue){
// flush events to listener
if (listener != null && eventQueue.size() > 0) {
for (int i = 0; i < eventQueue.size(); i++){
listener.onJoyAxisEvent(eventQueue.get(i));
}
eventQueue.clear();
}
}
}
public void destroy() {
logger.log(Level.INFO, "Doing Destroy.");
pauseSensors();
if (sensorManager != null) {
sensorManager.unregisterListener(this);
}
sensors.clear();
eventQueue.clear();
joysticks = null;
}
public boolean isInitialized() {
return initialized;
}
public void setInputListener(RawInputListener listener) {
this.listener = listener;
}
public long getInputTimeNanos() {
return System.nanoTime();
}
// End of JoyInput methods
// Start of Android SensorEventListener methods
public void onSensorChanged(SensorEvent se) {
if (!initialized) {
return;
}
int sensorType = se.sensor.getType();
SensorData sensorData = sensors.get(sensorType);
if (sensorData != null && sensorData.sensor.equals(se.sensor) && sensorData.enabled) {
if (!sensorData.haveData) {
sensorData.haveData = true;
} else {
if (sensorData.joyID != -1) {
final float[] deltaValues = new float[sensorData.lastValues.length];
for (int i=0; i<sensorData.lastValues.length; i++) {
deltaValues[i] = se.values[i] - sensorData.lastValues[i];
}
// TODO: need to scale physical sensor data to fit within
// joystick model of providing values of 0 to 1
synchronized (eventQueue){
for (int i=0; i<deltaValues.length; i++) {
if (FastMath.abs(deltaValues[i]) > sensorData.lastValues[i] + FastMath.ZERO_TOLERANCE) {
eventQueue.add(new JoyAxisEvent(sensorData.joyID, i, se.values[i]));
}
}
}
}
}
synchronized(sensorData.valuesLock) {
for (int i=0; i<sensorData.lastValues.length; i++) {
sensorData.lastValues[i] = se.values[i];
}
}
}
}
public void onAccuracyChanged(Sensor sensor, int i) {
int sensorType = sensor.getType();
SensorData sensorData = sensors.get(sensorType);
if (sensorData != null) {
logger.log(Level.INFO, "onAccuracyChanged for {0} ({1}): accuracy: {2}",
new Object[]{sensor.toString(), sensorData.joyName, i});
logger.log(Level.INFO, "MaxRange: {0}, Resolution: {1}",
new Object[]{sensor.getMaximumRange(), sensor.getResolution()});
if (sensorData.sensor != null && sensorData.sensor.equals(sensor)) {
sensorData.resolution = sensor.getResolution();
sensorData.maxRange = sensor.getMaximumRange();
}
}
}
// End of SensorEventListener methods
}

@ -43,6 +43,7 @@ import android.widget.EditText;
import android.widget.FrameLayout;
import com.jme3.input.*;
import com.jme3.input.android.AndroidInput;
import com.jme3.input.android.AndroidSensorJoyInput;
import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput;
@ -76,6 +77,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
protected AndroidInput androidInput;
protected AndroidGLSurfaceView view;
protected int minFrameDuration = 0; // No FPS cap
protected JoyInput androidSensorJoyInput = null;
/**
* EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 |
* EGL_OPENGL_ES2_BIT = OpenGL ES 2.0
@ -106,6 +108,12 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
* @return GLSurfaceView The newly created view
*/
public GLSurfaceView createView(ConfigType configType, boolean eglConfigVerboseLogging) {
// if simulated joysticks are used, init the window to update the activity used to
// get the window orientation
if (androidSensorJoyInput != null && androidSensorJoyInput instanceof AndroidSensorJoyInput) {
((AndroidSensorJoyInput)androidSensorJoyInput).initWindow();
}
// Start to set up the view
view = new AndroidGLSurfaceView(JmeAndroidSystem.getActivity());
if (androidInput == null) {
@ -268,7 +276,10 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
@Override
public JoyInput getJoyInput() {
return null;
if (androidSensorJoyInput == null) {
androidSensorJoyInput = new AndroidSensorJoyInput();
}
return androidSensorJoyInput;
}
@Override

@ -5,7 +5,7 @@ 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 {
@ -37,7 +37,7 @@ public final class Joystick {
/**
* 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){
@ -47,11 +47,11 @@ public final class Joystick {
/**
* 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()
*
* @see Joystick#getButtonCount()
*/
public void assignButton(String mappingName, int buttonId){
if (buttonId < 0 || buttonId >= buttonCount)
@ -62,12 +62,12 @@ public final class Joystick {
/**
* 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()
*
* @see Joystick#getAxisCount()
*/
public void assignAxis(String positiveMapping, String negativeMapping, int axisId){
inputManager.addMapping(positiveMapping, new JoyAxisTrigger(joyId, axisId, false));
@ -76,12 +76,12 @@ public final class Joystick {
/**
* 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)
*
* @see Joystick#assignAxis(java.lang.String, java.lang.String, int)
*/
public int getXAxisIndex(){
return axisXIndex;
@ -89,12 +89,12 @@ public final class Joystick {
/**
* 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)
*
* @see Joystick#assignAxis(java.lang.String, java.lang.String, int)
*/
public int getYAxisIndex(){
return axisYIndex;
@ -102,7 +102,7 @@ public final class Joystick {
/**
* Returns the number of axes on this joystick.
*
*
* @return the number of axes on this joystick.
*/
public int getAxisCount() {
@ -111,7 +111,7 @@ public final class Joystick {
/**
* Returns the number of buttons on this joystick.
*
*
* @return the number of buttons on this joystick.
*/
public int getButtonCount() {
@ -120,13 +120,22 @@ public final class Joystick {
/**
* Returns the name of this joystick.
*
*
* @return the name of this joystick.
*/
public String getName() {
return name;
}
/**
* Returns the joyId of this joystick.
*
* @return the joyId of this joystick.
*/
public int getJoyId() {
return joyId;
}
@Override
public String toString(){
return "Joystick[name=" + name + ", id=" + joyId + ", buttons=" + buttonCount

Loading…
Cancel
Save