Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / main / ObjectControl.java @ 79c7c950

1 880beeea Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6 4c87f159 Leszek Koltunski
// 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 880beeea Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.objectlib.main;
11
12 82b0cf8e Leszek Koltunski
import static org.distorted.objectlib.helpers.OperatingSystemInterface.*;
13
14 880beeea Leszek Koltunski
import org.distorted.library.main.QuatHelper;
15
import org.distorted.library.type.Static4D;
16
17 8e66157b Leszek Koltunski
import org.distorted.objectlib.effects.BaseEffect;
18 2fca02cf Leszek Koltunski
import org.distorted.objectlib.helpers.BlockController;
19 9276dced Leszek Koltunski
import org.distorted.objectlib.helpers.MovesFinished;
20 b3fff6fb Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectLibInterface;
21 51c25e4e Leszek Koltunski
import org.distorted.objectlib.helpers.OperatingSystemInterface;
22 c9c71c3f Leszek Koltunski
import org.distorted.objectlib.touchcontrol.TouchControl;
23 11fa413d Leszek Koltunski
import org.distorted.objectlib.touchcontrol.TouchControlShapeChanging;
24 880beeea Leszek Koltunski
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26
27
public class ObjectControl
28
{
29 da57aa64 Leszek Koltunski
    public static final int MAX_MOVING_PARTS = 242; // Gigaminx
30
    public static final int MAX_QUATS = 60;         // Gigaminx: 60 quats group.
31
32 880beeea Leszek Koltunski
    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 611940ac Leszek Koltunski
    public static final int MODE_NOTHING = 3;
38 880beeea Leszek Koltunski
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 b3fff6fb Leszek Koltunski
    private final ObjectLibInterface mInterface;
48 51c25e4e Leszek Koltunski
    private final OperatingSystemInterface mOS;
49 880beeea Leszek Koltunski
    private final ObjectPreRender mPreRender;
50 7c546131 Leszek Koltunski
    private TouchControl mTouchControl;
51 7ba38dd4 Leszek Koltunski
    private TwistyObjectNode mObjectNode;
52 880beeea Leszek Koltunski
    private boolean mDragging, mBeginningRotation, mContinuingRotation;
53 30bd2f96 Leszek Koltunski
    private int mScreenWidth, mScreenHeight, mScalingSize;
54 72d6857c Leszek Koltunski
    private float mMoveX, mMoveY;
55 11fa413d Leszek Koltunski
    private int mLastMode;
56 880beeea Leszek Koltunski
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 046104f5 Leszek Koltunski
    private final boolean mIsAutomatic;
70 880beeea Leszek Koltunski
71 b9956428 Leszek Koltunski
    private boolean mIsLocked, mRemLocked;
72 57ef6378 Leszek Koltunski
    private final int[] mBuffer;
73
    private final float[] mAxis;
74 3bf19410 Leszek Koltunski
    private int mMeshState, mIconMode;
75 4a389a4e Leszek Koltunski
    private boolean mRotateOnCreation;
76 a76330cc Leszek Koltunski
    private final Static4D mQuat,mTemp;
77 880beeea Leszek Koltunski
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79
80
    private void addSpeedProbe(float x, float y)
81
      {
82
      long currTime = System.currentTimeMillis();
83
      boolean theSame = mLastIndex==mFirstIndex;
84
85
      mLastIndex++;
86
      if( mLastIndex>=NUM_SPEED_PROBES ) mLastIndex=0;
87
88
      mLastT[mLastIndex] = currTime;
89
      mLastX[mLastIndex] = x;
90
      mLastY[mLastIndex] = y;
91
92
      if( mLastIndex==mFirstIndex)
93
        {
94
        mFirstIndex++;
95
        if( mFirstIndex>=NUM_SPEED_PROBES ) mFirstIndex=0;
96
        }
97
98
      if( theSame )
99
        {
100
        mLastT[mFirstIndex] = currTime;
101
        mLastX[mFirstIndex] = x;
102
        mLastY[mFirstIndex] = y;
103
        }
104
      }
105
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107
108
    private void computeCurrentSpeedInInchesPerSecond()
109
      {
110
      long firstTime = mLastT[mFirstIndex];
111
      long lastTime  = mLastT[mLastIndex];
112
      float fX = mLastX[mFirstIndex];
113
      float fY = mLastY[mFirstIndex];
114
      float lX = mLastX[mLastIndex];
115
      float lY = mLastY[mLastIndex];
116
117
      long timeDiff = lastTime-firstTime;
118
119
      mLastIndex = 0;
120
      mFirstIndex= 0;
121
122 78108318 Leszek Koltunski
      mCurrRotSpeed = timeDiff>0 ? 1000*retFingerDragDistanceInInches(fX-lX,fY-lY)/timeDiff : 0;
123 880beeea Leszek Koltunski
      }
124
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126
127 78108318 Leszek Koltunski
    private float retFingerDragDistanceInInches(float xd, float yd)
128 880beeea Leszek Koltunski
      {
129 78108318 Leszek Koltunski
      float xDist = mScreenWidth*xd;
130
      float yDist = mScreenHeight*yd;
131 880beeea Leszek Koltunski
      float distInPixels = (float)Math.sqrt(xDist*xDist + yDist*yDist);
132
133
      return distInPixels/mDensity;
134
      }
135
136 3d093961 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
137
138 57ef6378 Leszek Koltunski
    private void replaceMode(boolean down)
139 3d093961 Leszek Koltunski
      {
140
      mBeginningRotation= false;
141
142
      if( down )
143
        {
144 11fa413d Leszek Koltunski
        int cubit = mTouchControl.getTouchedCubit();
145
        int face  = mTouchControl.getTouchedCubitFace();
146
        mInterface.onReplaceModeDown(cubit,face);
147 3d093961 Leszek Koltunski
        }
148
      }
149
150 880beeea Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
151
152 11fa413d Leszek Koltunski
    private void setUpDragOrRotate(boolean down, float x, float y)
153 880beeea Leszek Koltunski
      {
154 11fa413d Leszek Koltunski
      if( mLastMode==MODE_DRAG )
155 880beeea Leszek Koltunski
        {
156
        mDragging           = true;
157
        mBeginningRotation  = false;
158
        mContinuingRotation = false;
159
        }
160
      else
161
        {
162 57ef6378 Leszek Koltunski
        CAMERA_POINT.set2( mObjectNode.getCameraDist() );
163 880beeea Leszek Koltunski
        Static4D touchPoint = new Static4D(x, y, 0, 0);
164
        Static4D rotatedTouchPoint= QuatHelper.rotateVectorByInvertedQuat(touchPoint, mQuat);
165
        Static4D rotatedCamera= QuatHelper.rotateVectorByInvertedQuat(CAMERA_POINT, mQuat);
166
167 57ef6378 Leszek Koltunski
        if( mTouchControl!=null && mTouchControl.objectTouched(rotatedTouchPoint,rotatedCamera) )
168 880beeea Leszek Koltunski
          {
169
          mDragging           = false;
170
          mContinuingRotation = false;
171
172 7205c655 Leszek Koltunski
               if( mLastMode==MODE_ROTATE  ) mBeginningRotation = !mPreRender.isRotationBlocked();
173 11fa413d Leszek Koltunski
          else if( mLastMode==MODE_REPLACE ) replaceMode(down);
174 880beeea Leszek Koltunski
          }
175
        else
176
          {
177 b9956428 Leszek Koltunski
          mDragging           = (!mIsLocked || mIsAutomatic);
178 880beeea Leszek Koltunski
          mBeginningRotation  = false;
179
          mContinuingRotation = false;
180 b3fff6fb Leszek Koltunski
          if( !mDragging ) mInterface.failedToDrag();
181 880beeea Leszek Koltunski
          }
182
        }
183
      }
184
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186
187
    private void drag(float x, float y)
188
      {
189 82b0cf8e Leszek Koltunski
      if( mOS.isFirstPressed() && mOS.isSecondPressed() )
190 880beeea Leszek Koltunski
        {
191 30bd2f96 Leszek Koltunski
        float x2 = (mX2 - mScreenWidth*0.5f)/ mScalingSize;
192
        float y2 = (mScreenHeight*0.5f - mY2)/ mScalingSize;
193 880beeea Leszek Koltunski
194
        float angleNow = getAngle(x,y,x2,y2);
195
        float angleDiff = angleNow-mRotAngle;
196
        float sinA =-(float)Math.sin(angleDiff);
197
        float cosA = (float)Math.cos(angleDiff);
198
199
        Static4D dragQuat = QuatHelper.quatMultiply(new Static4D(0,0,sinA,cosA), mQuat);
200
        mTemp.set(dragQuat);
201
202
        mRotAngle = angleNow;
203
204
        float distNow  = (float)Math.sqrt( (x-x2)*(x-x2) + (y-y2)*(y-y2) );
205
        float distQuot = mInitDistance<0 ? 1.0f : distNow/ mInitDistance;
206
        mInitDistance = distNow;
207
        TwistyObject object = mPreRender.getObject();
208 7c82e1c6 Leszek Koltunski
        if( object!=null )
209
          {
210 30bd2f96 Leszek Koltunski
          object.setObjectRatio(distQuot, mScalingSize );
211 7c82e1c6 Leszek Koltunski
          float ratio = object.getObjectRatio();
212
          if( mLastMode==MODE_REPLACE ) mTouchControl.setObjectRatio(ratio);
213
          }
214 880beeea Leszek Koltunski
        }
215
      else
216
        {
217
        Static4D dragQuat = QuatHelper.quatMultiply(QuatHelper.quatFromDrag(mX-x,y-mY), mQuat);
218
        mTemp.set(dragQuat);
219
        }
220
221
      mPreRender.setQuatOnNextRender();
222
      mX = x;
223
      mY = y;
224
      }
225
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227
228
    private void finishRotation()
229
      {
230 2df35810 Leszek Koltunski
      TwistyObject object = mPreRender.getObject();
231 beee90ab Leszek Koltunski
      int[][] angles = object.getBasicAngles();
232 880beeea Leszek Koltunski
233 d5411af4 Leszek Koltunski
      if( mCurrentAxis<angles.length && mCurrentRow<angles[mCurrentAxis].length )
234 880beeea Leszek Koltunski
        {
235 a1bcb301 Leszek Koltunski
        computeCurrentSpeedInInchesPerSecond();
236 beee90ab Leszek Koltunski
        int basic = angles[mCurrentAxis][mCurrentRow];
237
        int angle = object.computeNearestAngle(basic,mCurrentAngle, mCurrRotSpeed);
238 a1bcb301 Leszek Koltunski
        mPreRender.finishRotation(angle);
239
        mPreRender.rememberMove(mCurrentAxis,mCurrentRow,angle);
240
241
        if( angle!=0 )
242
          {
243 beee90ab Leszek Koltunski
          int realAngle = (angle*basic)/360;
244 a1bcb301 Leszek Koltunski
          mInterface.onFinishRotation(mCurrentAxis,mCurrentRow,realAngle);
245
          }
246 880beeea Leszek Koltunski
247 a1bcb301 Leszek Koltunski
        mContinuingRotation = false;
248
        mBeginningRotation  = false;
249
        mDragging           = true;
250
        }
251 880beeea Leszek Koltunski
      }
252
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254
255
    private void continueRotation(float x, float y)
256
      {
257
      float dx = x-mStartRotX;
258
      float dy = y-mStartRotY;
259 57ef6378 Leszek Koltunski
      float alpha = dx*mAxis[0] + dy*mAxis[1];
260
      float x2 = dx - alpha*mAxis[0];
261
      float y2 = dy - alpha*mAxis[1];
262 880beeea Leszek Koltunski
263
      float len = (float)Math.sqrt(x2*x2 + y2*y2);
264
265
      // we have the length of 1D vector 'angle', now the direction:
266 57ef6378 Leszek Koltunski
      float tmp = mAxis[1]==0 ? -mAxis[0]*y2 : mAxis[1]*x2;
267 880beeea Leszek Koltunski
268
      float angle = (tmp>0 ? 1:-1)*len*mRotationFactor;
269
      mCurrentAngle = SWIPING_SENSITIVITY*angle;
270
      mPreRender.getObject().continueRotation(mCurrentAngle);
271
272
      addSpeedProbe(x2,y2);
273
      }
274
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
277
    private void beginRotation(float x, float y)
278
      {
279 31ed545f Leszek Koltunski
      mStartRotX = x;
280
      mStartRotY = y;
281
282 880beeea Leszek Koltunski
      TwistyObject object = mPreRender.getObject();
283 a57e6870 Leszek Koltunski
      int[] numLayers = object.getNumLayers();
284 43a4ccff Leszek Koltunski
      Static4D touchPoint = new Static4D(x, y, 0, 0);
285
      Static4D rotatedTouchPoint= QuatHelper.rotateVectorByInvertedQuat(touchPoint, mQuat);
286 880beeea Leszek Koltunski
287 31ed545f Leszek Koltunski
      mTouchControl.newRotation(mBuffer,rotatedTouchPoint,mQuat);
288 880beeea Leszek Koltunski
289 31ed545f Leszek Koltunski
      mCurrentAxis = mBuffer[0];
290
      mCurrentRow  = mBuffer[1];
291 880beeea Leszek Koltunski
292 31ed545f Leszek Koltunski
      mTouchControl.getCastedRotAxis(mAxis,mQuat,mCurrentAxis);
293
      mRotationFactor = mTouchControl.returnRotationFactor(numLayers,mCurrentRow);
294 605f319b Leszek Koltunski
295
      if( object.beginNewRotation( mCurrentAxis, mCurrentRow ) )
296
        {
297
        mInterface.onBeginRotation();
298
        addSpeedProbe(x,y);
299
        mBeginningRotation = false;
300
        mContinuingRotation= true;
301
        }
302 880beeea Leszek Koltunski
      }
303
304
///////////////////////////////////////////////////////////////////////////////////////////////////
305
306
    private float getAngle(float x1, float y1, float x2, float y2)
307
      {
308
      return (float) Math.atan2(y1-y2, x1-x2);
309
      }
310
311
///////////////////////////////////////////////////////////////////////////////////////////////////
312
313 82b0cf8e Leszek Koltunski
    private void prepareDown()
314 880beeea Leszek Koltunski
      {
315 82b0cf8e Leszek Koltunski
      mOS.pressFirst();
316
      mOS.unpressSecond();
317
318
      mX1 = mOS.getFirstX() - mMoveX;
319
      mY1 = mOS.getFirstY() + mMoveY;
320 880beeea Leszek Koltunski
      }
321
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323
324 82b0cf8e Leszek Koltunski
    private void prepareMove()
325 880beeea Leszek Koltunski
      {
326 82b0cf8e Leszek Koltunski
      if( mOS.isFirstPressed() )
327 880beeea Leszek Koltunski
        {
328 82b0cf8e Leszek Koltunski
        mX1 = mOS.getFirstX() - mMoveX;
329
        mY1 = mOS.getFirstY() + mMoveY;
330 880beeea Leszek Koltunski
        }
331
332 82b0cf8e Leszek Koltunski
      if( mOS.isSecondPressed() )
333 880beeea Leszek Koltunski
        {
334 82b0cf8e Leszek Koltunski
        mX2 = mOS.getSecondX() - mMoveX;
335
        mY2 = mOS.getSecondY() + mMoveY;
336 880beeea Leszek Koltunski
        }
337
      }
338
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340
341 82b0cf8e Leszek Koltunski
    private void prepareUp()
342 880beeea Leszek Koltunski
      {
343 82b0cf8e Leszek Koltunski
      mOS.unpressFirst();
344
      mOS.unpressSecond();
345 880beeea Leszek Koltunski
      }
346
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348
349 82b0cf8e Leszek Koltunski
    private void prepareDown2()
350 880beeea Leszek Koltunski
      {
351 82b0cf8e Leszek Koltunski
      if( !mOS.isFirstPressed() )
352 880beeea Leszek Koltunski
        {
353 82b0cf8e Leszek Koltunski
        mOS.pressFirst();
354
        mX1 = mOS.getFirstX() - mMoveX;
355
        mY1 = mOS.getFirstY() + mMoveY;
356 880beeea Leszek Koltunski
        }
357 82b0cf8e Leszek Koltunski
      else if( !mOS.isSecondPressed() )
358 880beeea Leszek Koltunski
        {
359 82b0cf8e Leszek Koltunski
        mOS.pressSecond();
360
        mX2 = mOS.getSecondX() - mMoveX;
361
        mY2 = mOS.getSecondY() + mMoveY;
362 880beeea Leszek Koltunski
        }
363
      }
364
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366
367 82b0cf8e Leszek Koltunski
    private void prepareUp2()
368 880beeea Leszek Koltunski
      {
369 dfa958c7 Leszek Koltunski
      mOS.upOneOfThem();
370 880beeea Leszek Koltunski
      }
371
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373
374 11fa413d Leszek Koltunski
    private void actionMove(float x1, float y1, float x2, float y2)
375 880beeea Leszek Koltunski
      {
376 82b0cf8e Leszek Koltunski
      float pX,pY;
377
378
      if( mOS.isFirstPressed() ) { pX = x1; pY=y1; }
379
      else                       { pX = x2; pY=y2; }
380 880beeea Leszek Koltunski
381 30bd2f96 Leszek Koltunski
      float x = (pX - mScreenWidth*0.5f)/ mScalingSize;
382
      float y = (mScreenHeight*0.5f -pY)/ mScalingSize;
383 880beeea Leszek Koltunski
384
      if( mBeginningRotation )
385
        {
386 78108318 Leszek Koltunski
        if( retFingerDragDistanceInInches(mX-x,mY-y) > ROTATION_SENSITIVITY )
387 880beeea Leszek Koltunski
          {
388
          beginRotation(x,y);
389
          }
390
        }
391
      else if( mContinuingRotation )
392
        {
393
        continueRotation(x,y);
394
        }
395
      else if( mDragging )
396
        {
397
        drag(x,y);
398
        }
399
      else
400
        {
401 11fa413d Leszek Koltunski
        setUpDragOrRotate(false,x,y);
402 880beeea Leszek Koltunski
        }
403
      }
404
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406
407 11fa413d Leszek Koltunski
    private void actionDown(float x, float y)
408 880beeea Leszek Koltunski
      {
409 30bd2f96 Leszek Koltunski
      mX = (x -  mScreenWidth*0.5f)/ mScalingSize;
410
      mY = (mScreenHeight*0.5f - y)/ mScalingSize;
411 880beeea Leszek Koltunski
412 11fa413d Leszek Koltunski
      setUpDragOrRotate(true,mX,mY);
413 880beeea Leszek Koltunski
      }
414
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417
    private void actionUp()
418
      {
419
      if( mContinuingRotation )
420
        {
421
        finishRotation();
422
        }
423
424 11fa413d Leszek Koltunski
      if( mLastMode==MODE_REPLACE ) mInterface.onReplaceModeUp();
425 880beeea Leszek Koltunski
      }
426
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428
429
    private void actionDown2(float x1, float y1, float x2, float y2)
430
      {
431
      mRotAngle = getAngle(x1,-y1, x2,-y2);
432
      mInitDistance = -1;
433
434 30bd2f96 Leszek Koltunski
      mX = (x1 - mScreenWidth*0.5f )/ mScalingSize;
435
      mY = (mScreenHeight*0.5f - y1)/ mScalingSize;
436 880beeea Leszek Koltunski
437
      if( mBeginningRotation )
438
        {
439
        mContinuingRotation = false;
440
        mBeginningRotation  = false;
441
        mDragging           = true;
442
        }
443
      else if( mContinuingRotation )
444
        {
445
        finishRotation();
446
        }
447
      }
448
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450
451
    private void actionUp2(boolean p1isUp, float x1, float y1, boolean p2isUp, float x2, float y2)
452
      {
453
      if( p1isUp )
454
        {
455 30bd2f96 Leszek Koltunski
        mX = (x2 -  mScreenWidth*0.5f)/ mScalingSize;
456
        mY = (mScreenHeight*0.5f - y2)/ mScalingSize;
457 880beeea Leszek Koltunski
        }
458
      if( p2isUp )
459
        {
460 30bd2f96 Leszek Koltunski
        mX = (x1 -  mScreenWidth*0.5f)/ mScalingSize;
461
        mY = (mScreenHeight*0.5f - y1)/ mScalingSize;
462 880beeea Leszek Koltunski
        }
463
      }
464
465 30bd2f96 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
466
467
    int getScalingSize()
468
      {
469
      return mScalingSize;
470
      }
471
472 e32d318a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
473
474 11fa413d Leszek Koltunski
    void setTouchControl(TwistyObject object)
475 e32d318a Leszek Koltunski
      {
476 7c546131 Leszek Koltunski
      if( mLastMode!=MODE_REPLACE ) mTouchControl = object.getTouchControl();
477
      else                          mTouchControl = new TouchControlShapeChanging(object);
478 e32d318a Leszek Koltunski
      }
479
480 9276dced Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
481
// INTERNAL API (for AutomaticControl)
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483
484
    public ObjectPreRender getPreRender()
485
      {
486
      return mPreRender;
487
      }
488
489 b3fff6fb Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
490
491
    public ObjectLibInterface getInterface()
492
      {
493
      return mInterface;
494
      }
495
496 880beeea Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
497
// PUBLIC API
498
///////////////////////////////////////////////////////////////////////////////////////////////////
499
500 51c25e4e Leszek Koltunski
    public ObjectControl(ObjectLibInterface actioner, OperatingSystemInterface os)
501 880beeea Leszek Koltunski
      {
502
      mIsAutomatic = false;
503
504 57ef6378 Leszek Koltunski
      mBuffer = new int[2];
505
      mAxis   = new float[2];
506
507 a76330cc Leszek Koltunski
      mQuat= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
508
      mTemp= new Static4D(0,0,0,1);
509
510 11fa413d Leszek Koltunski
      mCurrRotSpeed= 0.0f;
511
      mLastMode    = -1;
512 4a389a4e Leszek Koltunski
      mRotateOnCreation = false;
513 880beeea Leszek Koltunski
514
      mLastX = new float[NUM_SPEED_PROBES];
515
      mLastY = new float[NUM_SPEED_PROBES];
516
      mLastT = new long[NUM_SPEED_PROBES];
517 c3a033e9 Leszek Koltunski
      mFirstIndex= 0;
518
      mLastIndex = 0;
519
      mMeshState =-1;
520 3bf19410 Leszek Koltunski
      mIconMode  =-1;
521 880beeea Leszek Koltunski
522 51c25e4e Leszek Koltunski
      mInterface = actioner;
523
      mOS = os;
524 880beeea Leszek Koltunski
525 51c25e4e Leszek Koltunski
      mDensity = mOS.getScreenDensity();
526 440f8e33 Leszek Koltunski
      mPreRender = new ObjectPreRender(this,actioner);
527 880beeea Leszek Koltunski
      }
528
529 4a389a4e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
530
531
    public void setRotateOnCreation(boolean rotate)
532
      {
533
      mRotateOnCreation = rotate;
534
      }
535
536
///////////////////////////////////////////////////////////////////////////////////////////////////
537
538
    public boolean getRotateOnCreation()
539
      {
540
      return mRotateOnCreation;
541
      }
542
543 7ba38dd4 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
544
545
    public TwistyObjectNode getNode()
546
      {
547
      return mObjectNode;
548
      }
549
550
///////////////////////////////////////////////////////////////////////////////////////////////////
551
552
    public void createNode(int width, int height)
553
      {
554
      if( mObjectNode==null ) mObjectNode = new TwistyObjectNode(width,height);
555
      }
556
557 880beeea Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
558
559 30bd2f96 Leszek Koltunski
    public void setScreenSizeAndScaling(int width, int height, int scaling)
560 880beeea Leszek Koltunski
      {
561
      mScreenWidth = width;
562
      mScreenHeight= height;
563 30bd2f96 Leszek Koltunski
      mScalingSize = scaling;
564 7ba38dd4 Leszek Koltunski
565 45e0065d Leszek Koltunski
      if( mObjectNode!=null ) mObjectNode.setSize(width,height);
566
567 7fe64077 Leszek Koltunski
      TwistyObject object = mPreRender.getObject();
568 fd6e2b3b Leszek Koltunski
569
      if( object!=null )
570
        {
571
        object.setTexture();
572 30bd2f96 Leszek Koltunski
        object.setNodeSize(mScalingSize);
573 fd6e2b3b Leszek Koltunski
        }
574 880beeea Leszek Koltunski
      }
575
576 ecf3d6e3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
577
578 64c209f5 Leszek Koltunski
    public void setObjectMove(int xmove, int ymove)
579 ecf3d6e3 Leszek Koltunski
      {
580 72d6857c Leszek Koltunski
      mMoveX = xmove;
581
      mMoveY = ymove;
582
583
      mPreRender.setMove(xmove,ymove);
584 ecf3d6e3 Leszek Koltunski
      }
585
586 64c209f5 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
587
588
    public void setObjectScale(float scale)
589
      {
590
      mPreRender.setScale(scale);
591
      }
592
593 880beeea Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
594
595 2fca02cf Leszek Koltunski
    public void onPause()
596
      {
597
      BlockController.onPause();
598
      }
599
600
///////////////////////////////////////////////////////////////////////////////////////////////////
601
602
    public void onResume()
603 880beeea Leszek Koltunski
      {
604 82b0cf8e Leszek Koltunski
      mOS.unpressFirst();
605
      mOS.unpressSecond();
606 b9956428 Leszek Koltunski
607
      unlock();
608 2fca02cf Leszek Koltunski
609
      BlockController.onResume();
610 880beeea Leszek Koltunski
      }
611
612 2289cab1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
613
614
    public void rotateNow(Static4D quat)
615
      {
616
      mTemp.set(quat);
617
      mQuat.set(mTemp);
618
      }
619
620 ee6bb8d7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
621
622
    public void scaleNow(float scale)
623
      {
624 30bd2f96 Leszek Koltunski
      mPreRender.getObject().setObjectRatioNow(scale,mScalingSize );
625 ee6bb8d7 Leszek Koltunski
      }
626
627 880beeea Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
628
629
    public void setQuat()
630
      {
631
      mQuat.set(mTemp);
632
      }
633
634
///////////////////////////////////////////////////////////////////////////////////////////////////
635
636
    public Static4D getQuat()
637
      {
638
      return mQuat;
639
      }
640
641
///////////////////////////////////////////////////////////////////////////////////////////////////
642
643 9276dced Leszek Koltunski
    public void preRender()
644 880beeea Leszek Koltunski
      {
645 9276dced Leszek Koltunski
      mPreRender.preRender();
646
      }
647
648
///////////////////////////////////////////////////////////////////////////////////////////////////
649
650
    public void blockTouch(int place)
651
      {
652 b9956428 Leszek Koltunski
      setLock(true);
653 7205c655 Leszek Koltunski
      mPreRender.blockRotation(place);
654 9276dced Leszek Koltunski
      }
655
656
///////////////////////////////////////////////////////////////////////////////////////////////////
657
658 7205c655 Leszek Koltunski
    public void unblockRotation()
659 9276dced Leszek Koltunski
      {
660 b9956428 Leszek Koltunski
      unsetLock();
661 7205c655 Leszek Koltunski
      mPreRender.unblockRotation();
662 9276dced Leszek Koltunski
      }
663
664 060b445e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
665
666
    public void unblockEverything()
667
      {
668
      mPreRender.unblockEverything();
669
      }
670
671 9276dced Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
672
673 7205c655 Leszek Koltunski
    public boolean isScramblingAndSolvingNotBlocked()
674 9276dced Leszek Koltunski
      {
675 7205c655 Leszek Koltunski
      return mPreRender.isScramblingAndSolvingNotBlocked();
676 9276dced Leszek Koltunski
      }
677
678
///////////////////////////////////////////////////////////////////////////////////////////////////
679
680
    public void initializeObject(int[][] moves)
681
      {
682
      mPreRender.initializeObject(moves);
683
      }
684
685
///////////////////////////////////////////////////////////////////////////////////////////////////
686
687 cf93ea4e Leszek Koltunski
    public void changeObject(int ordinal, int meshState, int iconMode, InitAssets asset)
688 9276dced Leszek Koltunski
      {
689 cf93ea4e Leszek Koltunski
      mPreRender.changeObject(ordinal, meshState, iconMode, asset);
690 9276dced Leszek Koltunski
      }
691
692 568d4698 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
693
694 cf93ea4e Leszek Koltunski
    public void changeIfDifferent(int ordinal, String newName, int meshState, int iconMode, InitAssets asset)
695 568d4698 Leszek Koltunski
      {
696 e1a86bf2 Leszek Koltunski
      TwistyObject object = mPreRender.getObject();
697 958a6e81 Leszek Koltunski
      String oldName = object==null ? "" : object.getShortName();
698 e1a86bf2 Leszek Koltunski
699 3bf19410 Leszek Koltunski
      if( !oldName.equals(newName) || mMeshState!=meshState || mIconMode!=iconMode )
700 e1a86bf2 Leszek Koltunski
        {
701 c3a033e9 Leszek Koltunski
        mMeshState = meshState;
702 3bf19410 Leszek Koltunski
        mIconMode  = iconMode;
703 cf93ea4e Leszek Koltunski
        mPreRender.changeObject(ordinal, meshState, iconMode, asset);
704 e1a86bf2 Leszek Koltunski
        }
705 568d4698 Leszek Koltunski
      }
706
707 9276dced Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
708 a20e56fc Leszek Koltunski
// if one or more fingers currently touch the screen, and we just pressed the 'scramble' button, do
709
// not scramble - otherwise a kind of a cheat is possible where user touches the screen, starts
710
// scrambling, then lifts the finger and the act of lifting screws the scrambling - no further
711
// scrambles take any effect!
712 9276dced Leszek Koltunski
713 a396a7e1 Leszek Koltunski
    public boolean scrambleObject(int num)
714 9276dced Leszek Koltunski
      {
715 a20e56fc Leszek Koltunski
      if( !mBeginningRotation && !mContinuingRotation )
716
        {
717 36f6390b Leszek Koltunski
        return mPreRender.scrambleObject(num);
718 a20e56fc Leszek Koltunski
        }
719 a396a7e1 Leszek Koltunski
      return false;
720 9276dced Leszek Koltunski
      }
721
722 186bc982 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
723
// ditto
724
725 a396a7e1 Leszek Koltunski
    public boolean fastScrambleObject(int duration, int num)
726 186bc982 Leszek Koltunski
      {
727
      if( !mBeginningRotation && !mContinuingRotation )
728
        {
729 36f6390b Leszek Koltunski
        return mPreRender.fastScrambleObject(duration,num);
730 186bc982 Leszek Koltunski
        }
731 a396a7e1 Leszek Koltunski
      return false;
732 186bc982 Leszek Koltunski
      }
733
734 826d293e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
735
736 b1370e3b Leszek Koltunski
    public void presentObject(int num, int duration)
737 826d293e Leszek Koltunski
      {
738 b1370e3b Leszek Koltunski
      mPreRender.presentObject(num,duration);
739 826d293e Leszek Koltunski
      }
740
741 9276dced Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
742
743
    public void solveObject()
744
      {
745
      mPreRender.solveObject();
746
      }
747
748 17d623f1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
749
750
    public void solveOnly()
751
      {
752
      mPreRender.solveOnly();
753
      }
754
755 4c2c0f44 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
756
757
    public void resetTextureMapsEffect(int duration)
758
      {
759
      mPreRender.resetTextureMapsEffect(duration);
760
      }
761
762 9276dced Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
763
764 2df35810 Leszek Koltunski
    public void addRotation(MovesFinished listener, int axis, int rowBitmap, int angle, int duration)
765 9276dced Leszek Koltunski
      {
766
      mPreRender.addRotation(listener,axis,rowBitmap,angle,duration);
767
      }
768
769
///////////////////////////////////////////////////////////////////////////////////////////////////
770
771
    public void resetAllTextureMaps()
772
      {
773
      mPreRender.resetAllTextureMaps();
774
      }
775
776
///////////////////////////////////////////////////////////////////////////////////////////////////
777
778
    public TwistyObject getObject()
779
      {
780
      return mPreRender.getObject();
781
      }
782
783
///////////////////////////////////////////////////////////////////////////////////////////////////
784
785 79c7c950 Leszek Koltunski
    public OperatingSystemInterface getOS()
786
      {
787
      return mOS;
788
      }
789
790
///////////////////////////////////////////////////////////////////////////////////////////////////
791
792
    public void savePreferences()
793 9276dced Leszek Koltunski
      {
794 79c7c950 Leszek Koltunski
      mPreRender.savePreferences(mOS);
795 8e66157b Leszek Koltunski
796
      for( int i=0; i< BaseEffect.Type.LENGTH; i++ )
797
        {
798 79c7c950 Leszek Koltunski
        BaseEffect.Type.getType(i).savePreferences(mOS);
799 8e66157b Leszek Koltunski
        }
800 9276dced Leszek Koltunski
      }
801
802
///////////////////////////////////////////////////////////////////////////////////////////////////
803
804 79c7c950 Leszek Koltunski
    public void restorePreferences()
805 9276dced Leszek Koltunski
      {
806 79c7c950 Leszek Koltunski
      mPreRender.restorePreferences(mOS);
807 8e66157b Leszek Koltunski
808
      for (int i=0; i<BaseEffect.Type.LENGTH; i++)
809
        {
810 79c7c950 Leszek Koltunski
        BaseEffect.Type.getType(i).restorePreferences(mOS);
811 8e66157b Leszek Koltunski
        }
812 880beeea Leszek Koltunski
      }
813 c3a033e9 Leszek Koltunski
814 b9956428 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
815
816 81141862 Leszek Koltunski
    public boolean retLocked()
817 b9956428 Leszek Koltunski
      {
818
      return mIsLocked;
819
      }
820
821
///////////////////////////////////////////////////////////////////////////////////////////////////
822
823 81141862 Leszek Koltunski
    public void toggleLock()
824 b9956428 Leszek Koltunski
      {
825
      mIsLocked = !mIsLocked;
826
      }
827
828
///////////////////////////////////////////////////////////////////////////////////////////////////
829
830 81141862 Leszek Koltunski
    public void unlock()
831
      {
832
      mIsLocked = false;
833
      }
834 b9956428 Leszek Koltunski
835
///////////////////////////////////////////////////////////////////////////////////////////////////
836
837 81141862 Leszek Koltunski
    public void setLock(boolean value)
838
      {
839
      mRemLocked = mIsLocked;
840
      mIsLocked = value;
841
      }
842 b9956428 Leszek Koltunski
843
///////////////////////////////////////////////////////////////////////////////////////////////////
844
845 81141862 Leszek Koltunski
    public void unsetLock()
846
      {
847
      mIsLocked = mRemLocked;
848
      }
849 880beeea Leszek Koltunski
850 11fa413d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
851
852
    public void setTextureMap(int cubit, int face, int newColor)
853
      {
854
      mPreRender.setTextureMap(cubit,face,newColor);
855
      }
856
857 880beeea Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
858
859 82b0cf8e Leszek Koltunski
    public boolean onTouchEvent(int mode)
860 880beeea Leszek Koltunski
      {
861 611940ac Leszek Koltunski
      if( mode!=MODE_NOTHING )
862
        {
863
        if( mObjectNode==null ) return true;
864 53e85349 Leszek Koltunski
865 7c546131 Leszek Koltunski
        if( mode!=mLastMode )
866 611940ac Leszek Koltunski
          {
867 2832c2fa Leszek Koltunski
          TwistyObject object = getObject();
868
869
          if( object!=null )
870
            {
871
            mLastMode = mode;
872
            setTouchControl(object);
873
            }
874
          else return true;
875 611940ac Leszek Koltunski
          }
876 11fa413d Leszek Koltunski
877 82b0cf8e Leszek Koltunski
        int action = mOS.getAction();
878 92d6c2f1 Leszek Koltunski
879 611940ac Leszek Koltunski
        switch(action)
880
          {
881 82b0cf8e Leszek Koltunski
          case ACTION_DOWN_1: prepareDown();
882
                              actionDown(mX1, mY1);
883
                              break;
884
          case ACTION_MOVE  : prepareMove();
885
                              actionMove(mX1, mY1, mX2, mY2);
886
                              break;
887
          case ACTION_UP_1  : prepareUp();
888
                              actionUp();
889
                              break;
890
          case ACTION_DOWN_2: prepareDown2();
891
                              actionDown2(mX1, mY1, mX2, mY2);
892
                              break;
893
          case ACTION_UP_2  : prepareUp2();
894
                              boolean p1isUp = !mOS.isFirstPressed();
895
                              boolean p2isUp = !mOS.isSecondPressed();
896
                              actionUp2(p1isUp, mX1, mY1, p2isUp, mX2, mY2);
897
                              break;
898 611940ac Leszek Koltunski
          }
899
        }
900 880beeea Leszek Koltunski
901
      return true;
902
      }
903
}