Small bug in AndroidInput

Hi everyone,



So I finally got an Android tablet and have started working on the android version of env3d (http://env3d.org). I found a very small bug in the AndroidInput’s MOVE delta calculation. Here is the relevant code:



[java]

case MotionEvent.ACTION_POINTER_UP:

case MotionEvent.ACTION_CANCEL:

case MotionEvent.ACTION_UP:

touch = getNextFreeTouchEvent();

touch.set(Type.UP, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), 0, 0);

touch.setPointerId(pointerId);

touch.setTime(event.getEventTime());

touch.setPressure(event.getPressure(pointerIndex));

processEvent(touch);



bWasHandled = true;

break;

case MotionEvent.ACTION_MOVE:

// Convert all pointers into events

for (int p = 0; p < event.getPointerCount(); p++) {

Vector2f lastPos = lastPositions.get§;

if (lastPos == null) {

lastPos = new Vector2f(event.getX§, this.getHeight() - event.getY§);

lastPositions.put(event.getPointerId§, lastPos);

}

touch = getNextFreeTouchEvent();

touch.set(Type.MOVE, event.getX§, this.getHeight() - event.getY§, event.getX§ - lastPos.x, this.getHeight() - event.getY§ - lastPos.y);

touch.setPointerId(event.getPointerId§);

touch.setTime(event.getEventTime());

touch.setPressure(event.getPressure§);

processEvent(touch);

lastPos.set(event.getX§, this.getHeight() - event.getY§);

}

bWasHandled = true;

break;

[/java]



The way the deltaX and deltaY are calculated is by first remembering the lastPos vector for the particular pointerID. This works great the first time but once the pointer is lifted, the lastPos vector remains in the lastPositions HashMap and the next time the screen is touched with the same pointerId, the lastPosition from the last touch event is retrieved and the incorrect deltaX and deltaY are calculated.



I think the solution is to remove the lastPos vector once the pointer is no longer valid, the following is my solution:



[patch]

This patch file was generated by NetBeans IDE

It uses platform neutral UTF-8 encoding and n newlines.

— Base (BASE)

+++ Locally Modified (Based On LOCAL)

@@ -254,6 +254,10 @@

touch.setPressure(event.getPressure(pointerIndex));

processEvent(touch);


  •            // user has pressed up, remove the lastPosition<br />
    
  •            System.out.println(&quot;removing last position &quot;+pointerIndex);<br />
    
  •            lastPositions.remove(event.getPointerId(pointerIndex));<br />
    

+

bWasHandled = true;

break;

case MotionEvent.ACTION_MOVE:

[/patch]



Please review and commit if approved.



Thanks!

3 Likes

I committed a change that removed the lastPosition on the UP as well as recorded the lastPosition on the DOWN.



[java]

This patch file was generated by NetBeans IDE

Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3_Reposrcandroidcomjme3inputandroid

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: AndroidInput.java

— AndroidInput.java Base (BASE)

+++ AndroidInput.java Locally Modified (Based On LOCAL)

@@ -227,6 +227,7 @@

int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)

>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;

int pointerId = event.getPointerId(pointerIndex);

  •    Vector2f lastPos = lastPositions.get(pointerId);<br />
    

// final int historySize = event.getHistorySize();
//final int pointerCount = event.getPointerCount();
@@ -240,6 +241,9 @@
touch.setPressure(event.getPressure(pointerIndex));
processEvent(touch);

+ lastPos = new Vector2f(event.getX(pointerIndex), view.getHeight() - event.getY(pointerIndex));
+ lastPositions.put(pointerId, lastPos);
+
bWasHandled = true;
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -251,13 +255,14 @@
touch.setTime(event.getEventTime());
touch.setPressure(event.getPressure(pointerIndex));
processEvent(touch);
+ lastPositions.remove(pointerId);

bWasHandled = true;
break;
case MotionEvent.ACTION_MOVE:
// Convert all pointers into events
for (int p = 0; p < event.getPointerCount(); p++) {
- Vector2f lastPos = lastPositions.get(p);
+ lastPos = lastPositions.get(p);
if (lastPos == null) {
lastPos = new Vector2f(event.getX(p), view.getHeight() - event.getY(p));
lastPositions.put(event.getPointerId(p), lastPos);
[/java]
3 Likes