Project

General

Profile

« Previous | Next » 

Revision 59b87d56

Added by Leszek Koltunski over 3 years ago

Adding Rex Cube - take 1 (doesn't work yet)

View differences:

src/main/java/org/distorted/objects/FactoryCubit.java
38 38
  static final float IVY_D = 0.003f;
39 39
  static final float IVY_C = 0.59f;
40 40
  static final float IVY_M = 0.35f;
41
  static final float REX_D = 0.03f;
41 42

  
42 43
  private static final float SQ2 = (float)Math.sqrt(2);
43 44
  private static final float SQ3 = (float)Math.sqrt(3);
44 45
  private static final float SQ6 = (float)Math.sqrt(6);
45 46

  
46 47
  private static final int IVY_N = 8;
48
  private static final int REX_N = 5;
47 49
  private static final Static1D RADIUS = new Static1D(1);
48 50
  private static FactoryCubit mThis;
49 51

  
......
192 194
      }
193 195
    }
194 196

  
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198
// Compute (rx,ry) - coords of a point which is the result of rotation by angle 'angle' of the point
199
// (px,py) along axis Z. Center of rotation: (cx,cy).
200
// Write (rx,ry) to array[index] and array[index+1].
201

  
202
  private void writeVertex( float cx, float cy, float px, float py, float angle, float[] array, int index)
203
    {
204
    float vx = px-cx;
205
    float vy = py-cy;
206

  
207
    double radAngle = Math.PI*angle/180;
208
    float sinA = (float)Math.sin(radAngle);
209
    float cosA = (float)Math.cos(radAngle);
210

  
211
    float rvx = vx*cosA +vy*sinA;
212
    float rvy =-vx*sinA +vy*cosA;
213

  
214
    array[index  ] = rvx + cx;
215
    array[index+1] = rvy + cy;
216
    }
217

  
195 218
///////////////////////////////////////////////////////////////////////////////////////////////////
196 219

  
197 220
  MeshBase createFacesCube(int sizeIndex)
......
578 601
    return new MeshJoined(meshes);
579 602
    }
580 603

  
604
///////////////////////////////////////////////////////////////////////////////////////////////////
605

  
606
  MeshBase createFacesRexCorner()
607
    {
608
    MeshBase[] meshes = new MeshBase[2];
609

  
610
    final float angle = (float)Math.PI/(6*REX_N);
611
    float[] vertices = new float[6*REX_N];
612
    final float H = SQ2*(SQ3/3 - 0.5f);
613
    final float D = 0.5f - REX_D;
614
    final float F = H*D;
615
    final float B = (float)Math.sqrt(12/(H*H) - 0.75f) - 0.5f;
616

  
617
    final float V1x = -F*0.5f;
618
    final float V1y = -F*SQ3/6;
619
    final float V2x = -V1x;
620
    final float V2y = V1y;
621
    final float V3x = 0.0f;
622
    final float V3y = -2*V1y;
623

  
624
    final float C1x = 0.0f;
625
    final float C1y = -D*( (SQ3/6)*H - (float)Math.sqrt(4.0f-0.25f*H*H) );
626
    final float C2x = B*V2x;
627
    final float C2y = B*V2y;
628
    final float C3x = B*V3x;
629
    final float C3y = B*V3y;
630

  
631
    for(int i=0; i<REX_N; i++)
632
      {
633
      writeVertex(C1x,C1y,V1x,V1y, i*angle, vertices, 2*i          );
634
      writeVertex(C2x,C2y,V2x,V2y, i*angle, vertices, 2*i + 2*REX_N);
635
      writeVertex(C3x,C3y,V3x,V3y, i*angle, vertices, 2*i + 4*REX_N);
636
      }
637

  
638
    float[] bands0 = computeBands(+0.03f,35,0.5f,0.5f,5);
639
    float[] bands1 = computeBands(-0.10f,45,0.5f,0.0f,2);
640

  
641
    meshes[0] = new MeshPolygon(vertices,bands0,1,1);
642
    meshes[0].setEffectAssociation(0,1,0);
643
    meshes[1] = new MeshPolygon(vertices,bands1,0,0);
644
    meshes[1].setEffectAssociation(0,2,0);
645

  
646
    return new MeshJoined(meshes);
647
    }
648

  
649
///////////////////////////////////////////////////////////////////////////////////////////////////
650

  
651
  MeshBase createFacesRexFace()
652
    {
653
    MeshBase[] meshes = new MeshBase[2];
654

  
655
    final float angle = (float)Math.PI/(6*REX_N);
656
    float[] vertices = new float[8*REX_N];
657
    final float H = SQ3/2 - 0.5f;
658
    final float D = 0.5f - REX_D;
659
    final float F = H*D;
660

  
661
    final float V1x = 0.0f;
662
    final float V1y = +F;
663
    final float V2x = +F;
664
    final float V2y = 0.0f;
665
    final float V3x = 0.0f;
666
    final float V3y = -F;
667
    final float V4x = -F;
668
    final float V4y = 0.0f;
669

  
670
    final float C1x = -D;
671
    final float C1y = -D;
672
    final float C2x = -D;
673
    final float C2y = +D;
674
    final float C3x = +D;
675
    final float C3y = +D;
676
    final float C4x = +D;
677
    final float C4y = -D;
678

  
679
    for(int i=0; i<REX_N; i++)
680
      {
681
      writeVertex(C1x,C1y,V1x,V1y, i*angle, vertices, 2*i          );
682
      writeVertex(C2x,C2y,V2x,V2y, i*angle, vertices, 2*i + 2*REX_N);
683
      writeVertex(C3x,C3y,V3x,V3y, i*angle, vertices, 2*i + 4*REX_N);
684
      writeVertex(C4x,C4y,V4x,V4y, i*angle, vertices, 2*i + 6*REX_N);
685
      }
686

  
687
    float[] bands0 = computeBands(+0.03f,35,0.5f,0.5f,5);
688
    float[] bands1 = computeBands(-0.10f,45,0.5f,0.0f,2);
689

  
690
    meshes[0] = new MeshPolygon(vertices,bands0,0,0);
691
    meshes[0].setEffectAssociation(0,1,0);
692
    meshes[1] = new MeshPolygon(vertices,bands1,0,0);
693
    meshes[1].setEffectAssociation(0,2,0);
694

  
695
    return new MeshJoined(meshes);
696
    }
697

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

  
700
  MeshBase createFacesRexEdge()
701
    {
702
    MeshBase[] meshes = new MeshBase[4];
703

  
704
    final float angle = (float)Math.PI/(6*REX_N);
705
    float[] vertices = new float[4*REX_N + 4];
706
    final float H = 1.0f - SQ3/2;
707
    final float D = 0.5f - REX_D;
708
    final float F = H*D;
709

  
710
    final float V1x = -D;
711
    final float V1y = +D - D*SQ3/2;
712
    final float V2x = 0.0f;
713
    final float V2y = D*(SQ3-1) - D*SQ3/2;
714

  
715
    final float C1x = -D;
716
    final float C1y = -D - D*SQ3/2;
717
    final float C2x = +D;
718
    final float C2y = C1y;
719

  
720
    for(int i=0; i<REX_N; i++)
721
      {
722
      writeVertex(C1x,C1y,V1x,V1y, i*angle, vertices, 2*i          );
723
      writeVertex(C2x,C2y,V2x,V2y, i*angle, vertices, 2*i + 2*REX_N);
724
      }
725

  
726
    vertices[4*REX_N  ] = +D;
727
    vertices[4*REX_N+1] = +F + REX_D;
728
    vertices[4*REX_N+2] = -D;
729
    vertices[4*REX_N+3] = +F + REX_D;
730

  
731
    float[] bands0 = computeBands(+0.03f,35,0.5f,0.5f,5);
732
    float[] bands1 = computeBands(-0.10f,45,0.5f,0.0f,2);
733

  
734
    meshes[0] = new MeshPolygon(vertices,bands0,1,2);
735
    meshes[0].setEffectAssociation(0,1,0);
736
    meshes[1] = meshes[0].copy(true);
737
    meshes[1].setEffectAssociation(0,2,0);
738
    meshes[2] = new MeshPolygon(vertices,bands1,0,0);
739
    meshes[2].setEffectAssociation(0,4,0);
740
    meshes[3] = meshes[2].copy(true);
741
    meshes[3].setEffectAssociation(0,8,0);
742

  
743
    return new MeshJoined(meshes);
744
    }
745

  
581 746
///////////////////////////////////////////////////////////////////////////////////////////////////
582 747
// EFFECTS
583 748
///////////////////////////////////////////////////////////////////////////////////////////////////
......
1005 1170
    return effect;
1006 1171
    }
1007 1172

  
1173
///////////////////////////////////////////////////////////////////////////////////////////////////
1174

  
1175
  VertexEffect[] createVertexEffectsRexEdge()
1176
    {
1177
    final float H = 1.0f - SQ3/2;
1178
    final float D = 0.5f - REX_D;
1179
    final float F = H*D;
1180

  
1181
    Static3D move  = new Static3D(0.0f, 0.5f - F, 0.0f);
1182
    Static3D center= new Static3D(0.0f, F, 0.0f);
1183
    Static3D axisX = new Static3D(1.0f, 0.0f, 0.0f);
1184
    Static3D axisY = new Static3D(0.0f, 1.0f, 0.0f);
1185

  
1186
    Static1D angle180 = new Static1D(180);
1187
    Static1D angle90  = new Static1D( 90);
1188

  
1189
    VertexEffect[] effect = new VertexEffect[3];
1190

  
1191
    effect[0] = new VertexEffectRotate(angle180, axisY, center);
1192
    effect[1] = new VertexEffectRotate(angle90 , axisX, center);
1193
    effect[2] = new VertexEffectMove(move);
1194

  
1195
    effect[0].setMeshAssociation(10,-1);  // meshes 1 & 3
1196
    effect[1].setMeshAssociation(10,-1);  // meshes 1 & 3
1197

  
1198
    return effect;
1199
    }
1200

  
1201
///////////////////////////////////////////////////////////////////////////////////////////////////
1202

  
1203
  VertexEffect[] createVertexEffectsRexCorner()
1204
    {
1205
    float F = SQ3/6*(1.0f-2*REX_D);
1206
    Static3D move  = new Static3D(F,F,0.0f);
1207
    Static3D center= new Static3D(0.0f, 0.0f, 0.0f);
1208
    Static3D axisZ = new Static3D(0.0f, 0.0f, 1.0f);
1209
    Static1D angle = new Static1D(45);
1210

  
1211
    VertexEffect[] effect = new VertexEffect[2];
1212

  
1213
    effect[0] = new VertexEffectRotate(angle, axisZ, center);
1214
    effect[1] = new VertexEffectMove(move);
1215

  
1216
    return effect;
1217
    }
1218

  
1008 1219
///////////////////////////////////////////////////////////////////////////////////////////////////
1009 1220
// OBJECTS
1010 1221
///////////////////////////////////////////////////////////////////////////////////////////////////
......
1298 1509
    mesh.addEmptyTexComponent();
1299 1510
    mesh.addEmptyTexComponent();
1300 1511

  
1512
    return mesh;
1513
    }
1514

  
1515
///////////////////////////////////////////////////////////////////////////////////////////////////
1516

  
1517
  MeshBase createRexCornerMesh()
1518
    {
1519
    MeshBase mesh = createFacesRexCorner();
1520
    VertexEffect[] effects = createVertexEffectsRexCorner();
1521
    for( VertexEffect effect : effects ) mesh.apply(effect);
1522

  
1523
    Static3D center = new Static3D(0.0f,0.0f,-0.25f);
1524
    Static3D[] vertices = new Static3D[1];
1525
    vertices[0] = new Static3D(+0.25f,+0.25f,+0.0f);
1526
    roundCorners(mesh,center,vertices,0.03f,0.10f);
1527

  
1528
    mesh.mergeEffComponents();
1529
    mesh.addEmptyTexComponent();
1530
    mesh.addEmptyTexComponent();
1531

  
1532
    return mesh;
1533
    }
1534

  
1535
///////////////////////////////////////////////////////////////////////////////////////////////////
1536

  
1537
  MeshBase createRexFaceMesh()
1538
    {
1539
    MeshBase mesh = createFacesRexFace();
1540

  
1541
    mesh.mergeEffComponents();
1542
    mesh.addEmptyTexComponent();
1543
    mesh.addEmptyTexComponent();
1544

  
1545
    return mesh;
1546
    }
1547

  
1548
///////////////////////////////////////////////////////////////////////////////////////////////////
1549

  
1550
  MeshBase createRexEdgeMesh()
1551
    {
1552
    MeshBase mesh = createFacesRexEdge();
1553
    VertexEffect[] effects = createVertexEffectsRexEdge();
1554
    for( VertexEffect effect : effects ) mesh.apply(effect);
1555

  
1556
    Static3D center = new Static3D(0.0f,-0.5f,-0.5f);
1557
    Static3D[] vertices = new Static3D[2];
1558
    vertices[0] = new Static3D(+0.5f,+0.0f,+0.0f);
1559
    vertices[1] = new Static3D(-0.5f,+0.0f,+0.0f);
1560
    roundCorners(mesh,center,vertices,0.03f,0.10f);
1561

  
1562
    mesh.mergeEffComponents();
1563

  
1301 1564
    return mesh;
1302 1565
    }
1303 1566
  }
src/main/java/org/distorted/objects/FactorySticker.java
239 239
    canvas.drawArc( left+cx3-halfR, top+cy3-halfR, left+cx3+halfR, top+cy3+halfR, 180, 90, false, paint);
240 240
    canvas.drawArc( left+cx4-halfR, top+cy4-halfR, left+cx4+halfR, top+cy4+halfR,   0, 90, false, paint);
241 241
    }
242

  
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244
// TODO
245

  
246
  void drawRexCornerSticker(Canvas canvas, Paint paint, int left, int top, int color, float stroke, float radius)
247
    {
248
    paint.setColor(color);
249
    paint.setStyle(Paint.Style.FILL);
250
    canvas.drawRect(left,top,left+TEXTURE_HEIGHT,top+TEXTURE_HEIGHT,paint);
251
    }
252

  
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254
// TODO
255

  
256
  void drawRexFaceSticker(Canvas canvas, Paint paint, int left, int top, int color, float stroke, float radius)
257
    {
258
    paint.setColor(color);
259
    paint.setStyle(Paint.Style.FILL);
260
    canvas.drawRect(left,top,left+TEXTURE_HEIGHT,top+TEXTURE_HEIGHT,paint);
261
    }
262

  
263
///////////////////////////////////////////////////////////////////////////////////////////////////
264
// TODO
265

  
266
  void drawRexEdgeSticker(Canvas canvas, Paint paint, int left, int top, int color, float stroke, float radius)
267
    {
268
    paint.setColor(color);
269
    paint.setStyle(Paint.Style.FILL);
270
    canvas.drawRect(left,top,left+TEXTURE_HEIGHT,top+TEXTURE_HEIGHT,paint);
271
    }
242 272
  }
src/main/java/org/distorted/objects/MovementRex.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
package org.distorted.objects;
21

  
22
import org.distorted.library.type.Static3D;
23

  
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

  
26
class MovementRex extends Movement
27
{
28
  static final float DIST3D = 0.5f;
29
  static final float DIST2D = 0.5f;
30

  
31
  static final Static3D[] FACE_AXIS = new Static3D[]
32
         {
33
           new Static3D(1,0,0), new Static3D(-1,0,0),
34
           new Static3D(0,1,0), new Static3D(0,-1,0),
35
           new Static3D(0,0,1), new Static3D(0,0,-1)
36
         };
37

  
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

  
40
  MovementRex()
41
    {
42
    super(TwistyRex.ROT_AXIS, FACE_AXIS, DIST3D, DIST2D);
43
    }
44

  
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46

  
47
  int computeRowFromOffset(int face, int size, float offset)
48
    {
49
    return offset<DIST2D ? 0:2;
50
    }
51

  
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53

  
54
  public float returnRotationFactor(int size, int row)
55
    {
56
    return 1.0f;
57
    }
58

  
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60
// _____________
61
// |  \  0  /  |
62
// |   \   /   |
63
// | 3 |   | 1 |
64
// |   /   \   |
65
// |  /  2  \  |
66
// -------------
67

  
68
  private int getQuarter(float[] touchPoint)
69
    {
70
    boolean p0 = touchPoint[1] >= touchPoint[0];
71
    boolean p1 = touchPoint[1] >=-touchPoint[0];
72

  
73
    if( p0 )  return p1 ? 0:3;
74
    else      return p1 ? 1:2;
75
    }
76

  
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

  
79
  boolean isInsideFace(int face, float[] p)
80
    {
81
    return ( p[0]<=DIST2D && p[0]>=-DIST2D && p[1]<=DIST2D && p[1]>=-DIST2D );
82
    }
83

  
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

  
86
  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
87
    {
88
    enabled[0] = 2;
89

  
90
    int quarter = getQuarter(touchPoint);
91

  
92
    switch(face)
93
      {
94
      case 0: switch(quarter)
95
                {
96
                case 0: enabled[1]=0; enabled[2]=1; break;
97
                case 1: enabled[1]=3; enabled[2]=1; break;
98
                case 2: enabled[1]=2; enabled[2]=3; break;
99
                case 3: enabled[1]=0; enabled[2]=2; break;
100
                }
101
              break;
102
      case 1: switch(quarter)
103
                {
104
                case 0: enabled[1]=2; enabled[2]=3; break;
105
                case 1: enabled[1]=3; enabled[2]=1; break;
106
                case 2: enabled[1]=0; enabled[2]=1; break;
107
                case 3: enabled[1]=0; enabled[2]=2; break;
108
                }
109
              break;
110
      case 2: switch(quarter)
111
                {
112
                case 0: enabled[1]=1; enabled[2]=2; break;
113
                case 1: enabled[1]=0; enabled[2]=1; break;
114
                case 2: enabled[1]=0; enabled[2]=3; break;
115
                case 3: enabled[1]=2; enabled[2]=3; break;
116
                }
117
              break;
118
      case 3: switch(quarter)
119
                {
120
                case 0: enabled[1]=1; enabled[2]=2; break;
121
                case 1: enabled[1]=2; enabled[2]=3; break;
122
                case 2: enabled[1]=0; enabled[2]=3; break;
123
                case 3: enabled[1]=0; enabled[2]=1; break;
124
                }
125
              break;
126
      case 4: switch(quarter)
127
                {
128
                case 0: enabled[1]=0; enabled[2]=3; break;
129
                case 1: enabled[1]=0; enabled[2]=2; break;
130
                case 2: enabled[1]=1; enabled[2]=2; break;
131
                case 3: enabled[1]=1; enabled[2]=3; break;
132
                }
133
              break;
134
      case 5: switch(quarter)
135
                {
136
                case 0: enabled[1]=1; enabled[2]=2; break;
137
                case 1: enabled[1]=0; enabled[2]=2; break;
138
                case 2: enabled[1]=0; enabled[2]=3; break;
139
                case 3: enabled[1]=1; enabled[2]=3; break;
140
                }
141
              break;
142
      }
143
    }
144
}
src/main/java/org/distorted/objects/ObjectList.java
120 120
         new MovementIvy(),
121 121
         3
122 122
       ),
123

  
124
   REX (
125
         new int[][] {
126
                       {3 , 16, R.raw.ivy, R.drawable.ui_small_ivy, R.drawable.ui_medium_ivy, R.drawable.ui_big_ivy, R.drawable.ui_huge_ivy} ,
127
                     },
128
         TwistyRex.class,
129
         new MovementRex(),
130
         3
131
       ),
123 132
  ;
124 133

  
125 134
  public static final int NUM_OBJECTS = values().length;
......
501 510
      case 6: return new TwistyHelicopter(size, quat, texture, mesh, effects, moves, res, scrWidth);
502 511
      case 7: return new TwistySkewb     (size, quat, texture, mesh, effects, moves, res, scrWidth);
503 512
      case 8: return new TwistyIvy       (size, quat, texture, mesh, effects, moves, res, scrWidth);
513
      case 9: return new TwistyRex       (size, quat, texture, mesh, effects, moves, res, scrWidth);
504 514
      }
505 515

  
506 516
    return null;
src/main/java/org/distorted/objects/TwistyObject.java
78 78
  private static final float MAX_SIZE_CHANGE = 1.35f;
79 79
  private static final float MIN_SIZE_CHANGE = 0.8f;
80 80

  
81
  private static boolean mCreateFromDMesh = true;
81
  private static boolean mCreateFromDMesh = false;
82 82

  
83 83
  private static final Static3D CENTER = new Static3D(0,0,0);
84 84
  private static final int POST_ROTATION_MILLISEC = 500;
src/main/java/org/distorted/objects/TwistyRex.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
package org.distorted.objects;
21

  
22
import android.content.res.Resources;
23
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

  
26
import org.distorted.library.effect.MatrixEffectQuaternion;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshBase;
30
import org.distorted.library.mesh.MeshSquare;
31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33
import org.distorted.main.R;
34
import org.distorted.main.RubikSurfaceView;
35

  
36
import java.util.Random;
37

  
38
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
39

  
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

  
42
public class TwistyRex extends TwistyObject
43
{
44
  private static final int FACES_PER_CUBIT =4;
45

  
46
  // the four rotation axis of a RubikRex. Must be normalized.
47
  static final Static3D[] ROT_AXIS = new Static3D[]
48
         {
49
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
50
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
51
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
52
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
53
         };
54

  
55
  private static final int[] FACE_COLORS = new int[]
56
         {
57
           COLOR_YELLOW, COLOR_WHITE,
58
           COLOR_BLUE  , COLOR_GREEN,
59
           COLOR_RED   , COLOR_BROWN
60
         };
61

  
62
  // All legal rotation quats of a RubikRex
63
  private static final Static4D[] QUATS = new Static4D[]
64
         {
65
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
66
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
67
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
68
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
69

  
70
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
71
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
72
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
73
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
74
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
75
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
76
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
77
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
78
         };
79

  
80
  private static final int[][] mFaceMap =
81
         {
82
           {  0, 18,18,18 },
83
           {  0, 18,18,18 },
84
           {  0, 18,18,18 },
85
           {  0, 18,18,18 },
86
           {  1, 18,18,18 },
87
           {  1, 18,18,18 },
88
           {  1, 18,18,18 },
89
           {  1, 18,18,18 },
90
           {  2, 18,18,18 },
91
           {  2, 18,18,18 },
92
           {  2, 18,18,18 },
93
           {  2, 18,18,18 },
94
           {  3, 18,18,18 },
95
           {  3, 18,18,18 },
96
           {  3, 18,18,18 },
97
           {  3, 18,18,18 },
98
           {  4, 18,18,18 },
99
           {  4, 18,18,18 },
100
           {  4, 18,18,18 },
101
           {  4, 18,18,18 },
102
           {  5, 18,18,18 },
103
           {  5, 18,18,18 },
104
           {  5, 18,18,18 },
105
           {  5, 18,18,18 },
106

  
107
           {  6, 18,18,18 },
108
           {  7, 18,18,18 },
109
           {  8, 18,18,18 },
110
           {  9, 18,18,18 },
111
           { 10, 18,18,18 },
112
           { 11, 18,18,18 },
113

  
114
           {  4, 2, 18,18 },
115
           {  4, 0, 18,18 },
116
           {  4, 3, 18,18 },
117
           {  4, 1, 18,18 },
118
           {  0, 2, 18,18 },
119
           {  3, 0, 18,18 },
120
           {  1, 3, 18,18 },
121
           {  3, 2, 18,18 },
122
           {  5, 2, 18,18 },
123
           {  5, 0, 18,18 },
124
           {  5, 3, 18,18 },
125
           {  5, 1, 18,18 },
126
         };
127

  
128
  private static MeshBase mCornerMesh, mFaceMesh, mEdgeMesh;
129

  
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

  
132
  TwistyRex(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
133
            DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
134
    {
135
    super(size, size, 60, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth);
136
    }
137

  
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

  
140
  float getScreenRatio()
141
    {
142
    return 1.0f;
143
    }
144

  
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

  
147
  Static4D[] getQuats()
148
    {
149
    return QUATS;
150
    }
151

  
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

  
154
  int getNumFaces()
155
    {
156
    return FACE_COLORS.length;
157
    }
158

  
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

  
161
  boolean shouldResetTextureMaps()
162
    {
163
    return false;
164
    }
165

  
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

  
168
  int getNumStickerTypes()
169
    {
170
    return 3;
171
    }
172

  
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

  
175
  float[] getCuts(int numLayers)
176
    {
177
    float C = SQ3*0.15f;   // bit less than 1/6 of the length of the main diagonal
178

  
179
    return new float[] {-C,+C};
180
    }
181

  
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

  
184
  int getNumCubitFaces()
185
    {
186
    return FACES_PER_CUBIT;
187
    }
188

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

  
191
  Static3D[] getCubitPositions(int numLayers)
192
    {
193
    final float DIST = 0.50f;
194
    final float E    = SQ3/3;
195

  
196
    final Static3D[] CENTERS = new Static3D[42];
197

  
198
    CENTERS[ 0] = new Static3D( +DIST  , +DIST*E, +DIST*E);
199
    CENTERS[ 1] = new Static3D( +DIST  , +DIST*E, -DIST*E);
200
    CENTERS[ 2] = new Static3D( +DIST  , -DIST*E, -DIST*E);
201
    CENTERS[ 3] = new Static3D( +DIST  , -DIST*E, +DIST*E);
202
    CENTERS[ 4] = new Static3D( -DIST  , +DIST*E, +DIST*E);
203
    CENTERS[ 5] = new Static3D( -DIST  , +DIST*E, -DIST*E);
204
    CENTERS[ 6] = new Static3D( -DIST  , -DIST*E, -DIST*E);
205
    CENTERS[ 7] = new Static3D( -DIST  , -DIST*E, +DIST*E);
206
    CENTERS[ 8] = new Static3D( +DIST*E, +DIST  , +DIST*E);
207
    CENTERS[ 9] = new Static3D( +DIST*E, +DIST  , -DIST*E);
208
    CENTERS[10] = new Static3D( -DIST*E, +DIST  , -DIST*E);
209
    CENTERS[11] = new Static3D( -DIST*E, +DIST  , +DIST*E);
210
    CENTERS[12] = new Static3D( +DIST*E, -DIST  , +DIST*E);
211
    CENTERS[13] = new Static3D( +DIST*E, -DIST  , -DIST*E);
212
    CENTERS[14] = new Static3D( -DIST*E, -DIST  , -DIST*E);
213
    CENTERS[15] = new Static3D( -DIST*E, -DIST  , +DIST*E);
214
    CENTERS[16] = new Static3D( +DIST*E, +DIST*E, +DIST  );
215
    CENTERS[17] = new Static3D( +DIST*E, -DIST*E, +DIST  );
216
    CENTERS[18] = new Static3D( -DIST*E, -DIST*E, +DIST  );
217
    CENTERS[19] = new Static3D( -DIST*E, +DIST*E, +DIST  );
218
    CENTERS[20] = new Static3D( +DIST*E, +DIST*E, -DIST  );
219
    CENTERS[21] = new Static3D( +DIST*E, -DIST*E, -DIST  );
220
    CENTERS[22] = new Static3D( -DIST*E, -DIST*E, -DIST  );
221
    CENTERS[23] = new Static3D( -DIST*E, +DIST*E, -DIST  );
222

  
223
    CENTERS[24] = new Static3D( +DIST  , +0.00f , +0.00f );
224
    CENTERS[25] = new Static3D( -DIST  , +0.00f , +0.00f );
225
    CENTERS[26] = new Static3D( +0.00f , +DIST  , +0.00f );
226
    CENTERS[27] = new Static3D( +0.00f , -DIST  , +0.00f );
227
    CENTERS[28] = new Static3D( +0.00f , +0.00f , +DIST  );
228
    CENTERS[29] = new Static3D( +0.00f , +0.00f , -DIST  );
229

  
230
    CENTERS[30] = new Static3D( +0.00f , +DIST  , +DIST  );
231
    CENTERS[31] = new Static3D( +DIST  , +0.00f , +DIST  );
232
    CENTERS[32] = new Static3D( +0.00f , -DIST  , +DIST  );
233
    CENTERS[33] = new Static3D( -DIST  , +0.00f , +DIST  );
234
    CENTERS[34] = new Static3D( +DIST  , +DIST  , +0.00f );
235
    CENTERS[35] = new Static3D( +DIST  , -DIST  , +0.00f );
236
    CENTERS[36] = new Static3D( -DIST  , -DIST  , +0.00f );
237
    CENTERS[37] = new Static3D( -DIST  , +DIST  , +0.00f );
238
    CENTERS[38] = new Static3D( +0.00f , +DIST  , -DIST  );
239
    CENTERS[39] = new Static3D( +DIST  , +0.00f , -DIST  );
240
    CENTERS[40] = new Static3D( +0.00f , -DIST  , -DIST  );
241
    CENTERS[41] = new Static3D( -DIST  , +0.00f , -DIST  );
242

  
243
    return CENTERS;
244
    }
245

  
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247
// 1  +90 ( 1, 0, 0) = Static4D(+SQ2/2,     0,     0, SQ2/2);
248
// 2  -90 ( 1, 0, 0) = Static4D(-SQ2/2,     0,     0, SQ2/2);
249
// 3  +90 ( 0, 1, 0) = Static4D(     0,+SQ2/2,     0, SQ2/2);
250
// 4  -90 ( 0, 1, 0) = Static4D(     0,-SQ2/2,     0, SQ2/2);
251
// 5  +90 ( 0, 0, 1) = Static4D(     0,     0,+SQ2/2, SQ2/2);
252
// 6  -90 ( 0, 0, 1) = Static4D(     0,     0,-SQ2/2, SQ2/2);
253
// 7  180 ( 1, 0, 1) = Static4D(+SQ2/2,     0,+SQ2/2,     0);
254
// 8  180 (-1, 0, 1) = Static4D(-SQ2/2,     0,+SQ2/2,     0);
255
// 9  180 ( 0, 1, 1) = Static4D(     0,+SQ2/2,+SQ2/2,     0);
256
//10  180 ( 0,-1, 1) = Static4D(     0,-SQ2/2,+SQ2/2,     0);
257
//11  180 ( 1, 1, 0) = Static4D(+SQ2/2,+SQ2/2,     0,     0);
258
//12  180 ( 1,-1, 0) = Static4D(+SQ2/2,-SQ2/2,     0,     0);
259

  
260
  private Static4D getQuat(int cubit)
261
    {
262
    switch(cubit)
263
      {
264
      case  0: return QUATS[5];
265
      case  1: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
266
      case  2: return QUATS[8];
267
      case  3: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
268
      case  4: return QUATS[6];
269
      case  5: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
270
      case  6: return QUATS[11];
271
      case  7: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
272
      case  8: return QUATS[10];
273
      case  9: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
274
      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
275
      case 11: return QUATS[4];
276
      case 12: return QUATS[9];
277
      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
278
      case 14: return QUATS[7];
279
      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
280
      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
281
      case 17: return QUATS[0];
282
      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
283
      case 19: return QUATS[3];
284
      case 20: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
285
      case 21: return QUATS[2];
286
      case 22: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
287
      case 23: return QUATS[1];
288

  
289
      case 24: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
290
      case 25: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
291
      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
292
      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
293
      case 28: return QUATS[0];
294
      case 29: return QUATS[1];
295

  
296
      case 30: return QUATS[0];
297
      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
298
      case 32: return QUATS[3];
299
      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
300
      case 34: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
301
      case 35: return QUATS[7];
302
      case 36: return QUATS[9];
303
      case 37: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
304
      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
305
      case 39: return QUATS[8];
306
      case 40: return QUATS[1];
307
      case 41: return QUATS[6];
308
      }
309

  
310
    return QUATS[0];
311
    }
312

  
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

  
315
  MeshBase createCubitMesh(int cubit)
316
    {
317
    MeshBase mesh;
318

  
319
    if( cubit<12 )
320
      {
321
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createRexCornerMesh();
322
      mesh = mCornerMesh.copy(true);
323
      }
324
    else if( cubit<18 )
325
      {
326
      if( mFaceMesh==null ) mFaceMesh = FactoryCubit.getInstance().createRexFaceMesh();
327
      mesh = mFaceMesh.copy(true);
328
      }
329
    else
330
      {
331
      if( mEdgeMesh==null ) mEdgeMesh = FactoryCubit.getInstance().createRexEdgeMesh();
332
      mesh = mEdgeMesh.copy(true);
333
      }
334

  
335
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
336
    mesh.apply(quat,0xffffffff,0);
337

  
338
    return mesh;
339
    }
340

  
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

  
343
  int getFaceColor(int cubit, int cubitface, int numLayers)
344
    {
345
    return mFaceMap[cubit][cubitface];
346
    }
347

  
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349

  
350
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
351
    {
352
    int COLORS = FACE_COLORS.length;
353
    FactorySticker factory = FactorySticker.getInstance();
354
    float S = 0.08f;
355
    float R = 0.12f;
356

  
357
    if( face<COLORS )
358
      {
359
      factory.drawRexCornerSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
360
      }
361
    else if( face<2*COLORS )
362
      {
363
      factory.drawRexFaceSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
364
      }
365
    else
366
      {
367
      factory.drawRexEdgeSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
368
      }
369
    }
370

  
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

  
373
  float returnMultiplier()
374
    {
375
    return 2.0f;
376
    }
377

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

  
380
  float[] getRowChances()
381
    {
382
    return new float[] { 0.5f, 0.5f, 1.0f };
383
    }
384

  
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386
// PUBLIC API
387

  
388
  public Static3D[] getRotationAxis()
389
    {
390
    return ROT_AXIS;
391
    }
392

  
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394

  
395
  public int getBasicAngle()
396
    {
397
    return 3;
398
    }
399

  
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401

  
402
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
403
    {
404
    int numAxis = ROTATION_AXIS.length;
405

  
406
    if( oldRotAxis == START_AXIS )
407
      {
408
      return rnd.nextInt(numAxis);
409
      }
410
    else
411
      {
412
      int newVector = rnd.nextInt(numAxis-1);
413
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
414
      }
415
    }
416

  
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418

  
419
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
420
    {
421
    float rowFloat = rnd.nextFloat();
422

  
423
    for(int row=0; row<mRowChances.length; row++)
424
      {
425
      if( rowFloat<=mRowChances[row] ) return row;
426
      }
427

  
428
    return 0;
429
    }
430

  
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432
// remember about the double cover or unit quaternions!
433

  
434
  private int mulQuat(int q1, int q2)
435
    {
436
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
437

  
438
    float rX = result.get0();
439
    float rY = result.get1();
440
    float rZ = result.get2();
441
    float rW = result.get3();
442

  
443
    final float MAX_ERROR = 0.1f;
444
    float dX,dY,dZ,dW;
445

  
446
    for(int i=0; i<QUATS.length; i++)
447
      {
448
      dX = QUATS[i].get0() - rX;
449
      dY = QUATS[i].get1() - rY;
450
      dZ = QUATS[i].get2() - rZ;
451
      dW = QUATS[i].get3() - rW;
452

  
453
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
454
          dY<MAX_ERROR && dY>-MAX_ERROR &&
455
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
456
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
457

  
458
      dX = QUATS[i].get0() + rX;
459
      dY = QUATS[i].get1() + rY;
460
      dZ = QUATS[i].get2() + rZ;
461
      dW = QUATS[i].get3() + rW;
462

  
463
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
464
          dY<MAX_ERROR && dY>-MAX_ERROR &&
465
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
466
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
467
      }
468

  
469
    return -1;
470
    }
471

  
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473
// The Rex is solved if and only if:
474
//
475
// TODO
476

  
477
  public boolean isSolved()
478
    {
479
    int q = CUBITS[0].mQuatIndex;
480

  
481
    for(int i=1; i<42; i++)
482
      {
483
      if( CUBITS[i].mQuatIndex != q) return false;
484
      }
485

  
486
    return true;
487
    }
488

  
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490
// only needed for solvers - there are no Rex solvers ATM)
491

  
492
  public String retObjectString()
493
    {
494
    return "";
495
    }
496

  
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498

  
499
  public int getObjectName(int numLayers)
500
    {
501
    return R.string.rex3;
502
    }
503

  
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505

  
506
  public int getInventor(int numLayers)
507
    {
508
    return R.string.rex3_inventor;
509
    }
510

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

  
513
  public int getComplexity(int numLayers)
514
    {
515
    return 3;
516
    }
517
}
src/main/res/values/strings.xml
84 84
    <string name="redi2" translatable="false">Redi Cube</string>
85 85
    <string name="heli3" translatable="false">Helicopter Cube</string>
86 86
    <string name="ivy2"  translatable="false">Ivy Cube</string>
87
    <string name="rex3"  translatable="false">Rex Cube</string>
87 88
    <string name="dino3" translatable="false">Dino Cube (6 color)</string>
88 89
    <string name="din43" translatable="false">Dino Cube (4 color)</string>
89 90

  
......
100 101
    <string name="redi2_inventor" translatable="false">Oskar van Deventer, 2009</string>
101 102
    <string name="heli3_inventor" translatable="false">Adam G. Cowan, 2006</string>
102 103
    <string name="ivy2_inventor"  translatable="false">Eitan Cher, 2009</string>
104
    <string name="rex3_inventor"  translatable="false">Andrew Cormier, 2009</string>
103 105
    <string name="dino3_inventor" translatable="false">Robert Webb, 1985</string>
104 106
    <string name="din43_inventor" translatable="false">Robert Webb, 1985</string>
105 107

  

Also available in: Unified diff