Project

General

Profile

Download (22.6 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / tutorial / TutorialSurfaceView.java @ 344f290c

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.tutorial;
21

    
22
import android.app.ActivityManager;
23
import android.content.Context;
24
import android.content.pm.ConfigurationInfo;
25
import android.opengl.GLES30;
26
import android.opengl.GLSurfaceView;
27
import android.util.AttributeSet;
28
import android.util.DisplayMetrics;
29
import android.view.MotionEvent;
30

    
31
import com.google.firebase.crashlytics.FirebaseCrashlytics;
32

    
33
import org.distorted.library.type.Static2D;
34
import org.distorted.library.type.Static4D;
35
import org.distorted.main.RubikActivity;
36
import org.distorted.objects.Movement;
37
import org.distorted.objects.TwistyObject;
38
import org.distorted.states.RubikStateSolving;
39
import org.distorted.states.StateList;
40

    
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

    
43
public class TutorialSurfaceView extends GLSurfaceView
44
{
45
    private static final int NUM_SPEED_PROBES = 10;
46
    private static final int INVALID_POINTER_ID = -1;
47

    
48
    // Moving the finger from the middle of the vertical screen to the right edge will rotate a
49
    // given face by SWIPING_SENSITIVITY/2 degrees.
50
    private final static int SWIPING_SENSITIVITY  = 240;
51
    // Moving the finger by 0.3 of an inch will start a Rotation.
52
    private final static float ROTATION_SENSITIVITY = 0.3f;
53

    
54
    private final Static4D CAMERA_POINT = new Static4D(0, 0, 1, 0);
55

    
56
    private TutorialRenderer mRenderer;
57
    private TutorialPreRender mPreRender;
58
    private Movement mMovement;
59
    private boolean mDragging, mBeginningRotation, mContinuingRotation;
60
    private int mScreenWidth, mScreenHeight, mScreenMin;
61

    
62
    private float mRotAngle, mInitDistance;
63
    private int mPtrID1, mPtrID2;
64
    private float mX, mY;
65
    private float mStartRotX, mStartRotY;
66
    private float mAxisX, mAxisY;
67
    private float mRotationFactor;
68
    private int mCurrentAxis, mCurrentRow;
69
    private float mCurrentAngle, mCurrRotSpeed;
70
    private float[] mLastX;
71
    private float[] mLastY;
72
    private long[] mLastT;
73
    private int mFirstIndex, mLastIndex;
74
    private int mDensity;
75

    
76
    private static Static4D mQuat= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
77
    private static Static4D mTemp= new Static4D(0,0,0,1);
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

    
81
    void setScreenSize(int width, int height)
82
      {
83
      mScreenWidth = width;
84
      mScreenHeight= height;
85

    
86
      mScreenMin = Math.min(width, height);
87
      }
88

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

    
91
    boolean isVertical()
92
      {
93
      return mScreenHeight>mScreenWidth;
94
      }
95

    
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

    
98
    TutorialRenderer getRenderer()
99
      {
100
      return mRenderer;
101
      }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

    
105
    TutorialPreRender getPreRender()
106
      {
107
      return mPreRender;
108
      }
109

    
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111

    
112
    void setQuat()
113
      {
114
      mQuat.set(mTemp);
115
      }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
    Static4D getQuat()
120
      {
121
      return mQuat;
122
      }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
    void setMovement(Movement movement)
127
      {
128
      mMovement = movement;
129
      }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
    private Static4D quatFromDrag(float dragX, float dragY)
134
      {
135
      float axisX = dragY;  // inverted X and Y - rotation axis is perpendicular to (dragX,dragY)
136
      float axisY = dragX;  // Why not (-dragY, dragX) ? because Y axis is also inverted!
137
      float axisZ = 0;
138
      float axisL = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
139

    
140
      if( axisL>0 )
141
        {
142
        axisX /= axisL;
143
        axisY /= axisL;
144
        axisZ /= axisL;
145

    
146
        float ratio = axisL;
147
        ratio = ratio - (int)ratio;     // the cos() is only valid in (0,Pi)
148

    
149
        float cosA = (float)Math.cos(Math.PI*ratio);
150
        float sinA = (float)Math.sqrt(1-cosA*cosA);
151

    
152
        return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
153
        }
154

    
155
      return new Static4D(0f, 0f, 0f, 1f);
156
      }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159
// cast the 3D axis we are currently rotating along (which is already casted to the surface of the
160
// currently touched face AND converted into a 4D vector - fourth 0) to a 2D in-screen-surface axis
161

    
162
    private void computeCurrentAxis(Static4D axis)
163
      {
164
      Static4D result = rotateVectorByQuat(axis, mQuat);
165

    
166
      mAxisX =result.get0();
167
      mAxisY =result.get1();
168

    
169
      float len = (float)Math.sqrt(mAxisX*mAxisX + mAxisY*mAxisY);
170
      mAxisX /= len;
171
      mAxisY /= len;
172
      }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175
// return quat1*quat2
176

    
177
    public static Static4D quatMultiply( Static4D quat1, Static4D quat2 )
178
      {
179
      float qx = quat1.get0();
180
      float qy = quat1.get1();
181
      float qz = quat1.get2();
182
      float qw = quat1.get3();
183

    
184
      float rx = quat2.get0();
185
      float ry = quat2.get1();
186
      float rz = quat2.get2();
187
      float rw = quat2.get3();
188

    
189
      float tx = rw*qx - rz*qy + ry*qz + rx*qw;
190
      float ty = rw*qy + rz*qx + ry*qw - rx*qz;
191
      float tz = rw*qz + rz*qw - ry*qx + rx*qy;
192
      float tw = rw*qw - rz*qz - ry*qy - rx*qx;
193

    
194
      return new Static4D(tx,ty,tz,tw);
195
      }
196

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198
// rotate 'vector' by quat  ( i.e. return quat*vector*(quat^-1) )
199

    
200
    public static Static4D rotateVectorByQuat(Static4D vector, Static4D quat)
201
      {
202
      float qx = quat.get0();
203
      float qy = quat.get1();
204
      float qz = quat.get2();
205
      float qw = quat.get3();
206

    
207
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
208
      Static4D tmp = quatMultiply(quat,vector);
209

    
210
      return quatMultiply(tmp,quatInverted);
211
      }
212

    
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214
// rotate 'vector' by quat^(-1)  ( i.e. return (quat^-1)*vector*quat )
215

    
216
    public static Static4D rotateVectorByInvertedQuat(Static4D vector, Static4D quat)
217
      {
218
      float qx = quat.get0();
219
      float qy = quat.get1();
220
      float qz = quat.get2();
221
      float qw = quat.get3();
222

    
223
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
224
      Static4D tmp = quatMultiply(quatInverted,vector);
225

    
226
      return quatMultiply(tmp,quat);
227
      }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
    private void addSpeedProbe(float x, float y)
232
      {
233
      long currTime = System.currentTimeMillis();
234
      boolean theSame = mLastIndex==mFirstIndex;
235

    
236
      mLastIndex++;
237
      if( mLastIndex>=NUM_SPEED_PROBES ) mLastIndex=0;
238

    
239
      mLastT[mLastIndex] = currTime;
240
      mLastX[mLastIndex] = x;
241
      mLastY[mLastIndex] = y;
242

    
243
      if( mLastIndex==mFirstIndex)
244
        {
245
        mFirstIndex++;
246
        if( mFirstIndex>=NUM_SPEED_PROBES ) mFirstIndex=0;
247
        }
248

    
249
      if( theSame )
250
        {
251
        mLastT[mFirstIndex] = currTime;
252
        mLastX[mFirstIndex] = x;
253
        mLastY[mFirstIndex] = y;
254
        }
255
      }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
    private void computeCurrentSpeedInInchesPerSecond()
260
      {
261
      long firstTime = mLastT[mFirstIndex];
262
      long lastTime  = mLastT[mLastIndex];
263
      float fX = mLastX[mFirstIndex];
264
      float fY = mLastY[mFirstIndex];
265
      float lX = mLastX[mLastIndex];
266
      float lY = mLastY[mLastIndex];
267

    
268
      long timeDiff = lastTime-firstTime;
269

    
270
      mLastIndex = 0;
271
      mFirstIndex= 0;
272

    
273
      mCurrRotSpeed = timeDiff>0 ? 1000*retFingerDragDistanceInInches(fX,fY,lX,lY)/timeDiff : 0;
274
      }
275

    
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277

    
278
    private float retFingerDragDistanceInInches(float xFrom, float yFrom, float xTo, float yTo)
279
      {
280
      float xDist = mScreenWidth*(xFrom-xTo);
281
      float yDist = mScreenHeight*(yFrom-yTo);
282
      float distInPixels = (float)Math.sqrt(xDist*xDist + yDist*yDist);
283

    
284
      return distInPixels/mDensity;
285
      }
286

    
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288

    
289
    private void setUpDragOrRotate(float x, float y)
290
      {
291
        Static4D touchPoint = new Static4D(x, y, 0, 0);
292
        Static4D rotatedTouchPoint= rotateVectorByInvertedQuat(touchPoint, mQuat);
293
        Static4D rotatedCamera= rotateVectorByInvertedQuat(CAMERA_POINT, mQuat);
294

    
295
        if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint,rotatedCamera) )
296
          {
297
          mDragging           = false;
298
          mContinuingRotation = false;
299
          mBeginningRotation  = true;
300
          }
301
        else
302
          {
303
          final TutorialActivity act = (TutorialActivity)getContext();
304
          mDragging           = !act.isLocked();
305
          mContinuingRotation = false;
306
          mBeginningRotation  = false;
307
          }
308
      }
309

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

    
312
    private void drag(MotionEvent event, float x, float y)
313
      {
314
      if( mPtrID1!=INVALID_POINTER_ID && mPtrID2!=INVALID_POINTER_ID)
315
        {
316
        int pointer = event.findPointerIndex(mPtrID2);
317
        float pX,pY;
318

    
319
        try
320
          {
321
          pX = event.getX(pointer);
322
          pY = event.getY(pointer);
323
          }
324
        catch(IllegalArgumentException ex)
325
          {
326
          mPtrID1=INVALID_POINTER_ID;
327
          mPtrID2=INVALID_POINTER_ID;
328

    
329
          FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
330
          crashlytics.setCustomKey("DragError", "pointer="+pointer );
331
          crashlytics.recordException(ex);
332

    
333
          return;
334
          }
335

    
336
        float x2 = (pX - mScreenWidth*0.5f)/mScreenMin;
337
        float y2 = (mScreenHeight*0.5f -pY)/mScreenMin;
338

    
339
        float angleNow = getAngle(x,y,x2,y2);
340
        float angleDiff = angleNow-mRotAngle;
341
        float sinA =-(float)Math.sin(angleDiff);
342
        float cosA = (float)Math.cos(angleDiff);
343

    
344
        Static4D dragQuat = quatMultiply(new Static4D(0,0,sinA,cosA), mQuat);
345
        mTemp.set(dragQuat);
346

    
347
        mRotAngle = angleNow;
348

    
349
        float distNow  = (float)Math.sqrt( (x-x2)*(x-x2) + (y-y2)*(y-y2) );
350
        float distQuot = mInitDistance<0 ? 1.0f : distNow/ mInitDistance;
351
        mInitDistance = distNow;
352

    
353
        TwistyObject object = mPreRender.getObject();
354
        if( object!=null ) object.setObjectRatio(distQuot);
355
        }
356
      else
357
        {
358
        Static4D dragQuat = quatMultiply(quatFromDrag(mX-x,y-mY), mQuat);
359
        mTemp.set(dragQuat);
360
        }
361

    
362
      mPreRender.setQuatOnNextRender();
363
      mX = x;
364
      mY = y;
365
      }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
    private void finishRotation()
370
      {
371
      computeCurrentSpeedInInchesPerSecond();
372
      int angle = mPreRender.getObject().computeNearestAngle(mCurrentAngle, mCurrRotSpeed);
373
      mPreRender.finishRotation(angle);
374

    
375
      if( angle!=0 )
376
        {
377
        final TutorialActivity act = (TutorialActivity)getContext();
378
        TutorialState state = act.getState();
379
        state.addMove(mCurrentAxis, mCurrentRow, angle);
380
        }
381

    
382
      mContinuingRotation = false;
383
      mBeginningRotation  = false;
384
      mDragging           = true;
385
      }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

    
389
    private void continueRotation(float x, float y)
390
      {
391
      float dx = x-mStartRotX;
392
      float dy = y-mStartRotY;
393
      float alpha = dx*mAxisX + dy*mAxisY;
394
      float x2 = dx - alpha*mAxisX;
395
      float y2 = dy - alpha*mAxisY;
396

    
397
      float len = (float)Math.sqrt(x2*x2 + y2*y2);
398

    
399
      // we have the length of 1D vector 'angle', now the direction:
400
      float tmp = mAxisY==0 ? -mAxisX*y2 : mAxisY*x2;
401

    
402
      float angle = (tmp>0 ? 1:-1)*len*mRotationFactor;
403
      mCurrentAngle = SWIPING_SENSITIVITY*angle;
404
      mPreRender.getObject().continueRotation(mCurrentAngle);
405

    
406
      addSpeedProbe(x2,y2);
407
      }
408

    
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410

    
411
    private void beginRotation(float x, float y)
412
      {
413
      mStartRotX = x;
414
      mStartRotY = y;
415

    
416
      TwistyObject object = mPreRender.getObject();
417
      int numLayers = object.getNumLayers();
418

    
419
      Static4D touchPoint2 = new Static4D(x, y, 0, 0);
420
      Static4D rotatedTouchPoint2= rotateVectorByInvertedQuat(touchPoint2, mQuat);
421
      Static2D res = mMovement.newRotation(numLayers,rotatedTouchPoint2);
422

    
423
      mCurrentAxis = (int)res.get0();
424
      mCurrentRow  = (int)res.get1();
425

    
426
      computeCurrentAxis( mMovement.getCastedRotAxis(mCurrentAxis) );
427
      mRotationFactor = mMovement.returnRotationFactor(numLayers,mCurrentRow);
428

    
429
      object.beginNewRotation( mCurrentAxis, mCurrentRow );
430

    
431
      addSpeedProbe(x,y);
432

    
433
      mBeginningRotation = false;
434
      mContinuingRotation= true;
435
      }
436

    
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

    
439
    private float getAngle(float x1, float y1, float x2, float y2)
440
      {
441
      return (float) Math.atan2(y1-y2, x1-x2);
442
      }
443

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445

    
446
    private void actionMove(MotionEvent event)
447
      {
448
      int pointer = event.findPointerIndex(mPtrID1 != INVALID_POINTER_ID ? mPtrID1:mPtrID2);
449

    
450
      if( pointer<0 ) return;
451

    
452
      float pX = event.getX(pointer);
453
      float pY = event.getY(pointer);
454

    
455
      float x = (pX - mScreenWidth*0.5f)/mScreenMin;
456
      float y = (mScreenHeight*0.5f -pY)/mScreenMin;
457

    
458
      if( mBeginningRotation )
459
        {
460
        if( retFingerDragDistanceInInches(mX,mY,x,y) > ROTATION_SENSITIVITY )
461
          {
462
          beginRotation(x,y);
463
          }
464
        }
465
      else if( mContinuingRotation )
466
        {
467
        continueRotation(x,y);
468
        }
469
      else if( mDragging )
470
        {
471
        drag(event,x,y);
472
        }
473
      else
474
        {
475
        setUpDragOrRotate(x,y);
476
        }
477
      }
478

    
479
///////////////////////////////////////////////////////////////////////////////////////////////////
480

    
481
    private void actionDown(MotionEvent event)
482
      {
483
      mPtrID1 = event.getPointerId(0);
484

    
485
      float x = event.getX();
486
      float y = event.getY();
487

    
488
      mX = (x - mScreenWidth*0.5f)/mScreenMin;
489
      mY = (mScreenHeight*0.5f -y)/mScreenMin;
490

    
491
      setUpDragOrRotate(mX,mY);
492
      }
493

    
494
///////////////////////////////////////////////////////////////////////////////////////////////////
495

    
496
    private void actionUp(MotionEvent event)
497
      {
498
      mPtrID1 = INVALID_POINTER_ID;
499
      mPtrID2 = INVALID_POINTER_ID;
500

    
501
      if( mContinuingRotation )
502
        {
503
        finishRotation();
504
        }
505
      }
506

    
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

    
509
    private void actionDown2(MotionEvent event)
510
      {
511
      int index = event.getActionIndex();
512

    
513
      if( mPtrID1==INVALID_POINTER_ID )
514
        {
515
        mPtrID1 = event.getPointerId(index);
516
        float x = event.getX();
517
        float y = event.getY();
518

    
519
        if( mPtrID2 != INVALID_POINTER_ID )
520
          {
521
          int pointer = event.findPointerIndex(mPtrID2);
522

    
523
          try
524
            {
525
            float x2 = event.getX(pointer);
526
            float y2 = event.getY(pointer);
527

    
528
            mRotAngle = getAngle(x,-y,x2,-y2);
529
            mInitDistance = -1;
530
            }
531
          catch(IllegalArgumentException ex)
532
            {
533
            mPtrID1=INVALID_POINTER_ID;
534
            mPtrID2=INVALID_POINTER_ID;
535

    
536
            FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
537
            crashlytics.setCustomKey("DragError", "pointer="+pointer );
538
            crashlytics.recordException(ex);
539

    
540
            return;
541
            }
542
          }
543

    
544
        mX = (x - mScreenWidth*0.5f)/mScreenMin;
545
        mY = (mScreenHeight*0.5f -y)/mScreenMin;
546
        }
547
      else if( mPtrID2==INVALID_POINTER_ID )
548
        {
549
        mPtrID2 = event.getPointerId(index);
550

    
551
        float x = event.getX();
552
        float y = event.getY();
553

    
554
        if( mPtrID2 != INVALID_POINTER_ID )
555
          {
556
          int pointer = event.findPointerIndex(mPtrID2);
557

    
558
          try
559
            {
560
            float x2 = event.getX(pointer);
561
            float y2 = event.getY(pointer);
562

    
563
            mRotAngle = getAngle(x,-y,x2,-y2);
564
            mInitDistance = -1;
565
            }
566
          catch(IllegalArgumentException ex)
567
            {
568
            mPtrID1=INVALID_POINTER_ID;
569
            mPtrID2=INVALID_POINTER_ID;
570

    
571
            FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
572
            crashlytics.setCustomKey("DragError", "pointer="+pointer );
573
            crashlytics.recordException(ex);
574

    
575
            return;
576
            }
577
          }
578

    
579
        if( mBeginningRotation || mContinuingRotation )
580
          {
581
          mX = (x - mScreenWidth*0.5f)/mScreenMin;
582
          mY = (mScreenHeight*0.5f -y)/mScreenMin;
583
          }
584
        }
585

    
586
      if( mBeginningRotation )
587
        {
588
        mContinuingRotation = false;
589
        mBeginningRotation  = false;
590
        mDragging           = true;
591
        }
592
      else if( mContinuingRotation )
593
        {
594
        finishRotation();
595
        }
596
      }
597

    
598
///////////////////////////////////////////////////////////////////////////////////////////////////
599

    
600
    private void actionUp2(MotionEvent event)
601
      {
602
      int index = event.getActionIndex();
603

    
604
      if( index==event.findPointerIndex(mPtrID1) )
605
        {
606
        mPtrID1 = INVALID_POINTER_ID;
607
        int pointer = event.findPointerIndex(mPtrID2);
608

    
609
        if( pointer>=0 )
610
          {
611
          float x1 = event.getX(pointer);
612
          float y1 = event.getY(pointer);
613

    
614
          mX = (x1 - mScreenWidth*0.5f)/mScreenMin;
615
          mY = (mScreenHeight*0.5f -y1)/mScreenMin;
616
          }
617
        }
618
      else if( index==event.findPointerIndex(mPtrID2) )
619
        {
620
        mPtrID2 = INVALID_POINTER_ID;
621
        }
622
      }
623

    
624
///////////////////////////////////////////////////////////////////////////////////////////////////
625

    
626
    void initialize()
627
      {
628
      mPtrID1 = INVALID_POINTER_ID;
629
      mPtrID2 = INVALID_POINTER_ID;
630
      }
631

    
632
///////////////////////////////////////////////////////////////////////////////////////////////////
633
// PUBLIC API
634
///////////////////////////////////////////////////////////////////////////////////////////////////
635

    
636
    public TutorialSurfaceView(Context context, AttributeSet attrs)
637
      {
638
      super(context,attrs);
639

    
640
      if(!isInEditMode())
641
        {
642
        mCurrRotSpeed= 0.0f;
643

    
644
        mLastX = new float[NUM_SPEED_PROBES];
645
        mLastY = new float[NUM_SPEED_PROBES];
646
        mLastT = new long[NUM_SPEED_PROBES];
647
        mFirstIndex =0;
648
        mLastIndex  =0;
649

    
650
        mRenderer  = new TutorialRenderer(this);
651
        mPreRender = new TutorialPreRender(this);
652

    
653
        TutorialActivity act = (TutorialActivity)context;
654
        DisplayMetrics dm = new DisplayMetrics();
655
        act.getWindowManager().getDefaultDisplay().getMetrics(dm);
656

    
657
        mDensity = dm.densityDpi;
658

    
659
        final ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
660

    
661
        try
662
          {
663
          final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
664
          int esVersion = configurationInfo.reqGlEsVersion>>16;
665
          setEGLContextClientVersion(esVersion);
666
          setRenderer(mRenderer);
667
          }
668
        catch(Exception ex)
669
          {
670
          act.OpenGLError();
671

    
672
          String shading = GLES30.glGetString(GLES30.GL_SHADING_LANGUAGE_VERSION);
673
          String version = GLES30.glGetString(GLES30.GL_VERSION);
674
          String vendor  = GLES30.glGetString(GLES30.GL_VENDOR);
675
          String renderer= GLES30.glGetString(GLES30.GL_RENDERER);
676

    
677
          FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
678
          crashlytics.setCustomKey("GLSL Version"  , shading );
679
          crashlytics.setCustomKey("GLversion"     , version );
680
          crashlytics.setCustomKey("GL Vendor "    , vendor  );
681
          crashlytics.setCustomKey("GLSLrenderer"  , renderer);
682
          crashlytics.recordException(ex);
683
          }
684
        }
685
      }
686

    
687
///////////////////////////////////////////////////////////////////////////////////////////////////
688

    
689
    @Override
690
    public boolean onTouchEvent(MotionEvent event)
691
      {
692
      int action = event.getActionMasked();
693

    
694
      switch(action)
695
         {
696
         case MotionEvent.ACTION_DOWN        : actionDown(event) ; break;
697
         case MotionEvent.ACTION_MOVE        : actionMove(event) ; break;
698
         case MotionEvent.ACTION_UP          : actionUp(event)   ; break;
699
         case MotionEvent.ACTION_POINTER_DOWN: actionDown2(event); break;
700
         case MotionEvent.ACTION_POINTER_UP  : actionUp2(event)  ; break;
701
         }
702

    
703
      return true;
704
      }
705
}
706

    
(5-5/5)