Project

General

Profile

« Previous | Next » 

Revision 47ba5ddc

Added by Leszek Koltunski over 4 years ago

RubikCube: further fixes

View differences:

src/main/java/org/distorted/magic/RubikCube.java
24 24
import android.graphics.Paint;
25 25

  
26 26
import org.distorted.library.effect.Effect;
27
import org.distorted.library.effect.EffectType;
28 27
import org.distorted.library.effect.MatrixEffectMove;
29 28
import org.distorted.library.effect.MatrixEffectQuaternion;
30 29
import org.distorted.library.effect.MatrixEffectRotate;
31 30
import org.distorted.library.effect.MatrixEffectScale;
32 31
import org.distorted.library.effect.VertexEffectSink;
33
import org.distorted.library.effectqueue.EffectQueue;
34 32
import org.distorted.library.main.DistortedEffects;
35 33
import org.distorted.library.main.DistortedNode;
36 34
import org.distorted.library.main.DistortedTexture;
......
67 65
    private MatrixEffectRotate[][][] mRotateEffect;
68 66
    private Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
69 67
    private Static3D mMove, mScale, mNodeMove, mNodeScale;
68
    private Static4D mQuatAccumulated;
70 69
    private DistortedTexture mTexture;
71 70

  
72 71
    private int mRotAxis, mRotRow;
......
93 92
      mNodeMove = new Static3D(0,0,0);
94 93
      mNodeScale= new Static3D(1,1,1);
95 94

  
95
      mQuatAccumulated = quatAcc;
96

  
96 97
      mRotAxis = VECTX;
97 98
      mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
98 99

  
......
187 188

  
188 189
///////////////////////////////////////////////////////////////////////////////////////////////////
189 190

  
190
    boolean isSolved()
191
    private int computeNearestAngle(float angle)
191 192
      {
192
      Static4D q = mQuatScramble[0][0][0];
193

  
194
      float x = q.get1();
195
      float y = q.get2();
196
      float z = q.get3();
197
      float w = q.get4();
198

  
199
      for(int i = 0; i< mSize; i++)
200
        for(int j = 0; j< mSize; j++)
201
          for(int k = 0; k< mSize; k++)
202
            {
203
            if( i==0 || i==mSize-1 || j==0 || j==mSize-1 || k==0 || k==mSize-1 )
204
              {
205
              q = mQuatScramble[i][j][k];
193
      final int NEAREST = 90;
206 194

  
207
              if( q.get1()!=x || q.get2()!=y || q.get3()!=z || q.get4()!=w )
208
                {
209
                return false;
210
                }
211
              }
212
            }
195
      int tmp = (int)((angle+NEAREST/2)/NEAREST);
196
      if( angle< -(NEAREST/2) ) tmp-=1;
213 197

  
214
      return true;
198
      return NEAREST*tmp;
215 199
      }
216 200

  
217 201
///////////////////////////////////////////////////////////////////////////////////////////////////
202
// All legal rotation quats must have all four of their components equal to either
203
// 0, 1, -1, 0.5, -0.5 or +-sqrt(2)/2.
204
//
205
// Because of quatMultiplication, errors can accumulate - so to avoid this, we
206
// correct the value of the 'scramble' quat to what it should be.
207
//
208
// We also have to remember that the group of unit quaternions is a double-cover of rotations
209
// in 3D ( q represents the same rotation as -q ) - so invert if needed.
218 210

  
219
    public void apply(Effect effect, int position)
211
    private static final float SQ2 = 0.5f*((float)Math.sqrt(2));
212
    private static final float[] LEGAL = { 0.0f , 0.5f , -0.5f , 1.0f , -1.0f , SQ2 , -SQ2 };
213

  
214
    private void normalizeScrambleQuat(int i, int j, int k)
220 215
      {
221
      for(int x=0; x<mSize; x++)
222
        for(int y=0; y<mSize; y++)
223
          for(int z=0; z<mSize; z++)
224
            {
225
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
226
              {
227
              mEffects[x][y][z].apply(effect, position);
228
              }
229
            }
230
      }
216
      Static4D quat = mQuatScramble[i][j][k];
231 217

  
232
///////////////////////////////////////////////////////////////////////////////////////////////////
218
      float x = quat.get1();
219
      float y = quat.get2();
220
      float z = quat.get3();
221
      float w = quat.get4();
222
      float diff;
233 223

  
234
    public void remove(long effectID)
235
      {
236
      for(int x=0; x<mSize; x++)
237
        for(int y=0; y<mSize; y++)
238
          for(int z=0; z<mSize; z++)
224
      for(float legal: LEGAL)
225
        {
226
        diff = x-legal;
227
        if( diff*diff<0.01f ) x = legal;
228
        diff = y-legal;
229
        if( diff*diff<0.01f ) y = legal;
230
        diff = z-legal;
231
        if( diff*diff<0.01f ) z = legal;
232
        diff = w-legal;
233
        if( diff*diff<0.01f ) w = legal;
234
        }
235

  
236
      if( w<0 )
237
        {
238
        w = -w;
239
        z = -z;
240
        y = -y;
241
        x = -x;
242
        }
243
      else if( w==0 )
244
        {
245
        if( z<0 )
246
          {
247
          z = -z;
248
          y = -y;
249
          x = -x;
250
          }
251
        else if( z==0 )
252
          {
253
          if( y<0 )
239 254
            {
240
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
255
            y = -y;
256
            x = -x;
257
            }
258
          else if( y==0 )
259
            {
260
            if( x<0 )
241 261
              {
242
              mEffects[x][y][z].abortById(effectID);
262
              x = -x;
243 263
              }
244 264
            }
245
      }
246

  
247
///////////////////////////////////////////////////////////////////////////////////////////////////
265
          }
266
        }
248 267

  
249
    public void solve()
250
      {
251
      for(int x=0; x<mSize; x++)
252
        for(int y=0; y<mSize; y++)
253
          for(int z=0; z<mSize; z++)
254
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
255
              {
256
              mQuatScramble[x][y][z].set(0,0,0,1);
257
              mCurrentPosition[x][y][z].set(x,y,z);
258
              }
268
      mQuatScramble[i][j][k].set(x,y,z,w);
259 269
      }
260 270

  
261 271
///////////////////////////////////////////////////////////////////////////////////////////////////
262 272

  
263
    public String print_effects()
273
    private float getSinkStrength()
264 274
      {
265
      String str="";
266

  
267
      EffectQueue[] effects = mEffects[0][0][0].getQueues();
268
      EffectQueue matrix      = effects[0];
269
      EffectQueue vertex      = effects[1];
270
      EffectQueue fragment    = effects[2];
271
      EffectQueue postprocess = effects[3];
272

  
273
      str+="MATRIX: ";
274
      int m_len = matrix.getNumEffects();
275
      for(int i=0; i<m_len; i++)
276
        {
277
        str+=(" "+matrix.getEffect(i).getName()+"("+matrix.getEffect(i).getID()+")" );
278
        }
279
      str+='\n';
280

  
281
      str+="VERTEX: ";
282
      int v_len = vertex.getNumEffects();
283
      for(int i=0; i<v_len; i++)
275
      switch(mSize)
284 276
        {
285
        str+=(" "+vertex.getEffect(i).getName()+"("+matrix.getEffect(i).getID()+")" );
277
        case 1 : return 1.1f;
278
        case 2 : return 1.5f;
279
        case 3 : return 1.8f;
280
        case 4 : return 2.0f;
281
        default: return 3.0f - 4.0f/mSize;
286 282
        }
287
      str+='\n';
283
      }
288 284

  
289
      str+="FRAGMENT: ";
290
      int f_len = fragment.getNumEffects();
291
      for(int i=0; i<f_len; i++)
292
        {
293
        str+=(" "+fragment.getEffect(i).getName()+"("+matrix.getEffect(i).getID()+")" );
294
        }
295
      str+='\n';
285
///////////////////////////////////////////////////////////////////////////////////////////////////
296 286

  
297
      str+="POSTPROCESS: ";
298
      int p_len = postprocess.getNumEffects();
299
      for(int i=0; i<p_len; i++)
287
    private boolean belongsToRotation(int x, int y, int z, int vector, int row)
288
      {
289
      switch(vector)
300 290
        {
301
        str+=(" "+postprocess.getEffect(i).getName()+"("+matrix.getEffect(i).getID()+")" );
291
        case VECTX: return mCurrentPosition[x][y][z].get1()==row;
292
        case VECTY: return mCurrentPosition[x][y][z].get2()==row;
293
        case VECTZ: return mCurrentPosition[x][y][z].get3()==row;
302 294
        }
303
      str+='\n';
304 295

  
305
      return str;
296
      return false;
306 297
      }
298

  
307 299
///////////////////////////////////////////////////////////////////////////////////////////////////
308 300

  
309
    public int getNumEffects(EffectType type)
301
    private void modifyCurrentPosition(int x, int y, int z, Static4D quat)
310 302
      {
311
      return mEffects[0][0][0].getNumEffects(type);
303
      Static3D current = mCurrentPosition[x][y][z];
304
      float diff = 0.5f*(mSize-1);
305
      float cubitCenterX = current.get1() - diff;
306
      float cubitCenterY = current.get2() - diff;
307
      float cubitCenterZ = current.get3() - diff;
308

  
309
      Static4D cubitCenter =  new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
310
      Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
311

  
312
      float rotatedX = rotatedCenter.get1() + diff;
313
      float rotatedY = rotatedCenter.get2() + diff;
314
      float rotatedZ = rotatedCenter.get3() + diff;
315

  
316
      int roundedX = (int)(rotatedX+0.1f);
317
      int roundedY = (int)(rotatedY+0.1f);
318
      int roundedZ = (int)(rotatedZ+0.1f);
319

  
320
      mCurrentPosition[x][y][z].set1(roundedX);
321
      mCurrentPosition[x][y][z].set2(roundedY);
322
      mCurrentPosition[x][y][z].set3(roundedZ);
312 323
      }
313 324

  
314 325
///////////////////////////////////////////////////////////////////////////////////////////////////
315 326

  
316
    public long addNewRotation(int vector, int row, int angle, long durationMillis, EffectListener listener )
327
    boolean isSolved()
317 328
      {
318
      Static3D axis = VectX;
319
      long effectID=0;
320
      boolean first = true;
321

  
322
      switch(vector)
323
        {
324
        case VECTX: axis = VectX; break;
325
        case VECTY: axis = VectY; break;
326
        case VECTZ: axis = VectZ; break;
327
        }
328

  
329
      mRotAxis = vector;
330
      mRotRow  = row;
329
      Static4D q = mQuatScramble[0][0][0];
331 330

  
332
      mRotationAngleStatic.set1(0.0f);
331
      float x = q.get1();
332
      float y = q.get2();
333
      float z = q.get3();
334
      float w = q.get4();
333 335

  
334
      for(int x=0; x<mSize; x++)
335
        for(int y=0; y<mSize; y++)
336
          for(int z=0; z<mSize; z++)
337
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
336
      for(int i = 0; i< mSize; i++)
337
        for(int j = 0; j< mSize; j++)
338
          for(int k = 0; k< mSize; k++)
339
            {
340
            if( i==0 || i==mSize-1 || j==0 || j==mSize-1 || k==0 || k==mSize-1 )
338 341
              {
339
              if( belongsToRotation(x,y,z,vector,mRotRow) )
340
                {
341
                mRotationAxis[x][y][z].set(axis);
342
                mRotationAngle[x][y][z].setDuration(durationMillis);
343
                mRotationAngle[x][y][z].resetToBeginning();
344
                mRotationAngle[x][y][z].add(new Static1D(0));
345
                mRotationAngle[x][y][z].add(new Static1D(angle));
342
              q = mQuatScramble[i][j][k];
346 343

  
347
                if( first )
348
                  {
349
                  first = false;
350
                  effectID = mRotateEffect[x][y][z].getID();
351
                  mRotateEffect[x][y][z].notifyWhenFinished(listener);
352
                  }
344
              if( q.get1()!=x || q.get2()!=y || q.get3()!=z || q.get4()!=w )
345
                {
346
                return false;
353 347
                }
354 348
              }
349
            }
355 350

  
356
      return effectID;
357
      }
358

  
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

  
361
    public int getSize()
362
      {
363
      return mSize;
351
      return true;
364 352
      }
365 353

  
366 354
///////////////////////////////////////////////////////////////////////////////////////////////////
......
415 403
              }
416 404
      }
417 405

  
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

  
420
    void continueRotation(float angleInDegrees)
421
      {
422
      mRotationAngleStatic.set1(angleInDegrees);
423
      }
424

  
425
///////////////////////////////////////////////////////////////////////////////////////////////////
426

  
427
    private int computeNearestAngle(float angle)
428
      {
429
      final int NEAREST = 90;
430

  
431
      int tmp = (int)((angle+NEAREST/2)/NEAREST);
432
      if( angle< -(NEAREST/2) ) tmp-=1;
433

  
434
      return NEAREST*tmp;
435
      }
436

  
437 406
///////////////////////////////////////////////////////////////////////////////////////////////////
438 407

  
439 408
    long finishRotationNow(EffectListener listener)
......
484 453

  
485 454
///////////////////////////////////////////////////////////////////////////////////////////////////
486 455

  
487
    public void removeRotationNow()
456
    void continueRotation(float angleInDegrees)
488 457
      {
489
      float qx=0,qy=0,qz=0;
490
      boolean first = true;
491
      Static4D quat = null;
492

  
493
      switch(mRotAxis)
494
        {
495
        case VECTX: qx=1; break;
496
        case VECTY: qy=1; break;
497
        case VECTZ: qz=1; break;
498
        }
458
      mRotationAngleStatic.set1(angleInDegrees);
459
      }
499 460

  
500
      for(int x=0; x<mSize; x++)
501
        for(int y=0; y<mSize; y++)
502
          for(int z=0; z<mSize; z++)
503
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
504
              {
505
              if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
506
                {
507
                if( first )
508
                  {
509
                  first = false;
510
                  int pointNum = mRotationAngle[x][y][z].getNumPoints();
511

  
512
                  if( pointNum>=1 )
513
                    {
514
                    float startingAngle = mRotationAngle[x][y][z].getPoint(pointNum-1).get1();
515
                    int nearestAngleInDegrees = computeNearestAngle(startingAngle);
516
                    double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
517
                    float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
518
                    float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
519
                    quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
520
                    }
521
                  else
522
                    {
523
                    android.util.Log.e("cube", "ERROR removing rotation!");
524
                    return;
525
                    }
526
                  }
527

  
528
                mRotationAngle[x][y][z].removeAll();
529
                mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z]));
530
                normalizeScrambleQuat(x,y,z);
531
                modifyCurrentPosition(x,y,z,quat);
532
                }
533
              }
534

  
535
      mRotationAngleStatic.set1(0);
536
      }
537

  
538
///////////////////////////////////////////////////////////////////////////////////////////////////
539
// All legal rotation quats must have all four of their components equal to either
540
// 0, 1, -1, 0.5, -0.5 or +-sqrt(2)/2.
541
//
542
// Because of quatMultiplication, errors can accumulate - so to avoid this, we
543
// correct the value of the 'scramble' quat to what it should be.
544
//
545
// We also have to remember that the group of unit quaternions is a double-cover of rotations
546
// in 3D ( q represents the same rotation as -q ) - so invert if needed.
547

  
548
    private static final float SQ2 = 0.5f*((float)Math.sqrt(2));
549
    private static final float[] LEGAL = { 0.0f , 0.5f , -0.5f , 1.0f , -1.0f , SQ2 , -SQ2 };
550

  
551
    private void normalizeScrambleQuat(int i, int j, int k)
552
      {
553
      Static4D quat = mQuatScramble[i][j][k];
554

  
555
      float x = quat.get1();
556
      float y = quat.get2();
557
      float z = quat.get3();
558
      float w = quat.get4();
559
      float diff;
560

  
561
      for(int legal=0; legal<LEGAL.length; legal++)
562
        {
563
        diff = x-LEGAL[legal];
564
        if( diff*diff<0.01f ) x = LEGAL[legal];
565
        diff = y-LEGAL[legal];
566
        if( diff*diff<0.01f ) y = LEGAL[legal];
567
        diff = z-LEGAL[legal];
568
        if( diff*diff<0.01f ) z = LEGAL[legal];
569
        diff = w-LEGAL[legal];
570
        if( diff*diff<0.01f ) w = LEGAL[legal];
571
        }
572

  
573
      if( w<0 )
574
        {
575
        w = -w;
576
        z = -z;
577
        y = -y;
578
        x = -x;
579
        }
580
      else if( w==0 )
581
        {
582
        if( z<0 )
583
          {
584
          z = -z;
585
          y = -y;
586
          x = -x;
587
          }
588
        else if( z==0 )
589
          {
590
          if( y<0 )
591
            {
592
            y = -y;
593
            x = -x;
594
            }
595
          else if( y==0 )
596
            {
597
            if( x<0 )
598
              {
599
              x = -x;
600
              }
601
            }
602
          }
603
        }
604

  
605
      mQuatScramble[i][j][k].set(x,y,z,w);
606
      }
607

  
608
///////////////////////////////////////////////////////////////////////////////////////////////////
609

  
610
    private float getSinkStrength()
611
      {
612
      switch(mSize)
613
        {
614
        case 1 : return 1.1f;
615
        case 2 : return 1.5f;
616
        case 3 : return 1.8f;
617
        case 4 : return 2.0f;
618
        default: return 3.0f - 4.0f/mSize;
619
        }
620
      }
621

  
622
///////////////////////////////////////////////////////////////////////////////////////////////////
623

  
624
    private boolean belongsToRotation(int x, int y, int z, int vector, int row)
625
      {
626
      switch(vector)
627
        {
628
        case VECTX: return mCurrentPosition[x][y][z].get1()==row;
629
        case VECTY: return mCurrentPosition[x][y][z].get2()==row;
630
        case VECTZ: return mCurrentPosition[x][y][z].get3()==row;
631
        }
632

  
633
      return false;
634
      }
635

  
636
///////////////////////////////////////////////////////////////////////////////////////////////////
637

  
638
    private void modifyCurrentPosition(int x, int y, int z, Static4D quat)
639
      {
640
      Static3D current = mCurrentPosition[x][y][z];
641
      float diff = 0.5f*(mSize-1);
642
      float cubitCenterX = current.get1() - diff;
643
      float cubitCenterY = current.get2() - diff;
644
      float cubitCenterZ = current.get3() - diff;
645

  
646
      Static4D cubitCenter =  new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
647
      Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
648

  
649
      float rotatedX = rotatedCenter.get1() + diff;
650
      float rotatedY = rotatedCenter.get2() + diff;
651
      float rotatedZ = rotatedCenter.get3() + diff;
652

  
653
      int roundedX = (int)(rotatedX+0.1f);
654
      int roundedY = (int)(rotatedY+0.1f);
655
      int roundedZ = (int)(rotatedZ+0.1f);
656

  
657
      mCurrentPosition[x][y][z].set1(roundedX);
658
      mCurrentPosition[x][y][z].set2(roundedY);
659
      mCurrentPosition[x][y][z].set3(roundedZ);
660
      }
661

  
662
///////////////////////////////////////////////////////////////////////////////////////////////////
461
///////////////////////////////////////////////////////////////////////////////////////////////////
663 462

  
664 463
    void createTexture()
665 464
      {
......
730 529
      mMove.set( texW*0.5f , texH*0.5f , 0.0f );
731 530
      mScale.set(scaleFactor,scaleFactor,scaleFactor);
732 531
      }
532

  
533
///////////////////////////////////////////////////////////////////////////////////////////////////
534
// PUBLIC API
535
///////////////////////////////////////////////////////////////////////////////////////////////////
536

  
537
    public Static4D getRotationQuat()
538
      {
539
      return mQuatAccumulated;
540
      }
541

  
542
///////////////////////////////////////////////////////////////////////////////////////////////////
543

  
544
    public void apply(Effect effect, int position)
545
      {
546
      for(int x=0; x<mSize; x++)
547
        for(int y=0; y<mSize; y++)
548
          for(int z=0; z<mSize; z++)
549
            {
550
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
551
              {
552
              mEffects[x][y][z].apply(effect, position);
553
              }
554
            }
555
      }
556

  
557
///////////////////////////////////////////////////////////////////////////////////////////////////
558

  
559
    public void remove(long effectID)
560
      {
561
      for(int x=0; x<mSize; x++)
562
        for(int y=0; y<mSize; y++)
563
          for(int z=0; z<mSize; z++)
564
            {
565
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
566
              {
567
              mEffects[x][y][z].abortById(effectID);
568
              }
569
            }
570
      }
571

  
572
///////////////////////////////////////////////////////////////////////////////////////////////////
573

  
574
    public void solve()
575
      {
576
      for(int x=0; x<mSize; x++)
577
        for(int y=0; y<mSize; y++)
578
          for(int z=0; z<mSize; z++)
579
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
580
              {
581
              mQuatScramble[x][y][z].set(0,0,0,1);
582
              mCurrentPosition[x][y][z].set(x,y,z);
583
              }
584
      }
585

  
586
///////////////////////////////////////////////////////////////////////////////////////////////////
587

  
588
    public int getSize()
589
      {
590
      return mSize;
591
      }
592

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

  
595
    public long addNewRotation(int vector, int row, int angle, long durationMillis, EffectListener listener )
596
      {
597
      Static3D axis = VectX;
598
      long effectID=0;
599
      boolean first = true;
600

  
601
      switch(vector)
602
        {
603
        case VECTX: axis = VectX; break;
604
        case VECTY: axis = VectY; break;
605
        case VECTZ: axis = VectZ; break;
606
        }
607

  
608
      mRotAxis = vector;
609
      mRotRow  = row;
610

  
611
      mRotationAngleStatic.set1(0.0f);
612

  
613
      for(int x=0; x<mSize; x++)
614
        for(int y=0; y<mSize; y++)
615
          for(int z=0; z<mSize; z++)
616
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
617
              {
618
              if( belongsToRotation(x,y,z,vector,mRotRow) )
619
                {
620
                mRotationAxis[x][y][z].set(axis);
621
                mRotationAngle[x][y][z].setDuration(durationMillis);
622
                mRotationAngle[x][y][z].resetToBeginning();
623
                mRotationAngle[x][y][z].add(new Static1D(0));
624
                mRotationAngle[x][y][z].add(new Static1D(angle));
625

  
626
                if( first )
627
                  {
628
                  first = false;
629
                  effectID = mRotateEffect[x][y][z].getID();
630
                  mRotateEffect[x][y][z].notifyWhenFinished(listener);
631
                  }
632
                }
633
              }
634

  
635
      return effectID;
636
      }
637

  
638
///////////////////////////////////////////////////////////////////////////////////////////////////
639

  
640
    public void removeRotationNow()
641
      {
642
      float qx=0,qy=0,qz=0;
643
      boolean first = true;
644
      Static4D quat = null;
645

  
646
      switch(mRotAxis)
647
        {
648
        case VECTX: qx=1; break;
649
        case VECTY: qy=1; break;
650
        case VECTZ: qz=1; break;
651
        }
652

  
653
      for(int x=0; x<mSize; x++)
654
        for(int y=0; y<mSize; y++)
655
          for(int z=0; z<mSize; z++)
656
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
657
              {
658
              if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
659
                {
660
                if( first )
661
                  {
662
                  first = false;
663
                  int pointNum = mRotationAngle[x][y][z].getNumPoints();
664

  
665
                  if( pointNum>=1 )
666
                    {
667
                    float startingAngle = mRotationAngle[x][y][z].getPoint(pointNum-1).get1();
668
                    int nearestAngleInDegrees = computeNearestAngle(startingAngle);
669
                    double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
670
                    float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
671
                    float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
672
                    quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
673
                    }
674
                  else
675
                    {
676
                    android.util.Log.e("cube", "ERROR removing rotation!");
677
                    return;
678
                    }
679
                  }
680

  
681
                mRotationAngle[x][y][z].removeAll();
682
                mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z]));
683
                normalizeScrambleQuat(x,y,z);
684
                modifyCurrentPosition(x,y,z,quat);
685
                }
686
              }
687

  
688
      mRotationAngleStatic.set1(0);
689
      }
733 690
}

Also available in: Unified diff