Project

General

Profile

Download (28 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / main / ObjectControl.java @ 57ef6378

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.objectlib.main;
21

    
22
import java.io.InputStream;
23

    
24
import android.app.Activity;
25
import android.content.SharedPreferences;
26
import android.util.DisplayMetrics;
27
import android.view.MotionEvent;
28

    
29
import org.distorted.library.main.QuatHelper;
30
import org.distorted.library.type.Static4D;
31

    
32
import org.distorted.objectlib.helpers.BlockController;
33
import org.distorted.objectlib.helpers.MovesFinished;
34
import org.distorted.objectlib.helpers.ObjectLibInterface;
35
import org.distorted.objectlib.touchcontrol.TouchControl;
36

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

    
39
public class ObjectControl
40
{
41
    public static final int NUM_SPEED_PROBES = 10;
42
    public static final int INVALID_POINTER_ID = -1;
43

    
44
    public static final int MODE_ROTATE  = 0;
45
    public static final int MODE_DRAG    = 1;
46
    public static final int MODE_REPLACE = 2;
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
    public final static int SWIPING_SENSITIVITY  = 240;
51
    // Moving the finger by 0.3 of an inch will start a Rotation.
52
    public final static float ROTATION_SENSITIVITY = 0.3f;
53

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

    
56
    private final ObjectLibInterface mInterface;
57
    private final ObjectPreRender mPreRender;
58
    private TouchControl mTouchControl;
59
    private TwistyObjectNode mObjectNode;
60
    private boolean mDragging, mBeginningRotation, mContinuingRotation;
61
    private int mScreenWidth, mScreenHeight, mScreenMin;
62
    private float mMoveX, mMoveY;
63

    
64
    private float mRotAngle, mInitDistance;
65
    private float mStartRotX, mStartRotY;
66
    private float mRotationFactor;
67
    private int mLastCubitColor, mLastCubit;
68
    private int mCurrentAxis, mCurrentRow;
69
    private float mCurrentAngle, mCurrRotSpeed;
70
    private final float[] mLastX;
71
    private final float[] mLastY;
72
    private final long[] mLastT;
73
    private int mFirstIndex, mLastIndex;
74
    private final int mDensity;
75

    
76
    private int mPointer1, mPointer2;
77
    private float mX1, mY1, mX2, mY2, mX, mY;
78
    private final boolean mIsAutomatic;
79

    
80
    private boolean mIsLocked, mRemLocked;
81
    private final int[] mBuffer;
82
    private final float[] mAxis;
83

    
84
    private static final Static4D mQuat= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
85
    private static final Static4D mTemp= new Static4D(0,0,0,1);
86

    
87
    private static boolean mForcedIconMode = false;
88

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

    
91
    private void addSpeedProbe(float x, float y)
92
      {
93
      long currTime = System.currentTimeMillis();
94
      boolean theSame = mLastIndex==mFirstIndex;
95

    
96
      mLastIndex++;
97
      if( mLastIndex>=NUM_SPEED_PROBES ) mLastIndex=0;
98

    
99
      mLastT[mLastIndex] = currTime;
100
      mLastX[mLastIndex] = x;
101
      mLastY[mLastIndex] = y;
102

    
103
      if( mLastIndex==mFirstIndex)
104
        {
105
        mFirstIndex++;
106
        if( mFirstIndex>=NUM_SPEED_PROBES ) mFirstIndex=0;
107
        }
108

    
109
      if( theSame )
110
        {
111
        mLastT[mFirstIndex] = currTime;
112
        mLastX[mFirstIndex] = x;
113
        mLastY[mFirstIndex] = y;
114
        }
115
      }
116

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

    
119
    private void computeCurrentSpeedInInchesPerSecond()
120
      {
121
      long firstTime = mLastT[mFirstIndex];
122
      long lastTime  = mLastT[mLastIndex];
123
      float fX = mLastX[mFirstIndex];
124
      float fY = mLastY[mFirstIndex];
125
      float lX = mLastX[mLastIndex];
126
      float lY = mLastY[mLastIndex];
127

    
128
      long timeDiff = lastTime-firstTime;
129

    
130
      mLastIndex = 0;
131
      mFirstIndex= 0;
132

    
133
      mCurrRotSpeed = timeDiff>0 ? 1000*retFingerDragDistanceInInches(fX,fY,lX,lY)/timeDiff : 0;
134
      }
135

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

    
138
    private float retFingerDragDistanceInInches(float xFrom, float yFrom, float xTo, float yTo)
139
      {
140
      float xDist = mScreenWidth*(xFrom-xTo);
141
      float yDist = mScreenHeight*(yFrom-yTo);
142
      float distInPixels = (float)Math.sqrt(xDist*xDist + yDist*yDist);
143

    
144
      return distInPixels/mDensity;
145
      }
146

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148

    
149
    private void replaceMode(boolean down)
150
      {
151
      mBeginningRotation= false;
152

    
153
      if( down )
154
        {
155
        int color = mInterface.getCurrentColor();
156
        float[] point = mTouchControl.getTouchedPoint3D();
157
        TwistyObject object = mPreRender.getObject();
158
        mLastCubit = object.getCubit(point);
159
        mLastCubitColor = mInterface.cubitIsLocked(mLastCubit);
160
        int face;
161

    
162
        if( mLastCubitColor>=0 )
163
          {
164
          face =4;
165
          }
166
        else
167
          {
168
          int touchedFace = mTouchControl.getTouchedFace();
169
          if( mLastCubit<8 ) face = touchedFace;
170
          else
171
            {
172
            switch(touchedFace)
173
              {
174
              case  0: face = mLastCubit==15 || mLastCubit==18 ? 3 : 5; break;
175
              case  1: face = mLastCubit==13 || mLastCubit==16 ? 3 : 5; break;
176
              case  2: face = mLastCubit==10                   ? 5 : 3; break;
177
              case  3: face = mLastCubit== 8                   ? 3 : 5; break;
178
              case  4: face = mLastCubit== 9                   ? 3 : 5; break;
179
              case  5: face = mLastCubit== 8                   ? 5 : 3; break;
180
              default: face =-1;
181
              }
182
            }
183
          }
184

    
185
        mPreRender.setTextureMap( mLastCubit, face , color );
186
        }
187
      }
188

    
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190

    
191
    private void setUpDragOrRotate(boolean down, float x, float y, int mode)
192
      {
193
      if( mode==MODE_DRAG )
194
        {
195
        mDragging           = true;
196
        mBeginningRotation  = false;
197
        mContinuingRotation = false;
198
        }
199
      else
200
        {
201
        CAMERA_POINT.set2( mObjectNode.getCameraDist() );
202
        Static4D touchPoint = new Static4D(x, y, 0, 0);
203
        Static4D rotatedTouchPoint= QuatHelper.rotateVectorByInvertedQuat(touchPoint, mQuat);
204
        Static4D rotatedCamera= QuatHelper.rotateVectorByInvertedQuat(CAMERA_POINT, mQuat);
205

    
206
        if( mTouchControl!=null && mTouchControl.objectTouched(rotatedTouchPoint,rotatedCamera) )
207
          {
208
          mDragging           = false;
209
          mContinuingRotation = false;
210

    
211
               if( mode==MODE_ROTATE  ) mBeginningRotation = !mPreRender.isTouchBlocked();
212
          else if( mode==MODE_REPLACE ) replaceMode(down);
213
          }
214
        else
215
          {
216
          mDragging           = (!mIsLocked || mIsAutomatic);
217
          mBeginningRotation  = false;
218
          mContinuingRotation = false;
219
          if( !mDragging ) mInterface.failedToDrag();
220
          }
221
        }
222
      }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
    private void drag(float x, float y)
227
      {
228
      if( mPointer1!=INVALID_POINTER_ID && mPointer2!=INVALID_POINTER_ID)
229
        {
230
        float x2 = (mX2 - mScreenWidth*0.5f)/mScreenMin;
231
        float y2 = (mScreenHeight*0.5f - mY2)/mScreenMin;
232

    
233
        float angleNow = getAngle(x,y,x2,y2);
234
        float angleDiff = angleNow-mRotAngle;
235
        float sinA =-(float)Math.sin(angleDiff);
236
        float cosA = (float)Math.cos(angleDiff);
237

    
238
        Static4D dragQuat = QuatHelper.quatMultiply(new Static4D(0,0,sinA,cosA), mQuat);
239
        mTemp.set(dragQuat);
240

    
241
        mRotAngle = angleNow;
242

    
243
        float distNow  = (float)Math.sqrt( (x-x2)*(x-x2) + (y-y2)*(y-y2) );
244
        float distQuot = mInitDistance<0 ? 1.0f : distNow/ mInitDistance;
245
        mInitDistance = distNow;
246
        TwistyObject object = mPreRender.getObject();
247
        if( object!=null ) object.setObjectRatio(distQuot, mObjectNode.getMinSize() );
248
        }
249
      else
250
        {
251
        Static4D dragQuat = QuatHelper.quatMultiply(QuatHelper.quatFromDrag(mX-x,y-mY), mQuat);
252
        mTemp.set(dragQuat);
253
        }
254

    
255
      mPreRender.setQuatOnNextRender();
256
      mX = x;
257
      mY = y;
258
      }
259

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

    
262
    private void finishRotation()
263
      {
264
      TwistyObject object = mPreRender.getObject();
265
      int[] angles = object.getBasicAngle();
266

    
267
      if( mCurrentAxis<angles.length )
268
        {
269
        computeCurrentSpeedInInchesPerSecond();
270

    
271
        int angle = object.computeNearestAngle(mCurrentAxis,mCurrentAngle, mCurrRotSpeed);
272
        mPreRender.finishRotation(angle);
273
        mPreRender.rememberMove(mCurrentAxis,mCurrentRow,angle);
274

    
275
        if( angle!=0 )
276
          {
277
          int basicAngle= angles[mCurrentAxis];
278
          int realAngle = (angle*basicAngle)/360;
279
          mInterface.onFinishRotation(mCurrentAxis,mCurrentRow,realAngle);
280
          }
281

    
282
        mContinuingRotation = false;
283
        mBeginningRotation  = false;
284
        mDragging           = true;
285
        }
286
      }
287

    
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

    
290
    private void continueRotation(float x, float y)
291
      {
292
      float dx = x-mStartRotX;
293
      float dy = y-mStartRotY;
294
      float alpha = dx*mAxis[0] + dy*mAxis[1];
295
      float x2 = dx - alpha*mAxis[0];
296
      float y2 = dy - alpha*mAxis[1];
297

    
298
      float len = (float)Math.sqrt(x2*x2 + y2*y2);
299

    
300
      // we have the length of 1D vector 'angle', now the direction:
301
      float tmp = mAxis[1]==0 ? -mAxis[0]*y2 : mAxis[1]*x2;
302

    
303
      float angle = (tmp>0 ? 1:-1)*len*mRotationFactor;
304
      mCurrentAngle = SWIPING_SENSITIVITY*angle;
305
      mPreRender.getObject().continueRotation(mCurrentAngle);
306

    
307
      addSpeedProbe(x2,y2);
308
      }
309

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

    
312
    private void beginRotation(float x, float y)
313
      {
314
      mStartRotX = x;
315
      mStartRotY = y;
316

    
317
      TwistyObject object = mPreRender.getObject();
318
      int[] numLayers = object.getNumLayers();
319

    
320
      Static4D touchPoint = new Static4D(x, y, 0, 0);
321
      Static4D rotatedTouchPoint= QuatHelper.rotateVectorByInvertedQuat(touchPoint, mQuat);
322
      mTouchControl.newRotation(mBuffer,rotatedTouchPoint);
323

    
324
      mCurrentAxis = mBuffer[0];
325
      mCurrentRow  = mBuffer[1];
326

    
327
      mTouchControl.getCastedRotAxis(mAxis,mQuat,mCurrentAxis);
328
      mRotationFactor = mTouchControl.returnRotationFactor(numLayers,mCurrentRow);
329

    
330
      object.beginNewRotation( mCurrentAxis, mCurrentRow );
331

    
332
      mInterface.onBeginRotation();
333

    
334
      addSpeedProbe(x,y);
335

    
336
      mBeginningRotation = false;
337
      mContinuingRotation= true;
338
      }
339

    
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

    
342
    private float getAngle(float x1, float y1, float x2, float y2)
343
      {
344
      return (float) Math.atan2(y1-y2, x1-x2);
345
      }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348

    
349
    private void prepareDown(MotionEvent event)
350
      {
351
      mPointer1 = event.getPointerId(0);
352
      mX1 = event.getX() - mMoveX;
353
      mY1 = event.getY() + mMoveY;
354
      mPointer2 = INVALID_POINTER_ID;
355
      }
356

    
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358

    
359
    private void prepareMove(MotionEvent event)
360
      {
361
      int index1 = event.findPointerIndex(mPointer1);
362

    
363
      if( index1>=0 )
364
        {
365
        mX1 = event.getX(index1) - mMoveX;
366
        mY1 = event.getY(index1) + mMoveY;
367
        }
368

    
369
      int index2 = event.findPointerIndex(mPointer2);
370

    
371
      if( index2>=0 )
372
        {
373
        mX2 = event.getX(index2) - mMoveX;
374
        mY2 = event.getY(index2) + mMoveY;
375
        }
376
      }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
    private void prepareUp(MotionEvent event)
381
      {
382
      mPointer1 = INVALID_POINTER_ID;
383
      mPointer2 = INVALID_POINTER_ID;
384
      }
385

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387

    
388
    private void prepareDown2(MotionEvent event)
389
      {
390
      int index = event.getActionIndex();
391

    
392
      if( mPointer1==INVALID_POINTER_ID )
393
        {
394
        mPointer1 = event.getPointerId(index);
395
        mX1 = event.getX(index) - mMoveX;
396
        mY1 = event.getY(index) + mMoveY;
397
        }
398
      else if( mPointer2==INVALID_POINTER_ID )
399
        {
400
        mPointer2 = event.getPointerId(index);
401
        mX2 = event.getX(index) - mMoveX;
402
        mY2 = event.getY(index) + mMoveY;
403
        }
404
      }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
    private void prepareUp2(MotionEvent event)
409
      {
410
      int index = event.getActionIndex();
411

    
412
           if( index==event.findPointerIndex(mPointer1) ) mPointer1 = INVALID_POINTER_ID;
413
      else if( index==event.findPointerIndex(mPointer2) ) mPointer2 = INVALID_POINTER_ID;
414
      }
415

    
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

    
418
    private void actionMove(float x1, float y1, float x2, float y2, int mode)
419
      {
420
      float pX = mPointer1 != INVALID_POINTER_ID ? x1 : x2;
421
      float pY = mPointer1 != INVALID_POINTER_ID ? y1 : y2;
422

    
423
      float x = (pX - mScreenWidth*0.5f)/mScreenMin;
424
      float y = (mScreenHeight*0.5f -pY)/mScreenMin;
425

    
426
      if( mBeginningRotation )
427
        {
428
        if( retFingerDragDistanceInInches(mX,mY,x,y) > ROTATION_SENSITIVITY )
429
          {
430
          beginRotation(x,y);
431
          }
432
        }
433
      else if( mContinuingRotation )
434
        {
435
        continueRotation(x,y);
436
        }
437
      else if( mDragging )
438
        {
439
        drag(x,y);
440
        }
441
      else
442
        {
443
        setUpDragOrRotate(false,x,y,mode);
444
        }
445
      }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

    
449
    private void actionDown(float x, float y, int mode)
450
      {
451
      mX = (x -  mScreenWidth*0.5f)/mScreenMin;
452
      mY = (mScreenHeight*0.5f - y)/mScreenMin;
453

    
454
      setUpDragOrRotate(true,mX,mY,mode);
455
      }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

    
459
    private void actionUp()
460
      {
461
      if( mContinuingRotation )
462
        {
463
        finishRotation();
464
        }
465

    
466
      if( mLastCubitColor>=0 )
467
        {
468
        mPreRender.setTextureMap( mLastCubit, 4, mLastCubitColor );
469
        mLastCubitColor = -1;
470
        }
471
      }
472

    
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474

    
475
    private void actionDown2(float x1, float y1, float x2, float y2)
476
      {
477
      mRotAngle = getAngle(x1,-y1, x2,-y2);
478
      mInitDistance = -1;
479

    
480
      mX = (x1 - mScreenWidth*0.5f )/mScreenMin;
481
      mY = (mScreenHeight*0.5f - y1)/mScreenMin;
482

    
483
      if( mBeginningRotation )
484
        {
485
        mContinuingRotation = false;
486
        mBeginningRotation  = false;
487
        mDragging           = true;
488
        }
489
      else if( mContinuingRotation )
490
        {
491
        finishRotation();
492
        }
493
      }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
    private void actionUp2(boolean p1isUp, float x1, float y1, boolean p2isUp, float x2, float y2)
498
      {
499
      if( p1isUp )
500
        {
501
        mX = (x2 -  mScreenWidth*0.5f)/mScreenMin;
502
        mY = (mScreenHeight*0.5f - y2)/mScreenMin;
503
        }
504
      if( p2isUp )
505
        {
506
        mX = (x1 -  mScreenWidth*0.5f)/mScreenMin;
507
        mY = (mScreenHeight*0.5f - y1)/mScreenMin;
508
        }
509
      }
510

    
511
///////////////////////////////////////////////////////////////////////////////////////////////////
512

    
513
    void setMovement(TouchControl touchControl)
514
      {
515
      mTouchControl = touchControl;
516
      }
517

    
518
///////////////////////////////////////////////////////////////////////////////////////////////////
519
// INTERNAL API (for AutomaticControl)
520
///////////////////////////////////////////////////////////////////////////////////////////////////
521

    
522
    public ObjectPreRender getPreRender()
523
      {
524
      return mPreRender;
525
      }
526

    
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528

    
529
    public ObjectLibInterface getInterface()
530
      {
531
      return mInterface;
532
      }
533

    
534
///////////////////////////////////////////////////////////////////////////////////////////////////
535

    
536
    public static void setIconMode(boolean mode)
537
      {
538
      mForcedIconMode = mode;
539
      }
540

    
541
///////////////////////////////////////////////////////////////////////////////////////////////////
542

    
543
    public static boolean isInIconMode()
544
      {
545
      return mForcedIconMode;
546
      }
547

    
548
///////////////////////////////////////////////////////////////////////////////////////////////////
549
// PUBLIC API
550
///////////////////////////////////////////////////////////////////////////////////////////////////
551

    
552
    public ObjectControl(Activity act, ObjectLibInterface actioner)
553
      {
554
      mIsAutomatic = false;
555

    
556
      mBuffer = new int[2];
557
      mAxis   = new float[2];
558

    
559
      mLastCubitColor = -1;
560
      mCurrRotSpeed   = 0.0f;
561

    
562
      mLastX = new float[NUM_SPEED_PROBES];
563
      mLastY = new float[NUM_SPEED_PROBES];
564
      mLastT = new long[NUM_SPEED_PROBES];
565
      mFirstIndex =0;
566
      mLastIndex  =0;
567

    
568
      DisplayMetrics dm = new DisplayMetrics();
569
      act.getWindowManager().getDefaultDisplay().getMetrics(dm);
570

    
571
      mDensity = dm.densityDpi;
572

    
573
      mPreRender = new ObjectPreRender(act,this,actioner);
574
      mInterface = actioner;
575
      }
576

    
577
///////////////////////////////////////////////////////////////////////////////////////////////////
578

    
579
    public TwistyObjectNode getNode()
580
      {
581
      return mObjectNode;
582
      }
583

    
584
///////////////////////////////////////////////////////////////////////////////////////////////////
585

    
586
    public void createNode(int width, int height)
587
      {
588
      if( mObjectNode==null ) mObjectNode = new TwistyObjectNode(width,height);
589
      }
590

    
591
///////////////////////////////////////////////////////////////////////////////////////////////////
592

    
593
    public void setScreenSize(int width, int height)
594
      {
595
      mScreenWidth = width;
596
      mScreenHeight= height;
597
      mScreenMin   = Math.min(width,height);
598

    
599
      if( mObjectNode!=null ) mObjectNode.setSize(width,height);
600

    
601
      TwistyObject object = mPreRender.getObject();
602

    
603
      if( object!=null )
604
        {
605
        object.setTexture();
606
        object.setNodeSize(mScreenMin);
607
        }
608
      }
609

    
610
///////////////////////////////////////////////////////////////////////////////////////////////////
611

    
612
    public void setObjectMove(int xmove, int ymove)
613
      {
614
      mMoveX = xmove;
615
      mMoveY = ymove;
616

    
617
      mPreRender.setMove(xmove,ymove);
618
      }
619

    
620
///////////////////////////////////////////////////////////////////////////////////////////////////
621

    
622
    public void setObjectScale(float scale)
623
      {
624
      mPreRender.setScale(scale);
625
      }
626

    
627
///////////////////////////////////////////////////////////////////////////////////////////////////
628

    
629
    public void onPause()
630
      {
631
      BlockController.onPause();
632
      }
633

    
634
///////////////////////////////////////////////////////////////////////////////////////////////////
635

    
636
    public void onResume()
637
      {
638
      mPointer1 = INVALID_POINTER_ID;
639
      mPointer2 = INVALID_POINTER_ID;
640

    
641
      unlock();
642

    
643
      BlockController.onResume();
644
      }
645

    
646
///////////////////////////////////////////////////////////////////////////////////////////////////
647

    
648
    public void rotateNow(Static4D quat)
649
      {
650
      mTemp.set(quat);
651
      mQuat.set(mTemp);
652
      }
653

    
654
///////////////////////////////////////////////////////////////////////////////////////////////////
655

    
656
    public void scaleNow(float scale)
657
      {
658
      mPreRender.getObject().setObjectRatioNow(scale,mObjectNode.getMinSize() );
659
      }
660

    
661
///////////////////////////////////////////////////////////////////////////////////////////////////
662

    
663
    public void setQuat()
664
      {
665
      mQuat.set(mTemp);
666
      }
667

    
668
///////////////////////////////////////////////////////////////////////////////////////////////////
669

    
670
    public Static4D getQuat()
671
      {
672
      return mQuat;
673
      }
674

    
675
///////////////////////////////////////////////////////////////////////////////////////////////////
676

    
677
    public void preRender()
678
      {
679
      mPreRender.preRender();
680
      }
681

    
682
///////////////////////////////////////////////////////////////////////////////////////////////////
683

    
684
    public void blockEverything(int place)
685
      {
686
      setLock(true);
687
      mPreRender.blockEverything(place);
688
      }
689

    
690
///////////////////////////////////////////////////////////////////////////////////////////////////
691

    
692
    public void blockTouch(int place)
693
      {
694
      setLock(true);
695
      mPreRender.blockTouch(place);
696
      }
697

    
698
///////////////////////////////////////////////////////////////////////////////////////////////////
699

    
700
    public void unblockEverything()
701
      {
702
      unsetLock();
703
      mPreRender.unblockEverything();
704
      }
705

    
706
///////////////////////////////////////////////////////////////////////////////////////////////////
707

    
708
    public void unblockTouch()
709
      {
710
      unsetLock();
711
      mPreRender.unblockTouch();
712
      }
713

    
714
///////////////////////////////////////////////////////////////////////////////////////////////////
715

    
716
    public void unblockUI()
717
      {
718
      mPreRender.unblockUI();
719
      }
720

    
721
///////////////////////////////////////////////////////////////////////////////////////////////////
722

    
723
    public boolean isTouchBlocked()
724
      {
725
      return mPreRender.isTouchBlocked();
726
      }
727

    
728
///////////////////////////////////////////////////////////////////////////////////////////////////
729

    
730
    public boolean isUINotBlocked()
731
      {
732
      return mPreRender.isUINotBlocked();
733
      }
734

    
735
///////////////////////////////////////////////////////////////////////////////////////////////////
736

    
737
    public void initializeObject(int[][] moves)
738
      {
739
      mPreRender.initializeObject(moves);
740
      }
741

    
742
///////////////////////////////////////////////////////////////////////////////////////////////////
743

    
744
    public void changeObject(int ordinal, InputStream jsonStream, InputStream meshStream)
745
      {
746
      mPreRender.changeObject(ordinal, jsonStream, meshStream);
747
      }
748

    
749
///////////////////////////////////////////////////////////////////////////////////////////////////
750

    
751
    public void changeIfDifferent(int ordinal, InputStream jsonStream, InputStream meshStream)
752
      {
753
      TwistyObject object = mPreRender.getObject();
754
      ObjectType old = object==null ? null : object.getObjectType();
755

    
756
      if( old==null || old.ordinal() != ordinal )
757
        {
758
        mPreRender.changeObject(ordinal, jsonStream, meshStream);
759
        }
760
      }
761

    
762
///////////////////////////////////////////////////////////////////////////////////////////////////
763

    
764
    public void scrambleObject(int num)
765
      {
766
      mPreRender.scrambleObject(num);
767
      }
768

    
769
///////////////////////////////////////////////////////////////////////////////////////////////////
770

    
771
    public void solveObject()
772
      {
773
      mPreRender.solveObject();
774
      }
775

    
776
///////////////////////////////////////////////////////////////////////////////////////////////////
777

    
778
    public void solveOnly()
779
      {
780
      mPreRender.solveOnly();
781
      }
782

    
783
///////////////////////////////////////////////////////////////////////////////////////////////////
784

    
785
    public void addRotation(MovesFinished listener, int axis, int rowBitmap, int angle, int duration)
786
      {
787
      mPreRender.addRotation(listener,axis,rowBitmap,angle,duration);
788
      }
789

    
790
///////////////////////////////////////////////////////////////////////////////////////////////////
791

    
792
    public void resetAllTextureMaps()
793
      {
794
      mPreRender.resetAllTextureMaps();
795
      }
796

    
797
///////////////////////////////////////////////////////////////////////////////////////////////////
798

    
799
    public TwistyObject getObject()
800
      {
801
      return mPreRender.getObject();
802
      }
803

    
804
///////////////////////////////////////////////////////////////////////////////////////////////////
805

    
806
    public void savePreferences(SharedPreferences.Editor editor)
807
      {
808
      mPreRender.savePreferences(editor);
809
      }
810

    
811
///////////////////////////////////////////////////////////////////////////////////////////////////
812

    
813
    public void restorePreferences(SharedPreferences preferences)
814
      {
815
      mPreRender.restorePreferences(preferences);
816
      }
817
///////////////////////////////////////////////////////////////////////////////////////////////////
818

    
819
    public boolean retLocked()
820
      {
821
      return mIsLocked;
822
      }
823

    
824
///////////////////////////////////////////////////////////////////////////////////////////////////
825

    
826
    public void toggleLock()
827
      {
828
      mIsLocked = !mIsLocked;
829
      }
830

    
831
///////////////////////////////////////////////////////////////////////////////////////////////////
832

    
833
    public void unlock()
834
      {
835
      mIsLocked = false;
836
      }
837

    
838
///////////////////////////////////////////////////////////////////////////////////////////////////
839

    
840
    public void setLock(boolean value)
841
      {
842
      mRemLocked = mIsLocked;
843
      mIsLocked = value;
844
      }
845

    
846
///////////////////////////////////////////////////////////////////////////////////////////////////
847

    
848
    public void unsetLock()
849
      {
850
      mIsLocked = mRemLocked;
851
      }
852

    
853
///////////////////////////////////////////////////////////////////////////////////////////////////
854

    
855
    public boolean onTouchEvent(MotionEvent event, int mode)
856
      {
857
      int action = event.getActionMasked();
858

    
859
      switch(action)
860
         {
861
         case MotionEvent.ACTION_DOWN        : prepareDown(event);
862
                                               actionDown(mX1, mY1, mode);
863
                                               break;
864
         case MotionEvent.ACTION_MOVE        : prepareMove(event);
865
                                               actionMove(mX1, mY1, mX2, mY2, mode);
866
                                               break;
867
         case MotionEvent.ACTION_UP          : prepareUp(event);
868
                                               actionUp();
869
                                               break;
870
         case MotionEvent.ACTION_POINTER_DOWN: prepareDown2(event);
871
                                               actionDown2(mX1, mY1, mX2, mY2);
872
                                               break;
873
         case MotionEvent.ACTION_POINTER_UP  : prepareUp2(event);
874
                                               boolean p1isUp = mPointer1==INVALID_POINTER_ID;
875
                                               boolean p2isUp = mPointer2==INVALID_POINTER_ID;
876
                                               actionUp2(p1isUp, mX1, mY1, p2isUp, mX2, mY2);
877
                                               break;
878
         }
879

    
880
      return true;
881
      }
882
}
883

    
(2-2/12)