Android: Add scaling to input coordinates (onTouch Coordinates from Android) to compensate for manually set surface resolutions. Android always sends the touch coordinates relative to the view resolution, not the resolution of the surface. If users use view.getHolder().setFixedSize(width, height) in MainActivity.onCreate(), then the input coordinates are not correct which messes up ray casting and other things. This scales the input coordinates before sending them to jME.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10918 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
experimental
iwg..ic 11 years ago
parent 4f75cb688f
commit 743aa2144a
  1. 28
      engine/src/android/com/jme3/input/android/AndroidGestureHandler.java
  2. 31
      engine/src/android/com/jme3/input/android/AndroidInputHandler.java
  3. 24
      engine/src/android/com/jme3/input/android/AndroidTouchHandler.java
  4. 24
      engine/src/android/com/jme3/input/android/AndroidTouchHandler14.java

@ -157,8 +157,8 @@ public class AndroidGestureHandler implements
// of a series of gesture events. // of a series of gesture events.
// logger.log(Level.INFO, "onDown pointerId: {0}, action: {1}, x: {2}, y: {3}", // logger.log(Level.INFO, "onDown pointerId: {0}, action: {1}, x: {2}, y: {3}",
// new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()}); // new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()});
gestureDownX = event.getX(); gestureDownX = androidInput.getJmeX(event.getX());
gestureDownY = androidInput.invertY(event.getY()); gestureDownY = androidInput.invertY(androidInput.getJmeY(event.getY()));
return true; return true;
} }
@ -173,8 +173,10 @@ public class AndroidGestureHandler implements
public void onShowPress(MotionEvent event) { public void onShowPress(MotionEvent event) {
// logger.log(Level.INFO, "onShowPress pointerId: {0}, action: {1}, x: {2}, y: {3}", // logger.log(Level.INFO, "onShowPress pointerId: {0}, action: {1}, x: {2}, y: {3}",
// new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()}); // new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()});
float jmeX = androidInput.getJmeX(event.getX());
float jmeY = androidInput.invertY(androidInput.getJmeY(event.getY()));
TouchEvent touchEvent = androidInput.getFreeTouchEvent(); TouchEvent touchEvent = androidInput.getFreeTouchEvent();
touchEvent.set(TouchEvent.Type.SHOWPRESS, event.getX(), androidInput.invertY(event.getY()), 0, 0); touchEvent.set(TouchEvent.Type.SHOWPRESS, jmeX, jmeY, 0, 0);
touchEvent.setPointerId(getPointerId(event)); touchEvent.setPointerId(getPointerId(event));
touchEvent.setTime(event.getEventTime()); touchEvent.setTime(event.getEventTime());
touchEvent.setPressure(event.getPressure()); touchEvent.setPressure(event.getPressure());
@ -184,8 +186,10 @@ public class AndroidGestureHandler implements
public void onLongPress(MotionEvent event) { public void onLongPress(MotionEvent event) {
// logger.log(Level.INFO, "onLongPress pointerId: {0}, action: {1}, x: {2}, y: {3}", // logger.log(Level.INFO, "onLongPress pointerId: {0}, action: {1}, x: {2}, y: {3}",
// new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()}); // new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()});
float jmeX = androidInput.getJmeX(event.getX());
float jmeY = androidInput.invertY(androidInput.getJmeY(event.getY()));
TouchEvent touchEvent = androidInput.getFreeTouchEvent(); TouchEvent touchEvent = androidInput.getFreeTouchEvent();
touchEvent.set(TouchEvent.Type.LONGPRESSED, event.getX(), androidInput.invertY(event.getY()), 0, 0); touchEvent.set(TouchEvent.Type.LONGPRESSED, jmeX, jmeY, 0, 0);
touchEvent.setPointerId(getPointerId(event)); touchEvent.setPointerId(getPointerId(event));
touchEvent.setTime(event.getEventTime()); touchEvent.setTime(event.getEventTime());
touchEvent.setPressure(event.getPressure()); touchEvent.setPressure(event.getPressure());
@ -205,8 +209,10 @@ public class AndroidGestureHandler implements
// logger.log(Level.INFO, "onScroll pointerId: {0}, startAction: {1}, startX: {2}, startY: {3}, endAction: {4}, endX: {5}, endY: {6}, dx: {7}, dy: {8}", // logger.log(Level.INFO, "onScroll pointerId: {0}, startAction: {1}, startX: {2}, startY: {3}, endAction: {4}, endX: {5}, endY: {6}, dx: {7}, dy: {8}",
// new Object[]{getPointerId(startEvent), getAction(startEvent), startEvent.getX(), startEvent.getY(), getAction(endEvent), endEvent.getX(), endEvent.getY(), distX, distY}); // new Object[]{getPointerId(startEvent), getAction(startEvent), startEvent.getX(), startEvent.getY(), getAction(endEvent), endEvent.getX(), endEvent.getY(), distX, distY});
float jmeX = androidInput.getJmeX(endEvent.getX());
float jmeY = androidInput.invertY(androidInput.getJmeY(endEvent.getY()));
TouchEvent touchEvent = androidInput.getFreeTouchEvent(); TouchEvent touchEvent = androidInput.getFreeTouchEvent();
touchEvent.set(TouchEvent.Type.SCROLL, endEvent.getX(), androidInput.invertY(endEvent.getY()), -distX, distY); touchEvent.set(TouchEvent.Type.SCROLL, jmeX, jmeY, androidInput.getJmeX(-distX), androidInput.getJmeY(distY));
touchEvent.setPointerId(getPointerId(endEvent)); touchEvent.setPointerId(getPointerId(endEvent));
touchEvent.setTime(endEvent.getEventTime()); touchEvent.setTime(endEvent.getEventTime());
touchEvent.setPressure(endEvent.getPressure()); touchEvent.setPressure(endEvent.getPressure());
@ -224,8 +230,10 @@ public class AndroidGestureHandler implements
// logger.log(Level.INFO, "onFling pointerId: {0}, startAction: {1}, startX: {2}, startY: {3}, endAction: {4}, endX: {5}, endY: {6}, velocityX: {7}, velocityY: {8}", // logger.log(Level.INFO, "onFling pointerId: {0}, startAction: {1}, startX: {2}, startY: {3}, endAction: {4}, endX: {5}, endY: {6}, velocityX: {7}, velocityY: {8}",
// new Object[]{getPointerId(startEvent), getAction(startEvent), startEvent.getX(), startEvent.getY(), getAction(endEvent), endEvent.getX(), endEvent.getY(), velocityX, velocityY}); // new Object[]{getPointerId(startEvent), getAction(startEvent), startEvent.getX(), startEvent.getY(), getAction(endEvent), endEvent.getX(), endEvent.getY(), velocityX, velocityY});
float jmeX = androidInput.getJmeX(startEvent.getX());
float jmeY = androidInput.invertY(androidInput.getJmeY(startEvent.getY()));
TouchEvent touchEvent = androidInput.getFreeTouchEvent(); TouchEvent touchEvent = androidInput.getFreeTouchEvent();
touchEvent.set(TouchEvent.Type.FLING, startEvent.getX(), androidInput.invertY(startEvent.getY()), velocityX, velocityY); touchEvent.set(TouchEvent.Type.FLING, jmeX, jmeY, velocityX, velocityY);
touchEvent.setPointerId(getPointerId(endEvent)); touchEvent.setPointerId(getPointerId(endEvent));
touchEvent.setTime(endEvent.getEventTime()); touchEvent.setTime(endEvent.getEventTime());
touchEvent.setPressure(endEvent.getPressure()); touchEvent.setPressure(endEvent.getPressure());
@ -239,8 +247,10 @@ public class AndroidGestureHandler implements
// Up of single tap when no double tap followed. // Up of single tap when no double tap followed.
// logger.log(Level.INFO, "onSingleTapConfirmed pointerId: {0}, action: {1}, x: {2}, y: {3}", // logger.log(Level.INFO, "onSingleTapConfirmed pointerId: {0}, action: {1}, x: {2}, y: {3}",
// new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()}); // new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()});
float jmeX = androidInput.getJmeX(event.getX());
float jmeY = androidInput.invertY(androidInput.getJmeY(event.getY()));
TouchEvent touchEvent = androidInput.getFreeTouchEvent(); TouchEvent touchEvent = androidInput.getFreeTouchEvent();
touchEvent.set(TouchEvent.Type.TAP, event.getX(), androidInput.invertY(event.getY()), 0, 0); touchEvent.set(TouchEvent.Type.TAP, jmeX, jmeY, 0, 0);
touchEvent.setPointerId(getPointerId(event)); touchEvent.setPointerId(getPointerId(event));
touchEvent.setTime(event.getEventTime()); touchEvent.setTime(event.getEventTime());
touchEvent.setPressure(event.getPressure()); touchEvent.setPressure(event.getPressure());
@ -254,8 +264,10 @@ public class AndroidGestureHandler implements
// DoubleTapEvent with a check for the UP action // DoubleTapEvent with a check for the UP action
// logger.log(Level.INFO, "onDoubleTap pointerId: {0}, action: {1}, x: {2}, y: {3}", // logger.log(Level.INFO, "onDoubleTap pointerId: {0}, action: {1}, x: {2}, y: {3}",
// new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()}); // new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()});
float jmeX = androidInput.getJmeX(event.getX());
float jmeY = androidInput.invertY(androidInput.getJmeY(event.getY()));
TouchEvent touchEvent = androidInput.getFreeTouchEvent(); TouchEvent touchEvent = androidInput.getFreeTouchEvent();
touchEvent.set(TouchEvent.Type.DOUBLETAP, event.getX(), androidInput.invertY(event.getY()), 0, 0); touchEvent.set(TouchEvent.Type.DOUBLETAP, jmeX, jmeY, 0, 0);
touchEvent.setPointerId(getPointerId(event)); touchEvent.setPointerId(getPointerId(event));
touchEvent.setTime(event.getEventTime()); touchEvent.setTime(event.getEventTime());
touchEvent.setPressure(event.getPressure()); touchEvent.setPressure(event.getPressure());

@ -41,6 +41,7 @@ import com.jme3.input.event.KeyInputEvent;
import com.jme3.input.event.MouseButtonEvent; import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent; import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent; import com.jme3.input.event.TouchEvent;
import com.jme3.renderer.android.AndroidGLSurfaceView;
import com.jme3.system.AppSettings; import com.jme3.system.AppSettings;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level; import java.util.logging.Level;
@ -66,15 +67,18 @@ public class AndroidInputHandler implements TouchInput {
// Internal // Internal
private View view; private AndroidGLSurfaceView view;
private AndroidTouchHandler touchHandler; private AndroidTouchHandler touchHandler;
private AndroidKeyHandler keyHandler; private AndroidKeyHandler keyHandler;
private AndroidGestureHandler gestureHandler; private AndroidGestureHandler gestureHandler;
private boolean initialized = false; private boolean initialized = false;
private RawInputListener listener = null; private RawInputListener listener = null;
private ConcurrentLinkedQueue<InputEvent> inputEventQueue = new ConcurrentLinkedQueue<InputEvent>(); private ConcurrentLinkedQueue<InputEvent> inputEventQueue = new ConcurrentLinkedQueue<InputEvent>();
final private static int MAX_TOUCH_EVENTS = 1024; private final static int MAX_TOUCH_EVENTS = 1024;
private final TouchEventPool touchEventPool = new TouchEventPool(MAX_TOUCH_EVENTS); private final TouchEventPool touchEventPool = new TouchEventPool(MAX_TOUCH_EVENTS);
private float scaleX = 1f;
private float scaleY = 1f;
public AndroidInputHandler() { public AndroidInputHandler() {
int buildVersion = Build.VERSION.SDK_INT; int buildVersion = Build.VERSION.SDK_INT;
@ -108,7 +112,7 @@ public class AndroidInputHandler implements TouchInput {
if (gestureHandler != null) { if (gestureHandler != null) {
gestureHandler.setView(view); gestureHandler.setView(view);
} }
this.view = view; this.view = (AndroidGLSurfaceView)view;
} }
public View getView() { public View getView() {
@ -116,11 +120,19 @@ public class AndroidInputHandler implements TouchInput {
} }
public float invertX(float origX) { public float invertX(float origX) {
return view.getWidth()-origX; return getJmeX(view.getWidth()) - origX;
} }
public float invertY(float origY) { public float invertY(float origY) {
return view.getHeight()-origY; return getJmeY(view.getHeight()) - origY;
}
public float getJmeX(float origX) {
return origX * scaleX;
}
public float getJmeY(float origY) {
return origY * scaleY;
} }
public void loadSettings(AppSettings settings) { public void loadSettings(AppSettings settings) {
@ -130,6 +142,15 @@ public class AndroidInputHandler implements TouchInput {
mouseEventsInvertX = settings.isEmulateMouseFlipX(); mouseEventsInvertX = settings.isEmulateMouseFlipX();
mouseEventsInvertY = settings.isEmulateMouseFlipY(); mouseEventsInvertY = settings.isEmulateMouseFlipY();
joystickEventsEnabled = settings.useJoysticks(); joystickEventsEnabled = settings.useJoysticks();
// view width and height are 0 until the view is displayed on the screen
if (view.getWidth() != 0 && view.getHeight() != 0) {
scaleX = (float)settings.getWidth() / (float)view.getWidth();
scaleY = (float)settings.getHeight() / (float)view.getHeight();
}
logger.log(Level.FINE, "Setting input scaling, scaleX: {0}, scaleY: {1}",
new Object[]{scaleX, scaleY});
} }
// ----------------------------------------- // -----------------------------------------

@ -112,6 +112,8 @@ public class AndroidTouchHandler implements View.OnTouchListener {
int pointerIndex = getPointerIndex(event); int pointerIndex = getPointerIndex(event);
int pointerId = getPointerId(event); int pointerId = getPointerId(event);
Vector2f lastPos = lastPositions.get(pointerId); Vector2f lastPos = lastPositions.get(pointerId);
float jmeX;
float jmeY;
numPointers = event.getPointerCount(); numPointers = event.getPointerCount();
@ -120,13 +122,15 @@ public class AndroidTouchHandler implements View.OnTouchListener {
switch (getAction(event)) { switch (getAction(event)) {
case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
jmeX = androidInput.getJmeX(event.getX(pointerIndex));
jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex)));
touch = androidInput.getFreeTouchEvent(); touch = androidInput.getFreeTouchEvent();
touch.set(TouchEvent.Type.DOWN, event.getX(pointerIndex), androidInput.invertY(event.getY(pointerIndex)), 0, 0); touch.set(TouchEvent.Type.DOWN, jmeX, jmeY, 0, 0);
touch.setPointerId(pointerId); touch.setPointerId(pointerId);
touch.setTime(event.getEventTime()); touch.setTime(event.getEventTime());
touch.setPressure(event.getPressure(pointerIndex)); touch.setPressure(event.getPressure(pointerIndex));
lastPos = new Vector2f(event.getX(pointerIndex), androidInput.invertY(event.getY(pointerIndex))); lastPos = new Vector2f(jmeX, jmeY);
lastPositions.put(pointerId, lastPos); lastPositions.put(pointerId, lastPos);
processEvent(touch); processEvent(touch);
@ -136,8 +140,10 @@ public class AndroidTouchHandler implements View.OnTouchListener {
case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
jmeX = androidInput.getJmeX(event.getX(pointerIndex));
jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex)));
touch = androidInput.getFreeTouchEvent(); touch = androidInput.getFreeTouchEvent();
touch.set(TouchEvent.Type.UP, event.getX(pointerIndex), androidInput.invertY(event.getY(pointerIndex)), 0, 0); touch.set(TouchEvent.Type.UP, jmeX, jmeY, 0, 0);
touch.setPointerId(pointerId); touch.setPointerId(pointerId);
touch.setTime(event.getEventTime()); touch.setTime(event.getEventTime());
touch.setPressure(event.getPressure(pointerIndex)); touch.setPressure(event.getPressure(pointerIndex));
@ -150,21 +156,23 @@ public class AndroidTouchHandler implements View.OnTouchListener {
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
// Convert all pointers into events // Convert all pointers into events
for (int p = 0; p < event.getPointerCount(); p++) { for (int p = 0; p < event.getPointerCount(); p++) {
jmeX = androidInput.getJmeX(event.getX(p));
jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(p)));
lastPos = lastPositions.get(event.getPointerId(p)); lastPos = lastPositions.get(event.getPointerId(p));
if (lastPos == null) { if (lastPos == null) {
lastPos = new Vector2f(event.getX(p), androidInput.invertY(event.getY(p))); lastPos = new Vector2f(jmeX, jmeY);
lastPositions.put(event.getPointerId(p), lastPos); lastPositions.put(event.getPointerId(p), lastPos);
} }
float dX = event.getX(p) - lastPos.x; float dX = jmeX - lastPos.x;
float dY = androidInput.invertY(event.getY(p)) - lastPos.y; float dY = jmeY - lastPos.y;
if (dX != 0 || dY != 0) { if (dX != 0 || dY != 0) {
touch = androidInput.getFreeTouchEvent(); touch = androidInput.getFreeTouchEvent();
touch.set(TouchEvent.Type.MOVE, event.getX(p), androidInput.invertY(event.getY(p)), dX, dY); touch.set(TouchEvent.Type.MOVE, jmeX, jmeY, dX, dY);
touch.setPointerId(event.getPointerId(p)); touch.setPointerId(event.getPointerId(p));
touch.setTime(event.getEventTime()); touch.setTime(event.getEventTime());
touch.setPressure(event.getPressure(p)); touch.setPressure(event.getPressure(p));
lastPos.set(event.getX(p), androidInput.invertY(event.getY(p))); lastPos.set(jmeX, jmeY);
processEvent(touch); processEvent(touch);

@ -76,6 +76,8 @@ public class AndroidTouchHandler14 extends AndroidTouchHandler implements
int pointerId = getPointerId(event); int pointerId = getPointerId(event);
int pointerIndex = getPointerIndex(event); int pointerIndex = getPointerIndex(event);
Vector2f lastPos = lastHoverPositions.get(pointerId); Vector2f lastPos = lastHoverPositions.get(pointerId);
float jmeX;
float jmeY;
numPointers = event.getPointerCount(); numPointers = event.getPointerCount();
@ -85,13 +87,15 @@ public class AndroidTouchHandler14 extends AndroidTouchHandler implements
TouchEvent touchEvent; TouchEvent touchEvent;
switch (action) { switch (action) {
case MotionEvent.ACTION_HOVER_ENTER: case MotionEvent.ACTION_HOVER_ENTER:
jmeX = androidInput.getJmeX(event.getX(pointerIndex));
jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex)));
touchEvent = androidInput.getFreeTouchEvent(); touchEvent = androidInput.getFreeTouchEvent();
touchEvent.set(TouchEvent.Type.HOVER_START, event.getX(pointerIndex), androidInput.invertY(event.getY(pointerIndex)), 0, 0); touchEvent.set(TouchEvent.Type.HOVER_START, jmeX, jmeY, 0, 0);
touchEvent.setPointerId(pointerId); touchEvent.setPointerId(pointerId);
touchEvent.setTime(event.getEventTime()); touchEvent.setTime(event.getEventTime());
touchEvent.setPressure(event.getPressure(pointerIndex)); touchEvent.setPressure(event.getPressure(pointerIndex));
lastPos = new Vector2f(event.getX(pointerIndex), androidInput.invertY(event.getY(pointerIndex))); lastPos = new Vector2f(jmeX, jmeY);
lastHoverPositions.put(pointerId, lastPos); lastHoverPositions.put(pointerId, lastPos);
processEvent(touchEvent); processEvent(touchEvent);
@ -100,21 +104,23 @@ public class AndroidTouchHandler14 extends AndroidTouchHandler implements
case MotionEvent.ACTION_HOVER_MOVE: case MotionEvent.ACTION_HOVER_MOVE:
// Convert all pointers into events // Convert all pointers into events
for (int p = 0; p < event.getPointerCount(); p++) { for (int p = 0; p < event.getPointerCount(); p++) {
jmeX = androidInput.getJmeX(event.getX(p));
jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(p)));
lastPos = lastHoverPositions.get(event.getPointerId(p)); lastPos = lastHoverPositions.get(event.getPointerId(p));
if (lastPos == null) { if (lastPos == null) {
lastPos = new Vector2f(event.getX(p), androidInput.invertY(event.getY(p))); lastPos = new Vector2f(jmeX, jmeY);
lastHoverPositions.put(event.getPointerId(p), lastPos); lastHoverPositions.put(event.getPointerId(p), lastPos);
} }
float dX = event.getX(p) - lastPos.x; float dX = jmeX - lastPos.x;
float dY = androidInput.invertY(event.getY(p)) - lastPos.y; float dY = jmeY - lastPos.y;
if (dX != 0 || dY != 0) { if (dX != 0 || dY != 0) {
touchEvent = androidInput.getFreeTouchEvent(); touchEvent = androidInput.getFreeTouchEvent();
touchEvent.set(TouchEvent.Type.HOVER_MOVE, event.getX(p), androidInput.invertY(event.getY(p)), dX, dY); touchEvent.set(TouchEvent.Type.HOVER_MOVE, jmeX, jmeY, dX, dY);
touchEvent.setPointerId(event.getPointerId(p)); touchEvent.setPointerId(event.getPointerId(p));
touchEvent.setTime(event.getEventTime()); touchEvent.setTime(event.getEventTime());
touchEvent.setPressure(event.getPressure(p)); touchEvent.setPressure(event.getPressure(p));
lastPos.set(event.getX(p), androidInput.invertY(event.getY(p))); lastPos.set(jmeX, jmeY);
processEvent(touchEvent); processEvent(touchEvent);
@ -123,8 +129,10 @@ public class AndroidTouchHandler14 extends AndroidTouchHandler implements
consumed = true; consumed = true;
break; break;
case MotionEvent.ACTION_HOVER_EXIT: case MotionEvent.ACTION_HOVER_EXIT:
jmeX = androidInput.getJmeX(event.getX(pointerIndex));
jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex)));
touchEvent = androidInput.getFreeTouchEvent(); touchEvent = androidInput.getFreeTouchEvent();
touchEvent.set(TouchEvent.Type.HOVER_END, event.getX(pointerIndex), androidInput.invertY(event.getY(pointerIndex)), 0, 0); touchEvent.set(TouchEvent.Type.HOVER_END, jmeX, jmeY, 0, 0);
touchEvent.setPointerId(pointerId); touchEvent.setPointerId(pointerId);
touchEvent.setTime(event.getEventTime()); touchEvent.setTime(event.getEventTime());
touchEvent.setPressure(event.getPressure(pointerIndex)); touchEvent.setPressure(event.getPressure(pointerIndex));

Loading…
Cancel
Save