Project

General

Profile

Download (14 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / RubikDino.java @ 8f53e513

1 418aa554 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 8f53e513 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectMove;
27
import org.distorted.library.effect.MatrixEffectQuaternion;
28
import org.distorted.library.effect.MatrixEffectRotate;
29
import org.distorted.library.effect.MatrixEffectScale;
30
import org.distorted.library.effect.VertexEffectDeform;
31
import org.distorted.library.effect.VertexEffectMove;
32
import org.distorted.library.effect.VertexEffectRotate;
33
import org.distorted.library.effect.VertexEffectScale;
34
import org.distorted.library.effect.VertexEffectSink;
35 418aa554 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
36
import org.distorted.library.main.DistortedTexture;
37
import org.distorted.library.mesh.MeshBase;
38 8f53e513 Leszek Koltunski
import org.distorted.library.mesh.MeshJoined;
39 418aa554 Leszek Koltunski
import org.distorted.library.mesh.MeshRectangles;
40 8f53e513 Leszek Koltunski
import org.distorted.library.mesh.MeshTriangles;
41
import org.distorted.library.type.Static1D;
42 418aa554 Leszek Koltunski
import org.distorted.library.type.Static3D;
43
import org.distorted.library.type.Static4D;
44
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46
47
public class RubikDino extends RubikObject
48
{
49 8f53e513 Leszek Koltunski
  private static final float SQ2 = (float)Math.sqrt(2);
50
  private static final float SQ3 = (float)Math.sqrt(3);
51
  private static final float ANGLE_FACES = (float)((180/Math.PI)*(2*Math.asin(SQ3/3))); // angle between two faces of a tetrahedron
52 418aa554 Leszek Koltunski
53
  // the four rotation axis of a RubikDino. Must be normalized.
54
  static final Static3D[] AXIS = new Static3D[]
55
         {
56
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
57
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
58
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
59
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
60
         };
61
62
  private static final int[] FACE_COLORS = new int[]
63
         {
64 8f53e513 Leszek Koltunski
           0xffffff00, 0xffffffff,   // (right-YELLOW) (left  -WHITE)
65
           0xff0000ff, 0xff00ff00,   // (top  -BLUE  ) (bottom-GREEN)
66
           0xffff0000, 0xffb5651d    // (front-RED   ) (back  -BROWN)
67 418aa554 Leszek Koltunski
         };
68
69
  // All legal rotation quats of a RubikDino
70
  private static final Static4D[] QUATS = new Static4D[]
71
         {
72
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
73 8f53e513 Leszek Koltunski
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
74
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
75
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
76 418aa554 Leszek Koltunski
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
77
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
78 8f53e513 Leszek Koltunski
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
79 418aa554 Leszek Koltunski
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
80 8f53e513 Leszek Koltunski
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
81 418aa554 Leszek Koltunski
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
82 8f53e513 Leszek Koltunski
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
83
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
84
         };
85
86
  // centers of the 12 edges. Must be in the same order like QUATs above.
87
  private static final Static3D[] CENTERS = new Static3D[]
88
         {
89
           new Static3D( 0.0f, 0.5f, 0.5f ),
90
           new Static3D( 0.0f,-0.5f, 0.5f ),
91
           new Static3D( 0.0f, 0.5f,-0.5f ),
92
           new Static3D( 0.0f,-0.5f,-0.5f ),
93
           new Static3D( 0.5f, 0.5f, 0.0f ),
94
           new Static3D( 0.5f, 0.0f, 0.5f ),
95
           new Static3D(-0.5f, 0.0f,-0.5f ),
96
           new Static3D( 0.5f,-0.5f, 0.0f ),
97
           new Static3D( 0.5f, 0.0f,-0.5f ),
98
           new Static3D(-0.5f,-0.5f, 0.0f ),
99
           new Static3D(-0.5f, 0.5f, 0.0f ),
100
           new Static3D(-0.5f, 0.0f, 0.5f )
101 418aa554 Leszek Koltunski
         };
102
103 8f53e513 Leszek Koltunski
  private static MeshBase mMesh;
104 418aa554 Leszek Koltunski
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106
107
  RubikDino(int size, Static4D quat, DistortedTexture texture,
108
            MeshRectangles mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
109
    {
110
    super(size, 60, quat, texture, mesh, effects, moves, RubikObjectList.DINO, res, scrWidth);
111
    }
112
113 8f53e513 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
114
115
  private MeshBase createTetrahedronMesh()
116
    {
117
    final float SQ2 = (float)Math.sqrt(2);
118
    final float SQ3 = (float)Math.sqrt(3);
119
    final int MESHES=4;
120
121
    int association = 1;
122
    MeshBase[] meshes = new MeshTriangles[MESHES];
123
124
    meshes[0] = new MeshTriangles(9);
125
    meshes[0].setEffectAssociation(0,association,0);
126
127
    for(int i=1; i<MESHES; i++)
128
      {
129
      association <<= 1;
130
      meshes[i] = meshes[0].copy(true);
131
      meshes[i].setEffectAssociation(0,association,0);
132
      }
133
134
    MeshBase result = new MeshJoined(meshes);
135
136
    Static3D a0 = new Static3D(         0,        1,       0 );
137
    Static3D a1 = new Static3D(         0,  -1.0f/3, 2*SQ2/3 );
138
    Static3D a2 = new Static3D(-SQ2*SQ3/3,  -1.0f/3,  -SQ2/3 );
139
    Static3D a3 = new Static3D( SQ2*SQ3/3,  -1.0f/3,  -SQ2/3 );
140
141
    float tetraHeight = SQ2*SQ3/3;
142
    float d1 = 0.75f*tetraHeight;
143
    float d2 =-0.10f*tetraHeight;
144
    float d3 = 0.20f*tetraHeight;
145
146
    Static3D dCen0 = new Static3D( d1*a0.get0(), d1*a0.get1(), d1*a0.get2() );
147
    Static3D dCen1 = new Static3D( d1*a1.get0(), d1*a1.get1(), d1*a1.get2() );
148
    Static3D dCen2 = new Static3D( d1*a2.get0(), d1*a2.get1(), d1*a2.get2() );
149
    Static3D dCen3 = new Static3D( d1*a3.get0(), d1*a3.get1(), d1*a3.get2() );
150
151
    Static3D dVec0 = new Static3D( d2*a0.get0(), d2*a0.get1(), d2*a0.get2() );
152
    Static3D dVec1 = new Static3D( d2*a1.get0(), d2*a1.get1(), d2*a1.get2() );
153
    Static3D dVec2 = new Static3D( d2*a2.get0(), d2*a2.get1(), d2*a2.get2() );
154
    Static3D dVec3 = new Static3D( d2*a3.get0(), d2*a3.get1(), d2*a3.get2() );
155
156
    Static4D dReg  = new Static4D(0,0,0,d3);
157
    Static1D dRad  = new Static1D(1);
158
159
    Static1D angle  = new Static1D(ANGLE_FACES);
160
    Static3D axis1  = new Static3D(  -1, 0,      0);
161
    Static3D axis2  = new Static3D(0.5f, 0, -SQ3/2);
162
    Static3D axis3  = new Static3D(0.5f, 0, +SQ3/2);
163
    Static3D center1= new Static3D(0,-SQ3*SQ2/12,-SQ3/6);
164
    Static3D center2= new Static3D(0,-SQ3*SQ2/12,+SQ3/3);
165
166
    Static3D center = new Static3D(0,0,0);
167
    Static4D region = new Static4D(0,0,0,0.6f);
168
169
    VertexEffectScale   effect1 = new VertexEffectScale ( new Static3D(1,SQ3/2,1) );
170
    VertexEffectRotate  effect2 = new VertexEffectRotate( new Static1D(90), new Static3D(1,0,0), new Static3D(0,0,0) );
171
    VertexEffectMove    effect3 = new VertexEffectMove  ( new Static3D(0,-SQ3*SQ2/12,SQ3/12) );
172
    VertexEffectRotate  effect4 = new VertexEffectRotate( new Static1D(180), new Static3D(0,0,1), center1 );
173
    VertexEffectRotate  effect5 = new VertexEffectRotate( angle, axis1, center1 );
174
    VertexEffectRotate  effect6 = new VertexEffectRotate( angle, axis2, center2 );
175
    VertexEffectRotate  effect7 = new VertexEffectRotate( angle, axis3, center2 );
176
177
    VertexEffectDeform  effect8 = new VertexEffectDeform(dVec0, dRad, dCen0, dReg);
178
    VertexEffectDeform  effect9 = new VertexEffectDeform(dVec1, dRad, dCen1, dReg);
179
    VertexEffectDeform  effect10= new VertexEffectDeform(dVec2, dRad, dCen2, dReg);
180
    VertexEffectDeform  effect11= new VertexEffectDeform(dVec3, dRad, dCen3, dReg);
181
182
    VertexEffectSink effect12= new VertexEffectSink( new Static1D(1.3f), center, region );
183
184
    effect4.setMeshAssociation(14,-1);  // apply to mesh[1], [2] and [3]
185
    effect5.setMeshAssociation( 2,-1);  // apply only to mesh[1]
186
    effect6.setMeshAssociation( 4,-1);  // apply only to mesh[2]
187
    effect7.setMeshAssociation( 8,-1);  // apply only to mesh[3]
188
189
    result.apply(effect1);
190
    result.apply(effect2);
191
    result.apply(effect3);
192
    result.apply(effect4);
193
    result.apply(effect5);
194
    result.apply(effect6);
195
    result.apply(effect7);
196
    result.apply(effect8);
197
    result.apply(effect9);
198
    result.apply(effect10);
199
    result.apply(effect11);
200
    result.apply(effect12);
201
202
    result.mergeEffComponents();
203
204
    return result;
205
    }
206
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208
209
  private void createBasicMesh()
210
    {
211
    mMesh = createTetrahedronMesh();
212
213
    Static3D axis = new Static3D(1,0,0);
214
    Static3D cent = new Static3D(0,0,0);
215
216
    MatrixEffectMove   moveEffect = new MatrixEffectMove  ( new Static3D(0.0f,SQ3*SQ2/12,SQ3/6) );
217
    MatrixEffectRotate rot1Effect = new MatrixEffectRotate( new Static1D(180+ANGLE_FACES/2), axis, cent);
218
    MatrixEffectScale  scalEffect = new MatrixEffectScale ( new Static3D(1.0f, SQ2/2, SQ2*SQ3/6) );
219
    MatrixEffectRotate rot2Effect = new MatrixEffectRotate( new Static1D(-45), axis, cent);
220
221
    mMesh.apply(moveEffect,0xffffffff,0);
222
    mMesh.apply(rot1Effect,0xffffffff,0);
223
    mMesh.apply(scalEffect,0xffffffff,0);
224
    mMesh.apply(rot2Effect,0xffffffff,0);
225
    }
226
227 418aa554 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
228
229
  float getScreenRatio()
230
    {
231 8f53e513 Leszek Koltunski
    return 1.0f;
232 418aa554 Leszek Koltunski
    }
233
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235
236
  Static4D[] getQuats()
237
    {
238
    return QUATS;
239
    }
240
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242
243
  int getNumFaces()
244
    {
245
    return FACE_COLORS.length;
246
    }
247
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249
250 8f53e513 Leszek Koltunski
  int getNumCubitFaces()
251 418aa554 Leszek Koltunski
    {
252 8f53e513 Leszek Koltunski
    return 4;
253
    }
254
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256 418aa554 Leszek Koltunski
257 8f53e513 Leszek Koltunski
  Static3D[] getCubitPositions(int size)
258
    {
259
    return CENTERS;
260 418aa554 Leszek Koltunski
    }
261
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263
264
  MeshBase createCubitMesh(int cubit)
265
    {
266 8f53e513 Leszek Koltunski
    if( mMesh==null ) createBasicMesh();
267
268
    MeshBase mesh = mMesh.copy(true);
269
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[cubit], new Static3D(0,0,0) );
270
    mesh.apply(quat,0xffffffff,0);
271 418aa554 Leszek Koltunski
272 8f53e513 Leszek Koltunski
    return mesh;
273 418aa554 Leszek Koltunski
    }
274
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
277
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side)
278
    {
279
    float STROKE = 0.06f*side;
280
    float OFF = STROKE/2 -1;
281
    float OFF2 = 0.5f*side + OFF;
282
    float HEIGHT = side - OFF;
283
    float RADIUS = side/12.0f;
284
    float ARC1_H = 0.2f*side;
285
    float ARC1_W = side*0.5f;
286
    float ARC2_W = 0.153f*side;
287
    float ARC2_H = 0.905f*side;
288
    float ARC3_W = side-ARC2_W;
289
290
    paint.setAntiAlias(true);
291
    paint.setStrokeWidth(STROKE);
292
    paint.setColor(FACE_COLORS[face]);
293
    paint.setStyle(Paint.Style.FILL);
294
295
    canvas.drawRect(left,top,left+side,top+side,paint);
296
297
    paint.setColor(INTERIOR_COLOR);
298
    paint.setStyle(Paint.Style.STROKE);
299
300
    canvas.drawLine(           left, HEIGHT,  side       +left, HEIGHT, paint);
301
    canvas.drawLine(      OFF +left, side  ,       OFF2  +left,      0, paint);
302
    canvas.drawLine((side-OFF)+left, side  , (side-OFF2) +left,      0, paint);
303
304
    canvas.drawArc( ARC1_W-RADIUS+left, ARC1_H-RADIUS, ARC1_W+RADIUS+left, ARC1_H+RADIUS, 225, 90, false, paint);
305
    canvas.drawArc( ARC2_W-RADIUS+left, ARC2_H-RADIUS, ARC2_W+RADIUS+left, ARC2_H+RADIUS, 105, 90, false, paint);
306
    canvas.drawArc( ARC3_W-RADIUS+left, ARC2_H-RADIUS, ARC3_W+RADIUS+left, ARC2_H+RADIUS, 345, 90, false, paint);
307
    }
308
309
///////////////////////////////////////////////////////////////////////////////////////////////////
310
// PUBLIC API
311
312
  public Static3D[] getRotationAxis()
313
    {
314
    return AXIS;
315
    }
316
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318
319
  public int getBasicAngle()
320
    {
321
    return 3;
322
    }
323
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325
326
  public float returnMultiplier()
327
    {
328
    // TODO
329
330
    return 0;
331
    }
332
333
///////////////////////////////////////////////////////////////////////////////////////////////////
334
335
  public float returnRotationFactor(float offset)
336
    {
337
    return 1.0f;
338
    }
339
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341
342
  public float[] getRowChances()
343
    {
344
    int size = getSize();
345
    float[] chances = new float[size];
346
347
    for(int i=0; i<size; i++)
348
      {
349
      chances[i] = (i+1.0f) / size;
350
      }
351
352
    return chances;
353
    }
354
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356
// TODO  (only needed for solvers - there are no Dino solvers ATM)
357
358
  public String retObjectString()
359
    {
360
    return "";
361
    }
362
363
}