Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikDino.java @ eaee1ddc

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.effect.VertexEffectDeform;
28
import org.distorted.library.effect.VertexEffectMove;
29
import org.distorted.library.effect.VertexEffectRotate;
30
import org.distorted.library.effect.VertexEffectScale;
31
import org.distorted.library.main.DistortedEffects;
32
import org.distorted.library.main.DistortedTexture;
33
import org.distorted.library.mesh.MeshBase;
34
import org.distorted.library.mesh.MeshJoined;
35
import org.distorted.library.mesh.MeshPolygon;
36
import org.distorted.library.mesh.MeshSquare;
37
import org.distorted.library.type.Static1D;
38
import org.distorted.library.type.Static3D;
39
import org.distorted.library.type.Static4D;
40

    
41
import java.util.Random;
42

    
43
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
44

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

    
47
public abstract class RubikDino extends RubikObject
48
{
49
  private static final float SQ2 = (float)Math.sqrt(2);
50
  private static final float SQ3 = (float)Math.sqrt(3);
51

    
52
  // the four rotation axis of a RubikDino. Must be normalized.
53
  static final Static3D[] ROT_AXIS = new Static3D[]
54
         {
55
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
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
         };
60

    
61
  // the six axis that determine the faces
62
  static final Static3D[] FACE_AXIS = new Static3D[]
63
         {
64
           new Static3D(1,0,0), new Static3D(-1,0,0),
65
           new Static3D(0,1,0), new Static3D(0,-1,0),
66
           new Static3D(0,0,1), new Static3D(0,0,-1)
67
         };
68

    
69
  private static final int[] FACE_COLORS = new int[]
70
         {
71
           0xffffff00, 0xffffffff,   // FACE_AXIS[0] (right-YELLOW) FACE_AXIS[1] (left  -WHITE)
72
           0xff0000ff, 0xff00ff00,   // FACE_AXIS[2] (top  -BLUE  ) FACE_AXIS[3] (bottom-GREEN)
73
           0xffff0000, 0xffb5651d    // FACE_AXIS[4] (front-RED   ) FACE_AXIS[5] (back  -BROWN)
74
         };
75

    
76
  // All legal rotation quats of a RubikDino
77
  static final Static4D[] QUATS = new Static4D[]
78
         {
79
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
80
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
81
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
82
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f ),
83
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
84
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
85
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
86
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
87
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
88
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
89
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
90
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f )
91
         };
92

    
93
  // centers of the 12 edges. Must be in the same order like QUATs above.
94
  private static final Static3D[] CENTERS = new Static3D[]
95
         {
96
           new Static3D( 0.0f, 1.5f, 1.5f ),
97
           new Static3D( 1.5f, 0.0f, 1.5f ),
98
           new Static3D( 0.0f,-1.5f, 1.5f ),
99
           new Static3D(-1.5f, 0.0f, 1.5f ),
100
           new Static3D( 1.5f, 1.5f, 0.0f ),
101
           new Static3D( 1.5f,-1.5f, 0.0f ),
102
           new Static3D(-1.5f,-1.5f, 0.0f ),
103
           new Static3D(-1.5f, 1.5f, 0.0f ),
104
           new Static3D( 0.0f, 1.5f,-1.5f ),
105
           new Static3D( 1.5f, 0.0f,-1.5f ),
106
           new Static3D( 0.0f,-1.5f,-1.5f ),
107
           new Static3D(-1.5f, 0.0f,-1.5f )
108
         };
109

    
110
  private static MeshBase mMesh;
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

    
114
  RubikDino(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
115
            DistortedEffects effects, int[][] moves, RubikObjectList obj, Resources res, int scrWidth)
116
    {
117
    super(size, 60, quat, texture, mesh, effects, moves, obj, res, scrWidth);
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
  private void createBasicMesh()
123
    {
124
    final float ANGLE = (float)((180/Math.PI)*(Math.atan(SQ2)));
125

    
126
    final int MESHES=4;
127

    
128
    float D = 0.02f;
129
    float E = 0.5f*SQ2;
130
    float F = 0.5f;
131

    
132
    float[] bands0 = { 1.0f    , 0,
133
                       1.0f-2*D, D*0.25f,
134
                       1.0f-4*D, D*0.35f,
135
                       1.0f-8*D, D*0.6f,
136
                       0.60f   , D*1.0f,
137
                       0.30f   , D*1.375f,
138
                       0.0f    , D*1.4f };
139

    
140
    float[] vertices0 = { -F,F/3, 0,-2*F/3, +F,F/3 };
141

    
142
    MeshBase[] meshes = new MeshPolygon[MESHES];
143
    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 5);
144
    meshes[0].setEffectAssociation(0,1,0);
145
    meshes[1] = meshes[0].copy(true);
146
    meshes[1].setEffectAssociation(0,2,0);
147

    
148
    float[] bands1 = { 1.0f    , 0,
149
                       0.50f   , 0.10f,
150
                       0.0f    , 0.20f };
151

    
152
    float[] vertices1 = { -E/2,-E*(SQ3/6), E/2,-E*(SQ3/6), 0,E*(SQ3/3) };
153

    
154
    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
155
    meshes[2].setEffectAssociation(0,4,0);
156
    meshes[3] = meshes[2].copy(true);
157
    meshes[3].setEffectAssociation(0,8,0);
158

    
159
    mMesh = new MeshJoined(meshes);
160

    
161
    Static3D a0 = new Static3D(     0,-3*F,    0 );
162
    Static3D a1 = new Static3D(     0,   0, -3*F );
163
    Static3D a2 = new Static3D(  -3*F,   0,    0 );
164
    Static3D a3 = new Static3D(  +3*F,   0,    0 );
165

    
166
    Static3D v0 = new Static3D(     0,-3*F/2, 3*F/2 );
167
    Static3D v1 = new Static3D(     0, 3*F/2,-3*F/2 );
168
    Static3D v2 = new Static3D(  -3*F, 3*F/2, 3*F/2 );
169
    Static3D v3 = new Static3D(  +3*F, 3*F/2, 3*F/2 );
170

    
171
    float d1 = 1.0f;
172
    float d2 =-0.10f;
173
    float d3 =-0.10f;
174
    float d4 = 0.40f;
175

    
176
    Static3D dCen0 = new Static3D( d1*a0.get0(), d1*a0.get1(), d1*a0.get2() );
177
    Static3D dCen1 = new Static3D( d1*a1.get0(), d1*a1.get1(), d1*a1.get2() );
178
    Static3D dCen2 = new Static3D( d1*a2.get0(), d1*a2.get1(), d1*a2.get2() );
179
    Static3D dCen3 = new Static3D( d1*a3.get0(), d1*a3.get1(), d1*a3.get2() );
180

    
181
    Static3D dVec0 = new Static3D( d3*v0.get0(), d3*v0.get1(), d3*v0.get2() );
182
    Static3D dVec1 = new Static3D( d3*v1.get0(), d3*v1.get1(), d3*v1.get2() );
183
    Static3D dVec2 = new Static3D( d2*v2.get0(), d2*v2.get1(), d2*v2.get2() );
184
    Static3D dVec3 = new Static3D( d2*v3.get0(), d2*v3.get1(), d2*v3.get2() );
185

    
186
    Static4D dReg  = new Static4D(0,0,0,d4);
187
    Static1D dRad  = new Static1D(1);
188

    
189
    Static1D angle1 = new Static1D(+ANGLE);
190
    Static1D angle2 = new Static1D(-ANGLE);
191

    
192
    Static3D axisX  = new Static3D(1,0,0);
193
    Static3D axisY  = new Static3D(0,1,0);
194
    Static3D axisZ  = new Static3D(0,-1,1);
195

    
196
    Static3D center0= new Static3D(0,0,0);
197
    Static3D center1= new Static3D(0,-3*F,0);
198

    
199
    VertexEffectScale   effect0 = new VertexEffectScale ( new Static3D(3,3,3) );
200
    VertexEffectMove    effect1 = new VertexEffectMove  ( new Static3D(0,-F,0) );
201
    VertexEffectRotate  effect2 = new VertexEffectRotate( new Static1D(90), axisX, center0 );
202
    VertexEffectScale   effect3 = new VertexEffectScale ( new Static3D(1,-1,1) );
203
    VertexEffectMove    effect4 = new VertexEffectMove  ( new Static3D(3*E/2,E*(SQ3/2)-3*F,0) );
204
    VertexEffectRotate  effect5 = new VertexEffectRotate( new Static1D(+90), axisY, center1 );
205
    VertexEffectScale   effect6 = new VertexEffectScale ( new Static3D(-1,1,1) );
206
    VertexEffectRotate  effect7 = new VertexEffectRotate( new Static1D( 45), axisX, center1 );
207
    VertexEffectRotate  effect8 = new VertexEffectRotate( angle1           , axisZ, center1 );
208
    VertexEffectRotate  effect9 = new VertexEffectRotate( angle2           , axisZ, center1 );
209

    
210
    VertexEffectDeform  effect10= new VertexEffectDeform(dVec0, dRad, dCen0, dReg);
211
    VertexEffectDeform  effect11= new VertexEffectDeform(dVec1, dRad, dCen1, dReg);
212
    VertexEffectDeform  effect12= new VertexEffectDeform(dVec2, dRad, dCen2, dReg);
213
    VertexEffectDeform  effect13= new VertexEffectDeform(dVec3, dRad, dCen3, dReg);
214

    
215
    effect0.setMeshAssociation(15,-1);  // apply to meshes 0,1,2,3
216
    effect1.setMeshAssociation( 3,-1);  // apply to meshes 0,1
217
    effect2.setMeshAssociation( 2,-1);  // apply to mesh 1
218
    effect3.setMeshAssociation( 2,-1);  // apply to mesh 0
219
    effect4.setMeshAssociation(12,-1);  // apply to meshes 2,3
220
    effect5.setMeshAssociation(12,-1);  // apply to meshes 2,3
221
    effect6.setMeshAssociation( 8,-1);  // apply to mesh 3
222
    effect7.setMeshAssociation(12,-1);  // apply to meshes 2,3
223
    effect8.setMeshAssociation( 4,-1);  // apply to mesh 2
224
    effect9.setMeshAssociation( 8,-1);  // apply to mesh 3
225
    effect10.setMeshAssociation(15,-1); // apply to meshes 0,1,2,3
226
    effect11.setMeshAssociation(15,-1); // apply to meshes 0,1,2,3
227
    effect12.setMeshAssociation(15,-1); // apply to meshes 0,1,2,3
228
    effect13.setMeshAssociation(15,-1); // apply to meshes 0,1,2,3
229

    
230
    mMesh.apply(effect0);
231
    mMesh.apply(effect1);
232
    mMesh.apply(effect2);
233
    mMesh.apply(effect3);
234
    mMesh.apply(effect4);
235
    mMesh.apply(effect5);
236
    mMesh.apply(effect6);
237
    mMesh.apply(effect7);
238
    mMesh.apply(effect8);
239
    mMesh.apply(effect9);
240
    mMesh.apply(effect10);
241
    mMesh.apply(effect11);
242
    mMesh.apply(effect12);
243
    mMesh.apply(effect13);
244

    
245
    mMesh.mergeEffComponents();
246
    }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

    
250
  float getScreenRatio()
251
    {
252
    return 0.5f;
253
    }
254

    
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256

    
257
  Static4D[] getQuats()
258
    {
259
    return QUATS;
260
    }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263

    
264
  int getNumFaces()
265
    {
266
    return FACE_COLORS.length;
267
    }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

    
271
  float getBasicStep()
272
    {
273
    return SQ3;
274
    }
275

    
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277

    
278
  int getNumStickerTypes()
279
    {
280
    return 1;
281
    }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

    
285
  int getNumCubitFaces()
286
    {
287
    return 4;
288
    }
289

    
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

    
292
  Static3D[] getCubitPositions(int size)
293
    {
294
    return CENTERS;
295
    }
296

    
297
///////////////////////////////////////////////////////////////////////////////////////////////////
298

    
299
  MeshBase createCubitMesh(int cubit)
300
    {
301
    if( mMesh==null ) createBasicMesh();
302

    
303
    MeshBase mesh = mMesh.copy(true);
304
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[cubit], new Static3D(0,0,0) );
305
    mesh.apply(quat,0xffffffff,0);
306

    
307
    return mesh;
308
    }
309

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

    
312
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side)
313
    {
314
    float STROKE = 0.04f*side;
315
    float L= left;
316
    float H= 0.333f*side;
317
    float LEN = 0.5f*side;
318

    
319
    paint.setAntiAlias(true);
320
    paint.setStrokeWidth(STROKE);
321
    paint.setColor(FACE_COLORS[face]);
322
    paint.setStyle(Paint.Style.FILL);
323

    
324
    canvas.drawRect(left,top,left+side,top+side,paint);
325

    
326
    paint.setColor(INTERIOR_COLOR);
327
    paint.setStyle(Paint.Style.STROKE);
328

    
329
    canvas.drawLine( L      , H,  L+2*LEN, H    , paint);
330
    canvas.drawLine( L      , H,  L+  LEN, H+LEN, paint);
331
    canvas.drawLine( L+2*LEN, H,  L+  LEN, H+LEN, paint);
332

    
333
    float S1 = 0.150f*side;
334
    float S2 = 0.090f*side;
335
    float X  = 0.7f*S2;
336
    float Y  = 0.2f*S1;
337

    
338
    float LA = left+0.500f*side;
339
    float RA = left;
340
    float TA = 0.333f*side;
341
    float BA = 0.833f*side;
342

    
343
    canvas.drawArc( RA+X        , TA     , RA+X+S2  , TA+S2, 135,135, false, paint);
344
    canvas.drawArc( RA+side-S2-X, TA     , RA+side-X, TA+S2, 270,135, false, paint);
345
    canvas.drawArc( LA-S1/2     , BA-S1-Y, LA+S1/2  , BA-Y ,  45, 90, false, paint);
346
    }
347

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

    
350
  float returnMultiplier()
351
    {
352
    return 2.0f;
353
    }
354

    
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356

    
357
  float[] getRowChances()
358
    {
359
    float[] chances = new float[3];
360

    
361
    chances[0] = 0.5f;
362
    chances[1] = 0.5f;
363
    chances[2] = 1.0f;
364

    
365
    return chances;
366
    }
367

    
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369
// PUBLIC API
370

    
371
  public Static3D[] getRotationAxis()
372
    {
373
    return ROT_AXIS;
374
    }
375

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

    
378
  public int getBasicAngle()
379
    {
380
    return 3;
381
    }
382

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

    
385
  public int computeRowFromOffset(float offset)
386
    {
387
    return offset<0.5f ? 0:2;
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

    
392
  public float returnRotationFactor(float offset)
393
    {
394
    return 1.0f;
395
    }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

    
399
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
400
    {
401
    int numAxis = ROTATION_AXIS.length;
402

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

    
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415

    
416
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
417
    {
418
    float rowFloat = rnd.nextFloat();
419

    
420
    switch(oldRotAxis)
421
      {
422
      case 0 : switch(newRotAxis)
423
                 {
424
                 case 1:
425
                 case 2: return oldRow;
426
                 case 3: return 2-oldRow;
427
                 default: android.util.Log.e("dino", "error: oldRotAxis="+oldRotAxis+" newRotAxis:"+newRotAxis);
428
                 }
429
      case 1 : switch(newRotAxis)
430
                 {
431
                 case 0:
432
                 case 3: return oldRow;
433
                 case 2: return 2-oldRow;
434
                 default: android.util.Log.e("dino", "error: oldRotAxis="+oldRotAxis+" newRotAxis:"+newRotAxis);
435
                 }
436
      case 2 : switch(newRotAxis)
437
                 {
438
                 case 0:
439
                 case 3: return oldRow;
440
                 case 1: return 2-oldRow;
441
                 default: android.util.Log.e("dino", "error: oldRotAxis="+oldRotAxis+" newRotAxis:"+newRotAxis);
442
                 }
443
      case 3 : switch(newRotAxis)
444
                 {
445
                 case 1:
446
                 case 2: return oldRow;
447
                 case 0: return 2-oldRow;
448
                 default: android.util.Log.e("dino", "error: oldRotAxis="+oldRotAxis+" newRotAxis:"+newRotAxis);
449
                 }
450
      default: return rowFloat<=0.5f ? 0:2;
451
      }
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455
// only needed for solvers - there are no Dino solvers ATM)
456

    
457
  public String retObjectString()
458
    {
459
    return "";
460
    }
461

    
462
}
(3-3/16)