11package org .andresoviedo .app .model3D .controller ;
22
3+ import org .andresoviedo .app .model3D .model .Object3DData ;
4+ import org .andresoviedo .app .model3D .services .SceneLoader ;
35import org .andresoviedo .app .model3D .view .ModelRenderer ;
6+ import org .andresoviedo .app .model3D .view .ModelSurfaceView ;
7+ import org .andresoviedo .app .util .math .Math3DUtils ;
48
59import android .graphics .PointF ;
6- import android .opengl .GLSurfaceView ;
710import android .opengl .GLU ;
811import android .opengl .Matrix ;
12+ import android .os .SystemClock ;
913import android .util .FloatMath ;
1014import android .util .Log ;
1115import android .view .MotionEvent ;
@@ -20,7 +24,7 @@ public class TouchController {
2024 private static final int TOUCH_STATUS_ROTATING_CAMERA = 4 ;
2125 private static final int TOUCH_STATUS_MOVING_WORLD = 5 ;
2226
23- private GLSurfaceView view ;
27+ private final ModelSurfaceView view ;
2428 private final ModelRenderer mRenderer ;
2529
2630 int pointerCount = 0 ;
@@ -41,17 +45,14 @@ public class TouchController {
4145 float rotation = 0 ;
4246 int currentSquare = Integer .MIN_VALUE ;
4347
44- float [] hit1 = null ;
45- float [] hit2 = null ;
46- float [] hit3 = null ;
47- float [] hit4 = null ;
48- float hitSquare = -1 ;
49- float hitTriangle = -1 ;
5048 boolean isOneFixedAndOneMoving = false ;
5149 boolean fingersAreClosing = false ;
5250 boolean isRotating = false ;
5351
5452 boolean gestureChanged = false ;
53+ private boolean moving = false ;
54+ private boolean simpleTouch = false ;
55+ private long lastActionTime ;
5556 private int touchDelay = -2 ;
5657 private int touchStatus = -1 ;
5758
@@ -64,7 +65,7 @@ public class TouchController {
6465 float [] rotationVector = new float [4 ];
6566 private float previousRotationSquare ;
6667
67- public TouchController (GLSurfaceView view , ModelRenderer renderer ) {
68+ public TouchController (ModelSurfaceView view , ModelRenderer renderer ) {
6869 super ();
6970 this .view = view ;
7071 this .mRenderer = renderer ;
@@ -77,18 +78,33 @@ public synchronized boolean onTouchEvent(MotionEvent motionEvent) {
7778
7879 switch (motionEvent .getActionMasked ()) {
7980 case MotionEvent .ACTION_UP :
80- case MotionEvent .ACTION_DOWN :
8181 case MotionEvent .ACTION_CANCEL :
8282 case MotionEvent .ACTION_POINTER_UP :
83- case MotionEvent .ACTION_POINTER_DOWN :
83+ case MotionEvent .ACTION_HOVER_EXIT :
8484 case MotionEvent .ACTION_OUTSIDE :
85+ // this to handle "1 simple touch"
86+ if (lastActionTime > SystemClock .uptimeMillis () - 250 ) {
87+ simpleTouch = true ;
88+ } else {
89+ gestureChanged = true ;
90+ touchDelay = 0 ;
91+ lastActionTime = SystemClock .uptimeMillis ();
92+ simpleTouch = false ;
93+ }
94+ moving = false ;
95+ break ;
96+ case MotionEvent .ACTION_DOWN :
97+ case MotionEvent .ACTION_POINTER_DOWN :
8598 case MotionEvent .ACTION_HOVER_ENTER :
86- case MotionEvent .ACTION_HOVER_EXIT :
87- Log .d ("Touch" , "Gesture changed..." );
99+ Log .d (TAG , "Gesture changed..." );
88100 gestureChanged = true ;
89101 touchDelay = 0 ;
102+ lastActionTime = SystemClock .uptimeMillis ();
103+ simpleTouch = false ;
90104 break ;
91105 case MotionEvent .ACTION_MOVE :
106+ moving = true ;
107+ simpleTouch = false ;
92108 touchDelay ++;
93109 break ;
94110 default :
@@ -108,9 +124,6 @@ public synchronized boolean onTouchEvent(MotionEvent motionEvent) {
108124 }
109125 dx1 = x1 - previousX1 ;
110126 dy1 = y1 - previousY1 ;
111- hit1 = unproject (x1 , y1 , 0 );
112- hit2 = unproject (x1 , y1 , 1 );
113- // Log.d("Ray", "Ray2---> x:" + xyzw2[0] + " y:" + xyzw2[1] + " z:" + xyzw2[2] + " w(" + xyzw2[3] + ")");
114127 } else if (pointerCount == 2 ) {
115128 x1 = motionEvent .getX (0 );
116129 y1 = motionEvent .getY (0 );
@@ -152,12 +165,6 @@ public synchronized boolean onTouchEvent(MotionEvent motionEvent) {
152165 currentPress1 = motionEvent .getPressure (0 );
153166 currentPress2 = motionEvent .getPressure (1 );
154167 rotation = 0 ;
155- hit1 = unproject (x1 , y1 , 0 );
156- hit2 = unproject (x1 , y1 , 1 );
157- hit3 = unproject (x2 , y2 , 0 );
158- hit4 = unproject (x2 , y2 , 1 );
159- // wzSquare = hit(xyzw3, xyzw2, mRenderer.getmSquare().getPosition());
160- // wzTriangle = hit(xyzw1, xyzw2, mRenderer.getmTriangle().getPosition());
161168 rotation = TouchScreen .getRotation360 (motionEvent );
162169 currentSquare = TouchScreen .getSquare (motionEvent );
163170 if (currentSquare == 1 && previousRotationSquare == 4 ) {
@@ -173,12 +180,17 @@ public synchronized boolean onTouchEvent(MotionEvent motionEvent) {
173180 && rotationVector [2 ] != 0 ;
174181 }
175182
183+ if (pointerCount == 1 && simpleTouch ) {
184+ // calculate the world coordinates where the user is clicking (near plane and far plane)
185+ float [] hit1 = unproject (x1 , y1 , 0 );
186+ float [] hit2 = unproject (x1 , y1 , 1 );
187+ // check if the ray intersect any of our objects and select the nearer
188+ selectObjectImpl (hit1 , hit2 );
189+ }
190+
176191 if (touchDelay > 1 ) {
177192 // INFO: Procesar gesto
178193 if (pointerCount == 1 && currentPress1 > 4.0f ) {
179- // TODO: enable this
180- // hitSquare = hit(hit1, hit2, mRenderer.getScene().getSquare1().getPosition());
181- // hitTriangle = hit(hit1, hit2, mRenderer.getScene().getSquare1().getPosition());
182194 } else if (pointerCount == 1 ) {
183195 touchStatus = TOUCH_STATUS_MOVING_WORLD ;
184196 // Log.i("Touch", "Moving World '" + dx1 + "','" + dy1 + "'...");
@@ -278,7 +290,7 @@ public synchronized boolean onTouchEvent(MotionEvent motionEvent) {
278290
279291 if (gestureChanged && touchDelay > 1 ) {
280292 gestureChanged = false ;
281- Log .i ( "Fin" , "Fin" );
293+ Log .v ( TAG , "Fin" );
282294 }
283295
284296 view .requestRender ();
@@ -287,6 +299,41 @@ public synchronized boolean onTouchEvent(MotionEvent motionEvent) {
287299
288300 }
289301
302+ /**
303+ * Get the nearest object intersecting the specified ray and selects it
304+ *
305+ * @param nearPoint
306+ * the near point in world coordinates
307+ * @param farPoint
308+ * the far point in world coordinates
309+ */
310+ private void selectObjectImpl (float [] nearPoint , float [] farPoint ) {
311+ SceneLoader scene = view .getModelActivity ().getScene ();
312+ if (scene == null ) {
313+ return ;
314+ }
315+ Object3DData objectToSelect = null ;
316+ float objectToSelectDistance = Integer .MAX_VALUE ;
317+ for (Object3DData obj : scene .getObjects ()) {
318+ float distance = Math3DUtils .calculateDistanceOfIntersection (nearPoint , farPoint , obj .getPosition (), 1f );
319+ if (distance != -1 ) {
320+ Log .d (TAG , "Hit object " + obj .getId () + " at distance " + distance );
321+ if (distance < objectToSelectDistance ) {
322+ objectToSelectDistance = distance ;
323+ objectToSelect = obj ;
324+ }
325+ }
326+ }
327+ if (objectToSelect != null ) {
328+ Log .i (TAG , "Selected object " + objectToSelect .getId () + " at distance " + objectToSelectDistance );
329+ if (scene .getSelectedObject () == objectToSelect ) {
330+ scene .setSelectedObject (null );
331+ } else {
332+ scene .setSelectedObject (objectToSelect );
333+ }
334+ }
335+ }
336+
290337 public float [] unproject (float rx , float ry , float rz ) {
291338 float [] xyzw = { 0 , 0 , 0 , 0 };
292339
@@ -303,33 +350,6 @@ public float[] unproject(float rx, float ry, float rz) {
303350 xyzw [3 ] = 1 ;
304351 return xyzw ;
305352 }
306-
307- public float hit (float [] xyzw , float [] xyzw2 , float [] position ) {
308- float zPrecition = 1000f ;
309-
310- float xDif = (xyzw2 [0 ] - xyzw [0 ]) / zPrecition ;
311- float yDif = (xyzw2 [1 ] - xyzw [1 ]) / zPrecition ;
312- float zDif = (xyzw2 [2 ] - xyzw [2 ]) / zPrecition ;
313-
314- // @formatter:off
315- for (int i = 0 ; i < zPrecition ; i ++) {
316- // Log.d("Hit cube", "HIT");
317- double objWidth = 1 ;
318- double objHalfWidth = objWidth /2 ;
319- float xIncr = xDif * i ;
320- if (( xyzw [0 ] + xIncr ) > position [0 ] - objHalfWidth
321- && (xyzw [0 ] + xIncr ) < position [0 ] + objHalfWidth
322- && (xyzw [1 ] + (yDif * i )) > position [1 ] - objHalfWidth
323- && (xyzw [1 ] + (yDif * i )) < position [1 ] + objHalfWidth
324- && (xyzw [2 ] + (zDif * i )) > position [2 ] - objHalfWidth
325- && (xyzw [2 ] + (zDif * i )) < position [2 ] + objHalfWidth ) {
326- Log .w ("Hit" , "HIT: i[" +i +"] wz[" +(xyzw [2 ] + (zDif * i ))+"]" );
327- return xyzw [2 ] + (zDif * i );
328- }
329- }
330- // @formatter:on
331- return -1 ;
332- }
333353}
334354
335355class TouchScreen {
0 commit comments