Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / main / ObjectControl.java @ 09ff1631

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.main;
11

    
12
import static org.distorted.objectlib.helpers.OperatingSystemInterface.*;
13

    
14
import org.distorted.library.main.QuatHelper;
15
import org.distorted.library.type.Static4D;
16

    
17
import org.distorted.objectlib.effects.BaseEffect;
18
import org.distorted.objectlib.helpers.BlockController;
19
import org.distorted.objectlib.helpers.MovesFinished;
20
import org.distorted.objectlib.helpers.ObjectLibInterface;
21
import org.distorted.objectlib.helpers.OperatingSystemInterface;
22
import org.distorted.objectlib.touchcontrol.TouchControl;
23
import org.distorted.objectlib.touchcontrol.TouchControlShapeChanging;
24

    
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26

    
27
public class ObjectControl
28
{
29
    public static final int MAX_MOVING_PARTS = 242; // Gigaminx
30
    public static final int MAX_QUATS = 60;         // Gigaminx: 60 quats group.
31

    
32
    public static final int NUM_SPEED_PROBES = 10;
33

    
34
    public static final int MODE_ROTATE  = 0;
35
    public static final int MODE_DRAG    = 1;
36
    public static final int MODE_REPLACE = 2;
37
    public static final int MODE_NOTHING = 3;
38

    
39
    // Moving the finger from the middle of the vertical screen to the right edge will rotate a
40
    // given face by SWIPING_SENSITIVITY/2 degrees.
41
    public final static int SWIPING_SENSITIVITY  = 240;
42
    // Moving the finger by 0.3 of an inch will start a Rotation.
43
    public final static float ROTATION_SENSITIVITY = 0.3f;
44

    
45
    private final Static4D CAMERA_POINT = new Static4D(0, 0, 0, 0);
46

    
47
    private final ObjectLibInterface mInterface;
48
    private final OperatingSystemInterface mOS;
49
    private final ObjectPreRender mPreRender;
50
    private TouchControl mTouchControl;
51
    private TwistyObjectNode mObjectNode;
52
    private boolean mDragging, mBeginningRotation, mContinuingRotation;
53
    private int mScreenWidth, mScreenHeight, mScalingSize;
54
    private float mMoveX, mMoveY;
55
    private int mLastMode;
56

    
57
    private float mRotAngle, mInitDistance;
58
    private float mStartRotX, mStartRotY;
59
    private float mRotationFactor;
60
    private int mCurrentAxis, mCurrentRow;
61
    private float mCurrentAngle, mCurrRotSpeed;
62
    private final float[] mLastX;
63
    private final float[] mLastY;
64
    private final long[] mLastT;
65
    private int mFirstIndex, mLastIndex;
66
    private final int mDensity;
67

    
68
    private float mX1, mY1, mX2, mY2, mX, mY;
69
    private final boolean mIsAutomatic;
70

    
71
    private boolean mIsLocked, mRemLocked;
72
    private final int[] mBuffer;
73
    private final float[] mAxis;
74
    private int mMeshState, mIconMode;
75
    private boolean mRotateOnCreation;
76
    private final Static4D mQuat,mTemp;
77
    private boolean mRotAxisIsNormal;
78
    private final float[] mNormalTouchPoint;
79
    private float mNormalRotAngle;
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

    
83
    private void addSpeedProbe(float x, float y)
84
      {
85
      long currTime = System.currentTimeMillis();
86
      boolean theSame = mLastIndex==mFirstIndex;
87

    
88
      mLastIndex++;
89
      if( mLastIndex>=NUM_SPEED_PROBES ) mLastIndex=0;
90

    
91
      mLastT[mLastIndex] = currTime;
92
      mLastX[mLastIndex] = x;
93
      mLastY[mLastIndex] = y;
94

    
95
      if( mLastIndex==mFirstIndex)
96
        {
97
        mFirstIndex++;
98
        if( mFirstIndex>=NUM_SPEED_PROBES ) mFirstIndex=0;
99
        }
100

    
101
      if( theSame )
102
        {
103
        mLastT[mFirstIndex] = currTime;
104
        mLastX[mFirstIndex] = x;
105
        mLastY[mFirstIndex] = y;
106
        }
107
      }
108

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

    
111
    private void computeCurrentSpeedInInchesPerSecond()
112
      {
113
      long firstTime = mLastT[mFirstIndex];
114
      long lastTime  = mLastT[mLastIndex];
115
      float fX = mLastX[mFirstIndex];
116
      float fY = mLastY[mFirstIndex];
117
      float lX = mLastX[mLastIndex];
118
      float lY = mLastY[mLastIndex];
119

    
120
      long timeDiff = lastTime-firstTime;
121

    
122
      mLastIndex = 0;
123
      mFirstIndex= 0;
124

    
125
      mCurrRotSpeed = timeDiff>0 ? 1000*retFingerDragDistanceInInches(fX-lX,fY-lY)/timeDiff : 0;
126
      }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
    private float retFingerDragDistanceInInches(float xd, float yd)
131
      {
132
      float xDist = mScreenWidth*xd;
133
      float yDist = mScreenHeight*yd;
134
      float distInPixels = (float)Math.sqrt(xDist*xDist + yDist*yDist);
135

    
136
      return distInPixels/mDensity;
137
      }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
    private void replaceMode(boolean down)
142
      {
143
      mBeginningRotation= false;
144

    
145
      if( down )
146
        {
147
        int cubit = mTouchControl.getTouchedCubit();
148
        int face  = mTouchControl.getTouchedCubitFace();
149
        mInterface.onReplaceModeDown(cubit,face);
150
        }
151
      }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
    private void setUpDragOrRotate(boolean down, float x, float y)
156
      {
157
      if( mLastMode==MODE_DRAG )
158
        {
159
        mDragging           = true;
160
        mBeginningRotation  = false;
161
        mContinuingRotation = false;
162
        }
163
      else
164
        {
165
        CAMERA_POINT.set2( mObjectNode.getCameraDist() );
166
        Static4D touchPoint = new Static4D(x, y, 0, 0);
167
        Static4D rotatedTouchPoint= QuatHelper.rotateVectorByInvertedQuat(touchPoint, mQuat);
168
        Static4D rotatedCamera= QuatHelper.rotateVectorByInvertedQuat(CAMERA_POINT, mQuat);
169

    
170
        if( mTouchControl!=null && mTouchControl.objectTouched(rotatedTouchPoint,rotatedCamera) )
171
          {
172
          mDragging           = false;
173
          mContinuingRotation = false;
174

    
175
               if( mLastMode==MODE_ROTATE  ) mBeginningRotation = !mPreRender.isRotationBlocked();
176
          else if( mLastMode==MODE_REPLACE ) replaceMode(down);
177
          }
178
        else
179
          {
180
          mDragging           = (!mIsLocked || mIsAutomatic);
181
          mBeginningRotation  = false;
182
          mContinuingRotation = false;
183
          if( !mDragging ) mInterface.failedToDrag();
184
          }
185
        }
186
      }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

    
190
    private void drag(float x, float y)
191
      {
192
      if( mOS.isFirstPressed() && mOS.isSecondPressed() )
193
        {
194
        float x2 = (mX2 - mScreenWidth*0.5f)/ mScalingSize;
195
        float y2 = (mScreenHeight*0.5f - mY2)/ mScalingSize;
196

    
197
        float angleNow = getAngle(x,y,x2,y2);
198
        float angleDiff = angleNow-mRotAngle;
199
        float sinA =-(float)Math.sin(angleDiff);
200
        float cosA = (float)Math.cos(angleDiff);
201

    
202
        Static4D dragQuat = QuatHelper.quatMultiply(new Static4D(0,0,sinA,cosA), mQuat);
203
        mTemp.set(dragQuat);
204

    
205
        mRotAngle = angleNow;
206

    
207
        float distNow  = (float)Math.sqrt( (x-x2)*(x-x2) + (y-y2)*(y-y2) );
208
        float distQuot = mInitDistance<0 ? 1.0f : distNow/ mInitDistance;
209
        mInitDistance = distNow;
210
        TwistyObject object = mPreRender.getObject();
211
        if( object!=null )
212
          {
213
          object.setObjectRatio(distQuot, mScalingSize );
214
          float ratio = object.getObjectRatio();
215
          if( mLastMode==MODE_REPLACE ) mTouchControl.setObjectRatio(ratio);
216
          }
217
        }
218
      else
219
        {
220
        Static4D dragQuat = QuatHelper.quatMultiply(QuatHelper.quatFromDrag(mX-x,y-mY), mQuat);
221
        mTemp.set(dragQuat);
222
        }
223

    
224
      mPreRender.setQuatOnNextRender();
225
      mX = x;
226
      mY = y;
227
      }
228

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

    
231
    private void finishRotation()
232
      {
233
      TwistyObject object = mPreRender.getObject();
234
      int[][] angles = object.getBasicAngles();
235

    
236
      if( mCurrentAxis<angles.length && mCurrentRow<angles[mCurrentAxis].length )
237
        {
238
        computeCurrentSpeedInInchesPerSecond();
239
        int basic = angles[mCurrentAxis][mCurrentRow];
240
        int angle = object.computeNearestAngle(basic,mCurrentAngle, mCurrRotSpeed);
241
        mPreRender.finishRotation(angle);
242
        mPreRender.rememberMove(mCurrentAxis,mCurrentRow,angle);
243

    
244
        if( angle!=0 )
245
          {
246
          int realAngle = (angle*basic)/360;
247
          mInterface.onFinishRotation(mCurrentAxis,mCurrentRow,realAngle);
248
          }
249

    
250
        mContinuingRotation = false;
251
        mBeginningRotation  = false;
252
        mDragging           = true;
253
        }
254
      }
255

    
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

    
258
    private void continueRotation(float x, float y)
259
      {
260
      if( !mRotAxisIsNormal )
261
        {
262
        float dx = x-mStartRotX;
263
        float dy = y-mStartRotY;
264
        float alpha = dx*mAxis[0] + dy*mAxis[1];
265
        float x2 = dx - alpha*mAxis[0];
266
        float y2 = dy - alpha*mAxis[1];
267

    
268
        float len = (float)Math.sqrt(x2*x2 + y2*y2);
269

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

    
273
        float angle = (tmp>0 ? 1:-1)*len*mRotationFactor;
274
        mCurrentAngle = SWIPING_SENSITIVITY*angle;
275
        mPreRender.getObject().continueRotation(mCurrentAngle);
276

    
277
        addSpeedProbe(x2,y2);
278
        }
279
      else
280
        {
281
        float rotAngle = computeNormalRotAngle(mNormalTouchPoint[0]-x,mNormalTouchPoint[1]-y);
282
        mCurrentAngle = mNormalRotAngle - rotAngle;
283
        mPreRender.getObject().continueRotation(mCurrentAngle);
284
        }
285
      }
286

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

    
289
    private void correctRotationAxis()
290
      {
291
      if( mAxis[0]==0 && mAxis[1]==0 )
292
        {
293
        mRotAxisIsNormal = true;
294

    
295
        // 0. get face center in object space
296
        // 1. multiply it by mQuat
297
        // 2. multiply if by mObjectRatio. Let the result be (x,y,z)
298
        // 3. let D be CAMERA_POINT.Z
299
        // 4. then compute the point on the screen (X,Y) the face center maps to:
300
        //    (X,Y) = (Ax,Ay) where A = D/(D-z)
301

    
302
        float[] faceCenter = mTouchControl.getTouchedPuzzleCenter();
303
        float D = CAMERA_POINT.get2();
304
        float[] rotated = new float[4];
305
        QuatHelper.rotateVectorByQuat(rotated, faceCenter[0],faceCenter[1],faceCenter[2],faceCenter[3],mQuat);
306
        TwistyObject object = getObject();
307
        float ratio = object.getObjectRatio();
308

    
309
        float x = rotated[0] * ratio;
310
        float y = rotated[1] * ratio;
311
        float z = rotated[2] * ratio;
312

    
313
        float A = D / (D-z);
314
        mNormalTouchPoint[0] = A*x;
315
        mNormalTouchPoint[1] = A*y;
316
        }
317
      else
318
        {
319
        mRotAxisIsNormal = false;
320
        }
321
      }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324
// in degrees
325

    
326
    private float computeNormalRotAngle(float vx, float vy)
327
      {
328
      return (float)((180*Math.atan2(vy,vx))/Math.PI);
329
      }
330

    
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332

    
333
    private void beginRotation(float x, float y)
334
      {
335
      mStartRotX = x;
336
      mStartRotY = y;
337

    
338
      TwistyObject object = mPreRender.getObject();
339
      int[] numLayers = object.getNumLayers();
340
      Static4D touchPoint = new Static4D(x, y, 0, 0);
341
      Static4D rotatedTouchPoint= QuatHelper.rotateVectorByInvertedQuat(touchPoint, mQuat);
342

    
343
      mTouchControl.newRotation(mBuffer,rotatedTouchPoint,mQuat);
344

    
345
      mCurrentAxis = mBuffer[0];
346
      mCurrentRow  = mBuffer[1];
347

    
348
      mTouchControl.getCastedRotAxis(mAxis,mQuat,mCurrentAxis);
349
      correctRotationAxis();
350
      mRotationFactor = mTouchControl.returnRotationFactor(numLayers,mCurrentRow);
351
      if( mRotAxisIsNormal ) mNormalRotAngle = computeNormalRotAngle(mNormalTouchPoint[0]-x,mNormalTouchPoint[1]-y);
352

    
353
      if( object.beginNewRotation( mCurrentAxis, mCurrentRow ) )
354
        {
355
        mInterface.onBeginRotation();
356
        addSpeedProbe(x,y);
357
        mBeginningRotation = false;
358
        mContinuingRotation= true;
359
        }
360
      }
361

    
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363

    
364
    private float getAngle(float x1, float y1, float x2, float y2)
365
      {
366
      return (float) Math.atan2(y1-y2, x1-x2);
367
      }
368

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370

    
371
    private void prepareDown()
372
      {
373
      mOS.pressFirst();
374
      mOS.unpressSecond();
375

    
376
      mX1 = mOS.getFirstX() - mMoveX;
377
      mY1 = mOS.getFirstY() + mMoveY;
378
      }
379

    
380
///////////////////////////////////////////////////////////////////////////////////////////////////
381

    
382
    private void prepareMove()
383
      {
384
      int index1 = mOS.getFirstPointerIndex();
385

    
386
      if( index1>=0 )
387
        {
388
        mX1 = mOS.getX(index1) - mMoveX;
389
        mY1 = mOS.getY(index1) + mMoveY;
390
        }
391

    
392
      int index2 = mOS.getSecondPointerIndex();
393

    
394
      if( index2>=0 )
395
        {
396
        mX2 = mOS.getX(index2) - mMoveX;
397
        mY2 = mOS.getY(index2) + mMoveY;
398
        }
399
      }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
    private void prepareUp()
404
      {
405
      mOS.unpressFirst();
406
      mOS.unpressSecond();
407
      }
408

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

    
411
    private void prepareDown2()
412
      {
413
      if( !mOS.isFirstPressed() )
414
        {
415
        mOS.pressFirst();
416
        mX1 = mOS.getFirstX() - mMoveX;
417
        mY1 = mOS.getFirstY() + mMoveY;
418
        }
419
      else if( !mOS.isSecondPressed() )
420
        {
421
        mOS.pressSecond();
422
        mX2 = mOS.getSecondX() - mMoveX;
423
        mY2 = mOS.getSecondY() + mMoveY;
424
        }
425
      }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
    private void prepareUp2()
430
      {
431
      mOS.upOneOfThem();
432
      }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

    
436
    private void actionMove(float x1, float y1, float x2, float y2)
437
      {
438
      float pX,pY;
439

    
440
      if( mOS.isFirstPressed() ) { pX = x1; pY=y1; }
441
      else                       { pX = x2; pY=y2; }
442

    
443
      float x = (pX - mScreenWidth*0.5f)/ mScalingSize;
444
      float y = (mScreenHeight*0.5f -pY)/ mScalingSize;
445

    
446
      if( mBeginningRotation )
447
        {
448
        if( retFingerDragDistanceInInches(mX-x,mY-y) > ROTATION_SENSITIVITY )
449
          {
450
          beginRotation(x,y);
451
          }
452
        }
453
      else if( mContinuingRotation )
454
        {
455
        continueRotation(x,y);
456
        }
457
      else if( mDragging )
458
        {
459
        drag(x,y);
460
        }
461
      else
462
        {
463
        setUpDragOrRotate(false,x,y);
464
        }
465
      }
466

    
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468

    
469
    private void actionDown(float x, float y)
470
      {
471
      mX = (x -  mScreenWidth*0.5f)/ mScalingSize;
472
      mY = (mScreenHeight*0.5f - y)/ mScalingSize;
473

    
474
      setUpDragOrRotate(true,mX,mY);
475
      }
476

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478

    
479
    private void actionUp()
480
      {
481
      if( mContinuingRotation )
482
        {
483
        finishRotation();
484
        }
485

    
486
      if( mLastMode==MODE_REPLACE ) mInterface.onReplaceModeUp();
487
      }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
    private void actionDown2(float x1, float y1, float x2, float y2)
492
      {
493
      mRotAngle = getAngle(x1,-y1, x2,-y2);
494
      mInitDistance = -1;
495

    
496
      mX = (x1 - mScreenWidth*0.5f )/ mScalingSize;
497
      mY = (mScreenHeight*0.5f - y1)/ mScalingSize;
498

    
499
      if( mBeginningRotation )
500
        {
501
        mContinuingRotation = false;
502
        mBeginningRotation  = false;
503
        mDragging           = true;
504
        }
505
      else if( mContinuingRotation )
506
        {
507
        finishRotation();
508
        }
509
      }
510

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

    
513
    private void actionUp2(boolean p1isUp, float x1, float y1, boolean p2isUp, float x2, float y2)
514
      {
515
      if( p1isUp )
516
        {
517
        mX = (x2 -  mScreenWidth*0.5f)/ mScalingSize;
518
        mY = (mScreenHeight*0.5f - y2)/ mScalingSize;
519
        }
520
      if( p2isUp )
521
        {
522
        mX = (x1 -  mScreenWidth*0.5f)/ mScalingSize;
523
        mY = (mScreenHeight*0.5f - y1)/ mScalingSize;
524
        }
525
      }
526

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

    
529
    int getScalingSize()
530
      {
531
      return mScalingSize;
532
      }
533

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

    
536
    void setTouchControl(TwistyObject object)
537
      {
538
      if( mLastMode!=MODE_REPLACE ) mTouchControl = object.getTouchControl();
539
      else                          mTouchControl = new TouchControlShapeChanging(object);
540
      }
541

    
542
///////////////////////////////////////////////////////////////////////////////////////////////////
543
// INTERNAL API (for AutomaticControl)
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545

    
546
    public ObjectPreRender getPreRender()
547
      {
548
      return mPreRender;
549
      }
550

    
551
///////////////////////////////////////////////////////////////////////////////////////////////////
552

    
553
    public ObjectLibInterface getInterface()
554
      {
555
      return mInterface;
556
      }
557

    
558
///////////////////////////////////////////////////////////////////////////////////////////////////
559
// PUBLIC API
560
///////////////////////////////////////////////////////////////////////////////////////////////////
561

    
562
    public ObjectControl(OperatingSystemInterface os)
563
      {
564
      mIsAutomatic = false;
565

    
566
      mBuffer = new int[2];
567
      mAxis   = new float[2];
568

    
569
      mQuat= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
570
      mTemp= new Static4D(0,0,0,1);
571

    
572
      mCurrRotSpeed= 0.0f;
573
      mLastMode    = -1;
574
      mRotateOnCreation = false;
575

    
576
      mNormalTouchPoint = new float[2];
577

    
578
      mLastX = new float[NUM_SPEED_PROBES];
579
      mLastY = new float[NUM_SPEED_PROBES];
580
      mLastT = new long[NUM_SPEED_PROBES];
581
      mFirstIndex= 0;
582
      mLastIndex = 0;
583
      mMeshState =-1;
584
      mIconMode  =-1;
585

    
586
      mInterface = os.getInterface();
587
      mOS = os;
588

    
589
      mDensity = mOS.getScreenDensity();
590
      mPreRender = new ObjectPreRender(this,mInterface);
591
      }
592

    
593
///////////////////////////////////////////////////////////////////////////////////////////////////
594

    
595
    public void setRotateOnCreation(boolean rotate)
596
      {
597
      mRotateOnCreation = rotate;
598
      }
599

    
600
///////////////////////////////////////////////////////////////////////////////////////////////////
601

    
602
    public boolean getRotateOnCreation()
603
      {
604
      return mRotateOnCreation;
605
      }
606

    
607
///////////////////////////////////////////////////////////////////////////////////////////////////
608

    
609
    public TwistyObjectNode getNode()
610
      {
611
      return mObjectNode;
612
      }
613

    
614
///////////////////////////////////////////////////////////////////////////////////////////////////
615

    
616
    public void createNode(int width, int height)
617
      {
618
      if( mObjectNode==null ) mObjectNode = new TwistyObjectNode(width,height);
619
      }
620

    
621
///////////////////////////////////////////////////////////////////////////////////////////////////
622

    
623
    public void setScreenSizeAndScaling(int width, int height, int scaling)
624
      {
625
      mScreenWidth = width;
626
      mScreenHeight= height;
627
      mScalingSize = scaling;
628

    
629
      if( mObjectNode!=null ) mObjectNode.setSize(width,height);
630

    
631
      TwistyObject object = mPreRender.getObject();
632

    
633
      if( object!=null )
634
        {
635
        object.setTexture();
636
        object.setNodeSize(mScalingSize);
637
        }
638
      }
639

    
640
///////////////////////////////////////////////////////////////////////////////////////////////////
641

    
642
    public void setObjectMove(int xmove, int ymove)
643
      {
644
      mMoveX = xmove;
645
      mMoveY = ymove;
646

    
647
      mPreRender.setMove(xmove,ymove);
648
      }
649

    
650
///////////////////////////////////////////////////////////////////////////////////////////////////
651

    
652
    public void setObjectScale(float scale)
653
      {
654
      mPreRender.setScale(scale);
655
      }
656

    
657
///////////////////////////////////////////////////////////////////////////////////////////////////
658

    
659
    public void onPause()
660
      {
661
      BlockController.onPause();
662
      }
663

    
664
///////////////////////////////////////////////////////////////////////////////////////////////////
665

    
666
    public void onResume()
667
      {
668
      mOS.unpressFirst();
669
      mOS.unpressSecond();
670

    
671
      unlock();
672

    
673
      BlockController.onResume();
674
      }
675

    
676
///////////////////////////////////////////////////////////////////////////////////////////////////
677

    
678
    public void rotateNow(Static4D quat)
679
      {
680
      mTemp.set(quat);
681
      mQuat.set(mTemp);
682
      }
683

    
684
///////////////////////////////////////////////////////////////////////////////////////////////////
685

    
686
    public void scaleNow(float scale)
687
      {
688
      mPreRender.getObject().setObjectRatioNow(scale,mScalingSize );
689
      }
690

    
691
///////////////////////////////////////////////////////////////////////////////////////////////////
692

    
693
    public void setQuat()
694
      {
695
      mQuat.set(mTemp);
696
      }
697

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

    
700
    public Static4D getQuat()
701
      {
702
      return mQuat;
703
      }
704

    
705
///////////////////////////////////////////////////////////////////////////////////////////////////
706

    
707
    public void preRender()
708
      {
709
      mPreRender.preRender();
710
      }
711

    
712
///////////////////////////////////////////////////////////////////////////////////////////////////
713

    
714
    public void blockTouch(int place)
715
      {
716
      setLock(true);
717
      mPreRender.blockRotation(place);
718
      }
719

    
720
///////////////////////////////////////////////////////////////////////////////////////////////////
721

    
722
    public void unblockRotation()
723
      {
724
      unsetLock();
725
      mPreRender.unblockRotation();
726
      }
727

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

    
730
    public void unblockEverything()
731
      {
732
      mPreRender.unblockEverything();
733
      }
734

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

    
737
    public boolean isScramblingAndSolvingNotBlocked()
738
      {
739
      return mPreRender.isScramblingAndSolvingNotBlocked();
740
      }
741

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

    
744
    public void initializeObject(int[][] moves)
745
      {
746
      mPreRender.initializeObject(moves);
747
      }
748

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

    
751
    public void changeObject(int ordinal, int meshState, int iconMode, InitAssets asset)
752
      {
753
      mPreRender.changeObject(ordinal, meshState, iconMode, asset);
754
      }
755

    
756
///////////////////////////////////////////////////////////////////////////////////////////////////
757

    
758
    public void changeIfDifferent(int ordinal, String newName, int meshState, int iconMode, InitAssets asset)
759
      {
760
      TwistyObject object = mPreRender.getObject();
761
      String oldName = object==null ? "" : object.getShortName();
762

    
763
      if( !oldName.equals(newName) || mMeshState!=meshState || mIconMode!=iconMode )
764
        {
765
        mMeshState = meshState;
766
        mIconMode  = iconMode;
767
        mPreRender.changeObject(ordinal, meshState, iconMode, asset);
768
        }
769
      }
770

    
771
///////////////////////////////////////////////////////////////////////////////////////////////////
772
// if one or more fingers currently touch the screen, and we just pressed the 'scramble' button, do
773
// not scramble - otherwise a kind of a cheat is possible where user touches the screen, starts
774
// scrambling, then lifts the finger and the act of lifting screws the scrambling - no further
775
// scrambles take any effect!
776

    
777
    public boolean scrambleObject(int num)
778
      {
779
      if( !mBeginningRotation && !mContinuingRotation )
780
        {
781
        return mPreRender.scrambleObject(num);
782
        }
783
      return false;
784
      }
785

    
786
///////////////////////////////////////////////////////////////////////////////////////////////////
787
// ditto
788

    
789
    public boolean fastScrambleObject(int duration, int num)
790
      {
791
      if( !mBeginningRotation && !mContinuingRotation )
792
        {
793
        return mPreRender.fastScrambleObject(duration,num);
794
        }
795
      return false;
796
      }
797

    
798
///////////////////////////////////////////////////////////////////////////////////////////////////
799

    
800
    public void presentObject(int num, int duration)
801
      {
802
      mPreRender.presentObject(num,duration);
803
      }
804

    
805
///////////////////////////////////////////////////////////////////////////////////////////////////
806

    
807
    public void solveObject()
808
      {
809
      mPreRender.solveObject();
810
      }
811

    
812
///////////////////////////////////////////////////////////////////////////////////////////////////
813

    
814
    public void solveOnly()
815
      {
816
      mPreRender.solveOnly();
817
      }
818

    
819
///////////////////////////////////////////////////////////////////////////////////////////////////
820

    
821
    public void resetTextureMapsEffect(int duration)
822
      {
823
      mPreRender.resetTextureMapsEffect(duration);
824
      }
825

    
826
///////////////////////////////////////////////////////////////////////////////////////////////////
827

    
828
    public void addRotation(MovesFinished listener, int axis, int rowBitmap, int angle, int duration)
829
      {
830
      mPreRender.addRotation(listener,axis,rowBitmap,angle,duration);
831
      }
832

    
833
///////////////////////////////////////////////////////////////////////////////////////////////////
834

    
835
    public void resetAllTextureMaps()
836
      {
837
      mPreRender.resetAllTextureMaps();
838
      }
839

    
840
///////////////////////////////////////////////////////////////////////////////////////////////////
841

    
842
    public TwistyObject getObject()
843
      {
844
      return mPreRender.getObject();
845
      }
846

    
847
///////////////////////////////////////////////////////////////////////////////////////////////////
848

    
849
    public OperatingSystemInterface getOS()
850
      {
851
      return mOS;
852
      }
853

    
854
///////////////////////////////////////////////////////////////////////////////////////////////////
855

    
856
    public void savePreferences()
857
      {
858
      mPreRender.savePreferences(mOS);
859

    
860
      for( int i=0; i< BaseEffect.Type.LENGTH; i++ )
861
        {
862
        BaseEffect.Type.getType(i).savePreferences(mOS);
863
        }
864
      }
865

    
866
///////////////////////////////////////////////////////////////////////////////////////////////////
867

    
868
    public void restorePreferences()
869
      {
870
      mPreRender.restorePreferences(mOS);
871

    
872
      for (int i=0; i<BaseEffect.Type.LENGTH; i++)
873
        {
874
        BaseEffect.Type.getType(i).restorePreferences(mOS);
875
        }
876
      }
877

    
878
///////////////////////////////////////////////////////////////////////////////////////////////////
879

    
880
    public boolean retLocked()
881
      {
882
      return mIsLocked;
883
      }
884

    
885
///////////////////////////////////////////////////////////////////////////////////////////////////
886

    
887
    public void toggleLock()
888
      {
889
      mIsLocked = !mIsLocked;
890
      }
891

    
892
///////////////////////////////////////////////////////////////////////////////////////////////////
893

    
894
    public void unlock()
895
      {
896
      mIsLocked = false;
897
      }
898

    
899
///////////////////////////////////////////////////////////////////////////////////////////////////
900

    
901
    public void setLock(boolean value)
902
      {
903
      mRemLocked = mIsLocked;
904
      mIsLocked = value;
905
      }
906

    
907
///////////////////////////////////////////////////////////////////////////////////////////////////
908

    
909
    public void unsetLock()
910
      {
911
      mIsLocked = mRemLocked;
912
      }
913

    
914
///////////////////////////////////////////////////////////////////////////////////////////////////
915

    
916
    public void setTextureMap(int cubit, int face, int newColor)
917
      {
918
      mPreRender.setTextureMap(cubit,face,newColor);
919
      }
920

    
921
///////////////////////////////////////////////////////////////////////////////////////////////////
922

    
923
    public boolean onTouchEvent(int mode)
924
      {
925
      if( mode!=MODE_NOTHING )
926
        {
927
        if( mObjectNode==null ) return true;
928

    
929
        if( mode!=mLastMode )
930
          {
931
          TwistyObject object = getObject();
932

    
933
          if( object!=null )
934
            {
935
            mLastMode = mode;
936
            setTouchControl(object);
937
            }
938
          else return true;
939
          }
940

    
941
        int action = mOS.getAction();
942

    
943
        switch(action)
944
          {
945
          case ACTION_DOWN_1: prepareDown();
946
                              actionDown(mX1, mY1);
947
                              break;
948
          case ACTION_MOVE  : prepareMove();
949
                              actionMove(mX1, mY1, mX2, mY2);
950
                              break;
951
          case ACTION_UP_1  : prepareUp();
952
                              actionUp();
953
                              break;
954
          case ACTION_DOWN_2: prepareDown2();
955
                              actionDown2(mX1, mY1, mX2, mY2);
956
                              break;
957
          case ACTION_UP_2  : prepareUp2();
958
                              boolean p1isUp = !mOS.isFirstPressed();
959
                              boolean p2isUp = !mOS.isSecondPressed();
960
                              actionUp2(p1isUp, mX1, mY1, p2isUp, mX2, mY2);
961
                              break;
962
          }
963
        }
964

    
965
      return true;
966
      }
967
}
968

    
(3-3/11)