From 743aa2144a87aaf18256499ce2a2fd8272489f24 Mon Sep 17 00:00:00 2001 From: "iwg..ic" Date: Tue, 26 Nov 2013 02:35:00 +0000 Subject: [PATCH] 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 --- .../input/android/AndroidGestureHandler.java | 28 ++++++++++++----- .../input/android/AndroidInputHandler.java | 31 ++++++++++++++++--- .../input/android/AndroidTouchHandler.java | 24 +++++++++----- .../input/android/AndroidTouchHandler14.java | 24 +++++++++----- 4 files changed, 78 insertions(+), 29 deletions(-) diff --git a/engine/src/android/com/jme3/input/android/AndroidGestureHandler.java b/engine/src/android/com/jme3/input/android/AndroidGestureHandler.java index 8b6896baf..d233836a5 100644 --- a/engine/src/android/com/jme3/input/android/AndroidGestureHandler.java +++ b/engine/src/android/com/jme3/input/android/AndroidGestureHandler.java @@ -157,8 +157,8 @@ public class AndroidGestureHandler implements // of a series of gesture events. // logger.log(Level.INFO, "onDown pointerId: {0}, action: {1}, x: {2}, y: {3}", // new Object[]{getPointerId(event), getAction(event), event.getX(), event.getY()}); - gestureDownX = event.getX(); - gestureDownY = androidInput.invertY(event.getY()); + gestureDownX = androidInput.getJmeX(event.getX()); + gestureDownY = androidInput.invertY(androidInput.getJmeY(event.getY())); return true; } @@ -173,8 +173,10 @@ public class AndroidGestureHandler implements public void onShowPress(MotionEvent event) { // logger.log(Level.INFO, "onShowPress pointerId: {0}, action: {1}, x: {2}, y: {3}", // 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.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.setTime(event.getEventTime()); touchEvent.setPressure(event.getPressure()); @@ -184,8 +186,10 @@ public class AndroidGestureHandler implements public void onLongPress(MotionEvent event) { // logger.log(Level.INFO, "onLongPress pointerId: {0}, action: {1}, x: {2}, y: {3}", // 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.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.setTime(event.getEventTime()); 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}", // 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.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.setTime(endEvent.getEventTime()); 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}", // 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.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.setTime(endEvent.getEventTime()); touchEvent.setPressure(endEvent.getPressure()); @@ -239,8 +247,10 @@ public class AndroidGestureHandler implements // Up of single tap when no double tap followed. // logger.log(Level.INFO, "onSingleTapConfirmed pointerId: {0}, action: {1}, x: {2}, y: {3}", // 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.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.setTime(event.getEventTime()); touchEvent.setPressure(event.getPressure()); @@ -254,8 +264,10 @@ public class AndroidGestureHandler implements // DoubleTapEvent with a check for the UP action // logger.log(Level.INFO, "onDoubleTap pointerId: {0}, action: {1}, x: {2}, y: {3}", // 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.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.setTime(event.getEventTime()); touchEvent.setPressure(event.getPressure()); diff --git a/engine/src/android/com/jme3/input/android/AndroidInputHandler.java b/engine/src/android/com/jme3/input/android/AndroidInputHandler.java index 8fd594030..f2ea5a4b4 100644 --- a/engine/src/android/com/jme3/input/android/AndroidInputHandler.java +++ b/engine/src/android/com/jme3/input/android/AndroidInputHandler.java @@ -41,6 +41,7 @@ import com.jme3.input.event.KeyInputEvent; import com.jme3.input.event.MouseButtonEvent; import com.jme3.input.event.MouseMotionEvent; import com.jme3.input.event.TouchEvent; +import com.jme3.renderer.android.AndroidGLSurfaceView; import com.jme3.system.AppSettings; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.logging.Level; @@ -66,15 +67,18 @@ public class AndroidInputHandler implements TouchInput { // Internal - private View view; + private AndroidGLSurfaceView view; private AndroidTouchHandler touchHandler; private AndroidKeyHandler keyHandler; private AndroidGestureHandler gestureHandler; private boolean initialized = false; private RawInputListener listener = null; private ConcurrentLinkedQueue inputEventQueue = new ConcurrentLinkedQueue(); - 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 float scaleX = 1f; + private float scaleY = 1f; + public AndroidInputHandler() { int buildVersion = Build.VERSION.SDK_INT; @@ -108,7 +112,7 @@ public class AndroidInputHandler implements TouchInput { if (gestureHandler != null) { gestureHandler.setView(view); } - this.view = view; + this.view = (AndroidGLSurfaceView)view; } public View getView() { @@ -116,11 +120,19 @@ public class AndroidInputHandler implements TouchInput { } public float invertX(float origX) { - return view.getWidth()-origX; + return getJmeX(view.getWidth()) - origX; } 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) { @@ -130,6 +142,15 @@ public class AndroidInputHandler implements TouchInput { mouseEventsInvertX = settings.isEmulateMouseFlipX(); mouseEventsInvertY = settings.isEmulateMouseFlipY(); 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}); + } // ----------------------------------------- diff --git a/engine/src/android/com/jme3/input/android/AndroidTouchHandler.java b/engine/src/android/com/jme3/input/android/AndroidTouchHandler.java index a5d2d85ed..8a2679bdc 100644 --- a/engine/src/android/com/jme3/input/android/AndroidTouchHandler.java +++ b/engine/src/android/com/jme3/input/android/AndroidTouchHandler.java @@ -112,6 +112,8 @@ public class AndroidTouchHandler implements View.OnTouchListener { int pointerIndex = getPointerIndex(event); int pointerId = getPointerId(event); Vector2f lastPos = lastPositions.get(pointerId); + float jmeX; + float jmeY; numPointers = event.getPointerCount(); @@ -120,13 +122,15 @@ public class AndroidTouchHandler implements View.OnTouchListener { switch (getAction(event)) { case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_DOWN: + jmeX = androidInput.getJmeX(event.getX(pointerIndex)); + jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex))); 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.setTime(event.getEventTime()); 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); processEvent(touch); @@ -136,8 +140,10 @@ public class AndroidTouchHandler implements View.OnTouchListener { case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: + jmeX = androidInput.getJmeX(event.getX(pointerIndex)); + jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex))); 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.setTime(event.getEventTime()); touch.setPressure(event.getPressure(pointerIndex)); @@ -150,21 +156,23 @@ public class AndroidTouchHandler implements View.OnTouchListener { case MotionEvent.ACTION_MOVE: // Convert all pointers into events 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)); 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); } - float dX = event.getX(p) - lastPos.x; - float dY = androidInput.invertY(event.getY(p)) - lastPos.y; + float dX = jmeX - lastPos.x; + float dY = jmeY - lastPos.y; if (dX != 0 || dY != 0) { 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.setTime(event.getEventTime()); touch.setPressure(event.getPressure(p)); - lastPos.set(event.getX(p), androidInput.invertY(event.getY(p))); + lastPos.set(jmeX, jmeY); processEvent(touch); diff --git a/engine/src/android/com/jme3/input/android/AndroidTouchHandler14.java b/engine/src/android/com/jme3/input/android/AndroidTouchHandler14.java index 1736ea66b..1a785a5e9 100644 --- a/engine/src/android/com/jme3/input/android/AndroidTouchHandler14.java +++ b/engine/src/android/com/jme3/input/android/AndroidTouchHandler14.java @@ -76,6 +76,8 @@ public class AndroidTouchHandler14 extends AndroidTouchHandler implements int pointerId = getPointerId(event); int pointerIndex = getPointerIndex(event); Vector2f lastPos = lastHoverPositions.get(pointerId); + float jmeX; + float jmeY; numPointers = event.getPointerCount(); @@ -85,13 +87,15 @@ public class AndroidTouchHandler14 extends AndroidTouchHandler implements TouchEvent touchEvent; switch (action) { case MotionEvent.ACTION_HOVER_ENTER: + jmeX = androidInput.getJmeX(event.getX(pointerIndex)); + jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex))); 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.setTime(event.getEventTime()); 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); processEvent(touchEvent); @@ -100,21 +104,23 @@ public class AndroidTouchHandler14 extends AndroidTouchHandler implements case MotionEvent.ACTION_HOVER_MOVE: // Convert all pointers into events 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)); 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); } - float dX = event.getX(p) - lastPos.x; - float dY = androidInput.invertY(event.getY(p)) - lastPos.y; + float dX = jmeX - lastPos.x; + float dY = jmeY - lastPos.y; if (dX != 0 || dY != 0) { 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.setTime(event.getEventTime()); touchEvent.setPressure(event.getPressure(p)); - lastPos.set(event.getX(p), androidInput.invertY(event.getY(p))); + lastPos.set(jmeX, jmeY); processEvent(touchEvent); @@ -123,8 +129,10 @@ public class AndroidTouchHandler14 extends AndroidTouchHandler implements consumed = true; break; case MotionEvent.ACTION_HOVER_EXIT: + jmeX = androidInput.getJmeX(event.getX(pointerIndex)); + jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex))); 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.setTime(event.getEventTime()); touchEvent.setPressure(event.getPressure(pointerIndex));