gamecreator Posted September 17, 2013 Share Posted September 17, 2013 I have the following code: context->DrawText("Touch down index 0: " + String(window->TouchDown(0)),5,0); context->DrawText("Touch down index 1: " + String(window->TouchDown(1)),5,30); It works mostly as I expect except for one situation. If I hold one finger down and then a second, they both return one. If I lift my second finger and then the first, they both return to 0. But If after holding both fingers down I lift my first finger and then the second, index 0 returns 0 but index 1 is stuck at 1. If there are no fingers touching the device, shouldn't they both be 0? Link to comment Share on other sites More sharing options...
gamecreator Posted September 17, 2013 Author Share Posted September 17, 2013 More, when I update the code as this: context->DrawText("Touch down index 0: " + String(window->TouchDown(0)) + " pos: " + window->GetTouchPosition(0).ToString(),5,70); context->DrawText("Touch down index 1: " + String(window->TouchDown(1)) + " pos: " + window->GetTouchPosition(1).ToString(),5,100); while holding down the both fingers and moving both, only index 0 updates continuously. Index 1 only updates when I put my finger down after having it up, but not while dragging it across the screen. Am I doing anything wrong or are these bugs? Link to comment Share on other sites More sharing options...
Josh Posted September 17, 2013 Share Posted September 17, 2013 Thank you. It is possible something is funky here. My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Admin Posted September 18, 2013 Share Posted September 18, 2013 This is on Android, right? Link to comment Share on other sites More sharing options...
gamecreator Posted September 18, 2013 Author Share Posted September 18, 2013 Yes (that's where the original thread was posted before it was moved to this forum). Link to comment Share on other sites More sharing options...
Admin Posted October 11, 2013 Share Posted October 11, 2013 Trying to charge a Nexus 7 to test this... Link to comment Share on other sites More sharing options...
Admin Posted October 11, 2013 Share Posted October 11, 2013 I can reproduce this behavior on a Nexus 7. That's a first step. Link to comment Share on other sites More sharing options...
Josh Posted October 11, 2013 Share Posted October 11, 2013 It appears the touch API is more complicated than I thought... http://developer.android.com/reference/android/view/MotionEvent.html My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
gamecreator Posted October 12, 2013 Author Share Posted October 12, 2013 Whoa. That's a lot of options. I hope that makes a ton more sense to you than it does to me. In any case, thank you for looking into it. Link to comment Share on other sites More sharing options...
Josh Posted October 12, 2013 Share Posted October 12, 2013 Makes absolutely no sense to me, but I will mess around with it and see what I get. Just bad design built on top of bad design. My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted October 12, 2013 Share Posted October 12, 2013 Of course, their provided example code doesn't print anything out The reason Android is free is because they could never charge for this. void printSamples(MotionEvent ev) { final int historySize = ev.getHistorySize(); final int pointerCount = ev.getPointerCount(); for (int h = 0; h < historySize; h++) { System.out.printf("At time %d:", ev.getHistoricalEventTime(h)); for (int p = 0; p < pointerCount; p++) { System.out.printf(" pointer %d: (%f,%f)", ev.getPointerId(p), ev.getHistoricalX(p, h), ev.getHistoricalY(p, h)); } } System.out.printf("At time %d:", ev.getEventTime()); for (int p = 0; p < pointerCount; p++) { System.out.printf(" pointer %d: (%f,%f)", ev.getPointerId(p), ev.getX(p), ev.getY(p)); } } My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted October 12, 2013 Share Posted October 12, 2013 This is the program I am using to test: #include "App.h" using namespace Leadwerks; App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {} App::~App() { delete world; delete window; } float angle=25; Joint* joint; bool App::Start() { window = Window::Create(); context = Context::Create(window); world = World::Create(); camera = Camera::Create(); camera->Move(0,0,-4); Font* font = Font::Load("Fonts/arial.ttf",36); context->SetFont(font); return true; } bool App::Loop() { if (window->Closed() || window->KeyDown(Key::Escape)) return false; Time::Update(); world->Update(); context->SetColor(0,0,0,0); context->Clear(); context->SetColor(1,1,1,1); context->SetBlendMode(Blend::Alpha); context->DrawText("Touch down index 0: " + String(window->TouchDown(0)),5,0); context->DrawText("Touch down index 1: " + String(window->TouchDown(1)),5,60); context->SetBlendMode(Blend::Solid); context->Sync(); return true; } And I am using this code in AndroidActivity.Java: @Override public boolean onTouchEvent(MotionEvent event) { //Integer activePointer = (event.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT); //Integer activePointer = event.getActionIndex(); for (int i=0; i<event.getPointerCount(); ++i) { //Integer activePointer = event.getPointerId(0); Integer mActivePointerId = event.getPointerId(i); Integer activePointer = event.findPointerIndex(mActivePointerId); Float x = event.getX(i); Float y = event.getY(i); switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: // Log.i("touchtest", "action_down " + activePointer.toString() + // "(" + x + "," + y + ")"); androidRenderer.touch(x, y, activePointer); break; case MotionEvent.ACTION_MOVE: // Log.i("touchtest", "action_move " + activePointer.toString() + // "(" + x + "," + y + ")"); androidRenderer.move(x, y, activePointer); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: // Log.i("touchtest", "action_up " + activePointer.toString() + "(" // + x + "," + y + ")"); androidRenderer.up(x, y, activePointer); break; } } return true; } My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted October 12, 2013 Share Posted October 12, 2013 More info here: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html I've decided to move on to PC graphics card compatibility testing and am not investing more time in this, for now. Sorry. My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
gamecreator Posted October 12, 2013 Author Share Posted October 12, 2013 Thank you for spending time trying to fix this. As the lack of this feature breaks the most basic mechanic - running and jumping or moving/turning and attacking/shooting - I hope this will eventually be fixed, for most Android customers' sake. 1 Link to comment Share on other sites More sharing options...
Admin Posted October 12, 2013 Share Posted October 12, 2013 http://developer.android.com/training/gestures/multi.html Unlike the older getAction() method, getActionMasked() is designed to work with multiple pointers. That might be the cause of the trouble I had. Layer on top of layer of bad design. Link to comment Share on other sites More sharing options...
Josh Posted October 22, 2013 Share Posted October 22, 2013 This will get fixed from 3.0 but I may need to pull in some outside expertise. 1 My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted October 22, 2013 Share Posted October 22, 2013 I posted here, but new users are moderated and Google appears to have abandon their own forum: https://groups.google.com/forum/#!forum/android-developers I posted another topic about three months back and I guess they haven't gotten around to approving me yet. Ah, here is where the Android developers hang out: http://www.anddev.org/post2256233.html#p2256233 I think I will get an answer there. My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted October 22, 2013 Share Posted October 22, 2013 Oh wow, I just started reading the other posts. That board is totally overtaken by spam. StackOverflow to the rescue: http://stackoverflow.com/questions/19528046/android-multitouch-event-indexes 1 My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
beo6 Posted October 23, 2013 Share Posted October 23, 2013 I haven't played with it yet. But as far as i read in the android documentation you should use MotionEventCompat.getActionMasked(event) for the action to work with multiple pointers and MotionEventCompat.getActionIndex(event) to get the pointer index for that action. But i haven't played much with the NDK myself but it reads pretty clear. Not sure why you are bitshifting there. Link to comment Share on other sites More sharing options...
Josh Posted November 5, 2013 Share Posted November 5, 2013 Working off of this code now: http://stackoverflow.com/questions/14201130/how-does-the-ontouch-event-behave It appears that touch indexes are not persistent. In other words, when touch index zero is lifted, the touches "shift" to the left, and touch index 1 becomes touch index 0. Motion events always indicate touch index 0, so I tried looping through from 0 to event.getPointerCount(), but I get a crash on getEventX(): for (int i = 0; i < event.getPointerCount(); i++) { Log.i("touchtest", "begin_move "); pointerIndex=event.getPointerId(i); x = event.getX(pointerIndex); y = event.getY(pointerIndex); Log.i("touchtest", "action_move " + pointerIndex.toString() + "(" + x + "," + y + ")"); androidRenderer.move(x, y, pointerIndex); } My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted November 5, 2013 Share Posted November 5, 2013 I believe I have the solution. In AndroidActivity.java, replace onTouchEvent with this code: @Override public boolean onTouchEvent(MotionEvent event) { Integer action,pointerIndex,pointerId; Float x,y; action = event.getAction(); pointerIndex = event.getActionIndex();//(action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; //index of this pointer x = event.getX(pointerIndex); y = event.getY(pointerIndex); pointerId = event.getPointerId(pointerIndex); switch (action & MotionEvent.ACTION_MASK){ case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: // Log.i("touchtest", "action_down " + pointerId.toString() + // "(" + x + "," + y + ")"); androidRenderer.touch(x, y, pointerId); break; case MotionEvent.ACTION_MOVE: for (int i = 0; i < event.getPointerCount(); i++) { Log.i("touchtest", "begin_move "); pointerId=event.getPointerId(i); x = event.getX(i); y = event.getY(i); //Log.i("touchtest", "action_move " + pointerId.toString() + // "(" + x + "," + y + ")"); androidRenderer.move(x, y, pointerIndex); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: //Log.i("touchtest", "action_up " + pointerId.toString() + "(" // + x + "," + y + ")"); androidRenderer.up(x, y, pointerId); break; } return true; } In main.cpp replace the Java_com_leadwerks_leandroidb_AndroidRenderer_move function with this code: JNIEXPORT void JNICALL Java_com_leadwerks_leandroidb_AndroidRenderer_move(JNIEnv * env, jobject obj, jfloat x, jfloat y, jint touchId) { if(touchId < 0) return; if (Leadwerks::Window::_TouchPosition[pointerIndex].x!=x || Leadwerks::Window::_TouchPosition[pointerIndex].y!=y) { Leadwerks3D::_TouchPosition[touchId].x = x; Leadwerks3D::_TouchPosition[touchId].y = y; Leadwerks3D::Event(EVENT_TOUCH_MOVE,NULL,touchId,x,y).Emit(); //Leadwerks3D::Print("Move! "+Leadwerks3D::String(x)+", "+Leadwerks3D::String(y)); } } I will upload the fix now. My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted November 5, 2013 Share Posted November 5, 2013 The fix is uploaded. I will leave this topic open for a day or two before closing it. Thanks for being patient. My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
gamecreator Posted November 5, 2013 Author Share Posted November 5, 2013 Thank you. It looks like the touch detection is fixed but position issue isn't yet. Link to comment Share on other sites More sharing options...
Josh Posted November 5, 2013 Share Posted November 5, 2013 My tests indicated touch move events were working correctly. (I printed out the events and could see the numbers corresponding to my input.) Do you have a test that proves otherwise? Drawing some squares on the screen under the touch positions would be a good way to demonstrate it. My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
gamecreator Posted November 5, 2013 Author Share Posted November 5, 2013 I use this code in my existing, updated project but I'll try creating a new project later and retest context->DrawText("Touch down index 0: " + String(window->TouchDown(0)) + " pos: " + window->GetTouchPosition(0).ToString(),5,100); context->DrawText("Touch down index 1: " + String(window->TouchDown(1)) + " pos: " + window->GetTouchPosition(1).ToString(),5,130); Link to comment Share on other sites More sharing options...
Recommended Posts