Project

General

Profile

« Previous | Next » 

Revision 542ec777

Added by Leszek Koltunski over 3 years ago

Square-1: looks to be finished.

View differences:

src/main/java/org/distorted/effects/scramble/ScrambleEffect.java
67 67

  
68 68
  private EffectController mController;
69 69
  private int mEffectReturned;
70
  private int mNumDoubleScramblesLeft, mNumScramblesLeft;
71
  private long mDurationSingleTurn;
70
  private int mNumScramblesLeft;
71
  private long mDurationPerDegree;
72 72
  private final Random mRnd;
73 73
  private int[] mBasicAngle;
74 74
  private boolean mRotReady, mPluginReady;
......
96 96
  abstract void effectFinishedPlugin(final long effectID);
97 97

  
98 98
///////////////////////////////////////////////////////////////////////////////////////////////////
99
// first compute how many out of 'numScrambles' are double turns (this will matter when we compute
100
// the time a single quarter-turn takes!
101
//
102
// Only works for
103
// basicAngle==5, i.e. something whose rotations are by  72 degrees (Megaminx) or
104
// basicAngle==4, i.e. something whose rotations are by  90 degrees (RubikCube) or
105
// basicAngle==3, i.e. something whose rotations are by 120 degrees (Pyramix) or
106
// basicAngle==2, i.e. something whose rotations are by 180 degrees (e.g. a 3x2x1 'Bunny')
107 99

  
108 100
  private void createBaseEffects(int duration, int numScrambles)
109 101
    {
110 102
    mNumScramblesLeft = numScrambles;
111
    mNumDoubleScramblesLeft=0;
103
    int absAngle, angle, axis, basicDegrees, totalDegrees = 0;
112 104

  
113 105
    for(int scramble=0; scramble<mNumScramblesLeft; scramble++)
114 106
      {
115 107
      mObject.randomizeNewScramble(mScrambles, mRnd, scramble);
116
      int angle = mScrambles[scramble][2];
117
      if( angle==2 || angle==-2 ) mNumDoubleScramblesLeft++;
108
      axis  = mScrambles[scramble][0];
109
      angle = mScrambles[scramble][2];
110
      absAngle = (angle<0 ? -angle : angle);
111
      basicDegrees = 360/mBasicAngle[axis];
112
      totalDegrees += absAngle*basicDegrees;
118 113
      }
119 114

  
120
    mDurationSingleTurn = duration/(mNumScramblesLeft+mNumDoubleScramblesLeft);
115
    mDurationPerDegree = duration/totalDegrees;
121 116
    mNumScrambles = 0;
122 117

  
123 118
    mRotReady    = false;
......
127 122
    }
128 123

  
129 124
///////////////////////////////////////////////////////////////////////////////////////////////////
130
// only works if basicAngle<=5
131 125

  
132 126
  private void addNewScramble()
133 127
    {
......
137 131
      int row  = mScrambles[mNumScrambles][1];
138 132
      int angle= mScrambles[mNumScrambles][2];
139 133

  
140
      int rowBitmap  = (1<<row);
134
      int rowBitmap= (1<<row);
141 135
      int absAngle = (angle<0 ? -angle : angle);
142
      long durationMillis = absAngle*mDurationSingleTurn;
136
      int basicDegrees  = 360/mBasicAngle[axis];
137
      long durationMillis = absAngle*basicDegrees*mDurationPerDegree;
143 138

  
144 139
      mNumScramblesLeft--;
145
      if( absAngle==2 ) mNumDoubleScramblesLeft--;
146

  
147
      if( mNumScramblesLeft==0 && mNumDoubleScramblesLeft!=0 )
148
        {
149
        android.util.Log.e("effect", "ERROR: "+mNumDoubleScramblesLeft);
150
        }
151

  
152
      mController.addRotation(this, axis, rowBitmap, angle*(360/mBasicAngle[axis]), durationMillis);
153

  
140
      mController.addRotation(this, axis, rowBitmap, angle*basicDegrees, durationMillis);
154 141
      mNumScrambles++;
155 142
      }
156 143
    else
157 144
      {
158
      if( mEffectReturned == mCubeEffectNumber+mNodeEffectNumber )
159
        {
160
        mRotReady = true;
161
        if( mPluginReady ) mController.effectFinished(FAKE_EFFECT_ID);
162
        }
145
      mRotReady = true;
146
      if( mPluginReady ) mController.effectFinished(FAKE_EFFECT_ID);
163 147
      }
164 148
    }
165 149

  
src/main/java/org/distorted/objects/TwistyObject.java
888 888
        int index = CUBITS[i].removeRotationNow(quat);
889 889
        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),index);
890 890
        }
891
/*
892
    if( NUM_CUBITS==18 )
893
      {
894
      boolean error=false;
895
      String str="";
896

  
897
      for(int i=10; i<18; i++)
898
        {
899
        int q = CUBITS[i].mQuatIndex;
900

  
901
        str += (" "+q);
902

  
903
        if( (((i%2)==0) && (q==2 || q== 8 || q==17 || q==23)) ||
904
            (((i%2)==1) && (q==5 || q==11 || q==14 || q==20))  )
905
           error=true;
906
        }
907

  
908
      if( error ) str+= " ERROR";
909
      android.util.Log.e("D", "cubit: "+str);
910
      }
911

  
912
 */
891 913
    }
892 914

  
893 915
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/TwistySquare1.java
40 40

  
41 41
class TwistySquare1 extends TwistyObject
42 42
{
43
  private static final int LAST_SL = 0; // automatic rotations: last rot was a 'slash' i.e. along ROT_AXIS[1]
44
  private static final int LAST_UP = 1; // last rot was along ROT_AXIS[0], upper layer and forelast was a slash
45
  private static final int LAST_LO = 2; // last rot was along ROT_AXIS[0], lower layer and forelast was a slash
46
  private static final int LAST_UL = 3; // two last rots were along ROT_AXIS[0] (so the next must be a slash)
47

  
43 48
  private static final float COS15 = (SQ6+SQ2)/4;
44 49
  private static final float SIN15 = (SQ6-SQ2)/4;
45 50
  private static final float     X = 3*(2-SQ3)/2;
......
232 237
    {
233 238
      { 2, 8,17,23},
234 239
      { 5,11,14,20},
235
      { 8, 2,23,17},
236
      {11, 5,20,14},
237
      {17,23, 2, 8},
238
      {14,20, 5,11},
239
      {23,17, 8, 2},
240
      {20,14,11, 5}
241 240
    };
242 241

  
243
  // QUAT[i]*QUAT[j] = QUAT_MULT[i][j]
242
  // QUATS[i]*QUATS[j] = QUATS[QUAT_MULT[i][j]]
244 243
  private static final int[][] QUAT_MULT = new int[][]
245 244
    {
246 245
      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,},
......
271 270

  
272 271
  private static MeshBase[] mMeshes;
273 272

  
273
  private final int[][] mPermittedAngles;
274
  private final int[] mCornerQuat;
275
  private int mLastRot, mPermittedUp, mPermittedDo;
276

  
274 277
///////////////////////////////////////////////////////////////////////////////////////////////////
275 278

  
276 279
  TwistySquare1(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
277 280
                DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
278 281
    {
279 282
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.SQU1, res, scrWidth);
283

  
284
    mLastRot = LAST_SL;
285
    mPermittedAngles = new int[2][BASIC_ANGLE[0]];
286
    mCornerQuat = new int[8];
280 287
    }
281 288

  
282 289
///////////////////////////////////////////////////////////////////////////////////////////////////
......
503 510
    return rowBitmap;
504 511
    }
505 512

  
513
///////////////////////////////////////////////////////////////////////////////////////////////////
514

  
515
  private boolean cornerIsUp(int index)
516
    {
517
    return ((index<4) ^ (mCornerQuat[index]>=12));
518
    }
519

  
520
///////////////////////////////////////////////////////////////////////////////////////////////////
521

  
522
  private boolean cornerIsLeft(int index)
523
    {
524
    int q = mCornerQuat[index];
525

  
526
    switch(index)
527
      {
528
      case 0:
529
      case 4: return ((q>=3 && q<= 7) || (q>=18 && q<=22));
530
      case 1:
531
      case 5: return ((q>=6 && q<=10) || (q>=15 && q<=19));
532
      case 2:
533
      case 6: return ((q==0 || q==1 || (q>=9 && q<=11)) || (q>=12 && q<=16));
534
      case 3:
535
      case 7: return ((q>=0 && q<=4) || (q==12 || q==13 || (q>=21 && q<=23)));
536
      }
537

  
538
    return false;
539
    }
540

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

  
543
  private boolean quatIsBad(int quatIndex, int corner)
544
    {
545
    int index = (corner%2);
546

  
547
    return ( quatIndex==BAD_CORNER_QUATS[index][0] ||
548
             quatIndex==BAD_CORNER_QUATS[index][1] ||
549
             quatIndex==BAD_CORNER_QUATS[index][2] ||
550
             quatIndex==BAD_CORNER_QUATS[index][3]  );
551
    }
552

  
553
///////////////////////////////////////////////////////////////////////////////////////////////////
554

  
555
  private boolean isPermittedDo(int angle)
556
    {
557
    for(int corner=0; corner<8; corner++)
558
      {
559
      if( !cornerIsUp(corner) )
560
        {
561
        int currQuat = mCornerQuat[corner];
562
        int finalQuat= QUAT_MULT[angle][currQuat];
563
        if( quatIsBad(finalQuat,corner) ) return false;
564
        }
565
      }
566

  
567
    return true;
568
    }
569

  
570
///////////////////////////////////////////////////////////////////////////////////////////////////
571

  
572
  private boolean isPermittedUp(int angle)
573
    {
574
    for(int corner=0; corner<8; corner++)
575
      {
576
//android.util.Log.e("D", "isPermittedUp: up corner: "+corner+" angle: "+angle);
577

  
578

  
579
      if( cornerIsUp(corner) )
580
        {
581
        int currQuat = mCornerQuat[corner];
582
        int finalQuat= QUAT_MULT[angle][currQuat];
583

  
584
//boolean bad = quatIsBad(finalQuat,corner);
585
//android.util.Log.e("D", "isPermittedUp: up corner: "+corner+" angle: "+angle+" is bad: "+bad);
586

  
587
        if( quatIsBad(finalQuat,corner) ) return false;
588
        }
589
      }
590

  
591
    return true;
592
    }
593

  
594
///////////////////////////////////////////////////////////////////////////////////////////////////
595

  
596
  private void computePermittedAngles()
597
    {
598
    mPermittedDo = 0;
599

  
600
    for(int angle=0; angle<BASIC_ANGLE[0]; angle++)
601
      {
602
      if( isPermittedDo(angle ) ) mPermittedAngles[0][mPermittedDo++] = angle;
603
      }
604

  
605
    mPermittedUp = 0;
606

  
607
    for(int angle=0; angle<BASIC_ANGLE[0]; angle++)
608
      {
609
      if( isPermittedUp(angle ) ) mPermittedAngles[1][mPermittedUp++] = angle;
610
      }
611
/*
612
    String strDo="";
613

  
614
    for(int i=0; i<mPermittedDo; i++)
615
      {
616
      strDo += (" "+mPermittedAngles[0][i]);
617
      }
618

  
619
    String strUp="";
620

  
621
    for(int i=0; i<mPermittedUp; i++)
622
      {
623
      strUp += (" "+mPermittedAngles[1][i]);
624
      }
625

  
626
    android.util.Log.e("D", "up  : "+strUp);
627
    android.util.Log.e("D", "down: "+strDo);
628

  
629
 */
630
    }
631

  
632
///////////////////////////////////////////////////////////////////////////////////////////////////
633

  
634
  private int getNextAngle(Random rnd, int layer)
635
    {
636
    int basic = BASIC_ANGLE[0];
637
    int num = layer==0 ? mPermittedDo:mPermittedUp;
638
    int index = rnd.nextInt(num);
639
    int angle = mPermittedAngles[layer][index];
640
    return angle<basic/2 ? -angle : basic-angle;
641
    }
642

  
643
///////////////////////////////////////////////////////////////////////////////////////////////////
644

  
645
  private int getNextAngleNotZero(Random rnd, int layer)
646
    {
647
    int basic = BASIC_ANGLE[0];
648
    int num = layer==0 ? mPermittedDo:mPermittedUp;
649
    int index = rnd.nextInt(num-1);
650
    int angle = mPermittedAngles[layer][index+1];
651
    return angle<basic/2 ? -angle : basic-angle;
652
    }
653

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

  
656
  private int makeQuat(int axis,int index)
657
    {
658
    if( axis==1 ) return 13;
659
    if( index<0 ) index+=12;
660
    return index;
661
    }
662

  
663
///////////////////////////////////////////////////////////////////////////////////////////////////
664

  
665
  private boolean cornerBelongs(int index, int axis, int layer)
666
    {
667
    if( axis==0 )
668
      {
669
      boolean up = cornerIsUp(index);
670
      return ((up && layer==2) || (!up && layer==0));
671
      }
672
    else
673
      {
674
      boolean le = cornerIsLeft(index);
675
      return ((le && layer==0) || (!le && layer==1));
676
      }
677
    }
678

  
679
///////////////////////////////////////////////////////////////////////////////////////////////////
680

  
681
  private void updateCornerQuats(int[] rotInfo)
682
    {
683
    int axis = rotInfo[0];
684
    int layer= rotInfo[1];
685
    int index=-rotInfo[2];
686

  
687
    int quat = makeQuat(axis,index);
688

  
689
    for(int corner=0; corner<8; corner++)
690
      {
691
      if( cornerBelongs(corner,axis,layer) )
692
        {
693
        int curr = mCornerQuat[corner];
694
        mCornerQuat[corner] = QUAT_MULT[quat][curr];
695
        }
696
      }
697
/*
698
    String q="";
699

  
700
    for(int c=0; c<8; c++)
701
      {
702
      q += (" "+mCornerQuat[c]);
703
      }
704

  
705
    android.util.Log.d("D", "quat="+quat+" corner quats now= "+q);
706
*/
707
    }
708

  
506 709
///////////////////////////////////////////////////////////////////////////////////////////////////
507 710
// PUBLIC API
508 711

  
......
519 722
    }
520 723

  
521 724
///////////////////////////////////////////////////////////////////////////////////////////////////
522
// TODO
523 725

  
524 726
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
525 727
    {
728
    int layer, nextAngle;
729

  
526 730
    if( num==0 )
527 731
      {
528
      scramble[num][0] = rnd.nextInt(NUM_AXIS);
732
      for(int corner=0; corner<8; corner++) mCornerQuat[corner] = 0;
733
      mLastRot = rnd.nextInt(4);
734
      computePermittedAngles();
529 735
      }
530
    else
531
      {
532
      int newVector = rnd.nextInt(NUM_AXIS-1);
533
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
534
      }
535

  
536
    scramble[num][1] = rnd.nextFloat()<=0.5f ? 0 : 1;
537 736

  
538
    switch( rnd.nextInt(4) )
737
    switch(mLastRot)
539 738
      {
540
      case 0: scramble[num][2] = -2; break;
541
      case 1: scramble[num][2] = -1; break;
542
      case 2: scramble[num][2] =  1; break;
543
      case 3: scramble[num][2] =  2; break;
739
      case LAST_SL: layer = rnd.nextInt(2);
740
                    nextAngle = getNextAngle(rnd,layer);
741

  
742
                    if( nextAngle==0 )
743
                      {
744
                      layer = 1-layer;
745
                      nextAngle = getNextAngleNotZero(rnd,layer);
746
                      }
747

  
748
                    scramble[num][0] = 0;
749
                    scramble[num][1] = 2*layer;
750
                    scramble[num][2] = nextAngle;
751
                    mLastRot = layer==0 ? LAST_LO : LAST_UP;
752
                    updateCornerQuats(scramble[num]);
753

  
754
//android.util.Log.e("D", "SL axis="+scramble[num][0]+" layer="+scramble[num][1]+" angle="+scramble[num][2]);
755

  
756
                    break;
757
      case LAST_LO:
758
      case LAST_UP: layer = mLastRot==LAST_LO ? 1:0;
759
                    nextAngle = getNextAngle(rnd,layer);
760

  
761
                    if( nextAngle!=0 )
762
                      {
763
                      scramble[num][0] = 0;
764
                      scramble[num][1] = 2*layer;
765
                      scramble[num][2] = nextAngle;
766
                      updateCornerQuats(scramble[num]);
767
                      mLastRot = LAST_UL;
768
//android.util.Log.e("D", "LO/UP 1 axis="+scramble[num][0]+" layer="+scramble[num][1]+" angle="+scramble[num][2]);
769
                      }
770
                    else
771
                      {
772
                      scramble[num][0] = 1;
773
                      scramble[num][1] = rnd.nextInt(2);
774
                      scramble[num][2] = 1;
775
                      mLastRot = LAST_SL;
776
                      updateCornerQuats(scramble[num]);
777
                      computePermittedAngles();
778
//android.util.Log.e("D", "LO/UP 2 axis="+scramble[num][0]+" layer="+scramble[num][1]+" angle="+scramble[num][2]);
779
                      }
780

  
781
                    break;
782
      case LAST_UL: scramble[num][0] = 1;
783
                    scramble[num][1] = rnd.nextInt(2);
784
                    scramble[num][2] = 1;
785
                    mLastRot = LAST_SL;
786
                    updateCornerQuats(scramble[num]);
787
                    computePermittedAngles();
788
//android.util.Log.e("D", "UL axis="+scramble[num][0]+" layer="+scramble[num][1]+" angle="+scramble[num][2]);
789

  
790
                    break;
544 791
      }
545 792
    }
546 793

  

Also available in: Unified diff