Project

General

Profile

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

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

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
import org.distorted.main.RubikSurfaceView;
41

    
42
import java.util.Random;
43

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

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

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

    
53
  // the four rotation axis of a RubikDino. Must be normalized.
54
  static final Static3D[] ROT_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
  // the six axis that determine the faces
63
  static final Static3D[] FACE_AXIS = new Static3D[]
64
         {
65
           new Static3D(1,0,0), new Static3D(-1,0,0),
66
           new Static3D(0,1,0), new Static3D(0,-1,0),
67
           new Static3D(0,0,1), new Static3D(0,0,-1)
68
         };
69

    
70
  private static final int[] FACE_COLORS = new int[]
71
         {
72
           COLOR_YELLOW, COLOR_WHITE,
73
           COLOR_BLUE  , COLOR_GREEN,
74
           COLOR_RED   , COLOR_BROWN
75
         };
76

    
77
  // All legal rotation quats of a RubikDino
78
  static final Static4D[] QUATS = new Static4D[]
79
         {
80
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
81
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
82
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
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.5f, -0.5f, -0.5f,  0.5f ),
88
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
89
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
90
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
91
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f )
92
         };
93

    
94
  // centers of the 12 edges. Must be in the same order like QUATs above.
95
  private static final Static3D[] CENTERS = new Static3D[]
96
         {
97
           new Static3D( 0.0f, 1.5f, 1.5f ),
98
           new Static3D( 1.5f, 0.0f, 1.5f ),
99
           new Static3D( 0.0f,-1.5f, 1.5f ),
100
           new Static3D(-1.5f, 0.0f, 1.5f ),
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(-1.5f, 1.5f, 0.0f ),
105
           new Static3D( 0.0f, 1.5f,-1.5f ),
106
           new Static3D( 1.5f, 0.0f,-1.5f ),
107
           new Static3D( 0.0f,-1.5f,-1.5f ),
108
           new Static3D(-1.5f, 0.0f,-1.5f )
109
         };
110

    
111
  private static MeshBase mMesh;
112

    
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114

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

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

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

    
127
    final int MESHES=4;
128

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

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

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

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

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

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

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

    
160
    mMesh = new MeshJoined(meshes);
161

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

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

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

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

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

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

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

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

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

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

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

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

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

    
246
    mMesh.mergeEffComponents();
247
    }
248

    
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250

    
251
  int mulQuat(int q1, int q2)
252
    {
253
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
254

    
255
    float rX = result.get0();
256
    float rY = result.get1();
257
    float rZ = result.get2();
258
    float rW = result.get3();
259

    
260
    final float MAX_ERROR = 0.1f;
261
    float dX,dY,dZ,dW;
262

    
263
    for(int i=0; i<QUATS.length; i++)
264
      {
265
      dX = QUATS[i].get0() - rX;
266
      dY = QUATS[i].get1() - rY;
267
      dZ = QUATS[i].get2() - rZ;
268
      dW = QUATS[i].get3() - rW;
269

    
270
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
271
          dY<MAX_ERROR && dY>-MAX_ERROR &&
272
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
273
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
274

    
275
      dX = QUATS[i].get0() + rX;
276
      dY = QUATS[i].get1() + rY;
277
      dZ = QUATS[i].get2() + rZ;
278
      dW = QUATS[i].get3() + rW;
279

    
280
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
281
          dY<MAX_ERROR && dY>-MAX_ERROR &&
282
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
283
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
284
      }
285

    
286
    return -1;
287
    }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

    
291
  float getScreenRatio()
292
    {
293
    return 0.5f;
294
    }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

    
298
  Static4D[] getQuats()
299
    {
300
    return QUATS;
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

    
305
  int getNumFaces()
306
    {
307
    return FACE_COLORS.length;
308
    }
309

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

    
312
  float getBasicStep()
313
    {
314
    return SQ3;
315
    }
316

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

    
319
  int getNumStickerTypes()
320
    {
321
    return 1;
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
  int getNumCubitFaces()
327
    {
328
    return 4;
329
    }
330

    
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332

    
333
  Static3D[] getCubitPositions(int size)
334
    {
335
    return CENTERS;
336
    }
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

    
340
  MeshBase createCubitMesh(int cubit)
341
    {
342
    if( mMesh==null ) createBasicMesh();
343

    
344
    MeshBase mesh = mMesh.copy(true);
345
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[cubit], new Static3D(0,0,0) );
346
    mesh.apply(quat,0xffffffff,0);
347

    
348
    return mesh;
349
    }
350

    
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

    
353
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side)
354
    {
355
    float STROKE = 0.04f*side;
356
    float L= left;
357
    float H= 0.333f*side;
358
    float LEN = 0.5f*side;
359

    
360
    paint.setAntiAlias(true);
361
    paint.setStrokeWidth(STROKE);
362
    paint.setColor(FACE_COLORS[face]);
363
    paint.setStyle(Paint.Style.FILL);
364

    
365
    canvas.drawRect(left,top,left+side,top+side,paint);
366

    
367
    paint.setColor(INTERIOR_COLOR);
368
    paint.setStyle(Paint.Style.STROKE);
369

    
370
    canvas.drawLine( L      , H,  L+2*LEN, H    , paint);
371
    canvas.drawLine( L      , H,  L+  LEN, H+LEN, paint);
372
    canvas.drawLine( L+2*LEN, H,  L+  LEN, H+LEN, paint);
373

    
374
    float S1 = 0.150f*side;
375
    float S2 = 0.090f*side;
376
    float X  = 0.7f*S2;
377
    float Y  = 0.2f*S1;
378

    
379
    float LA = left+0.500f*side;
380
    float RA = left;
381
    float TA = 0.333f*side;
382
    float BA = 0.833f*side;
383

    
384
    canvas.drawArc( RA+X        , TA     , RA+X+S2  , TA+S2, 135,135, false, paint);
385
    canvas.drawArc( RA+side-S2-X, TA     , RA+side-X, TA+S2, 270,135, false, paint);
386
    canvas.drawArc( LA-S1/2     , BA-S1-Y, LA+S1/2  , BA-Y ,  45, 90, false, paint);
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  float returnMultiplier()
392
    {
393
    return 2.0f;
394
    }
395

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

    
398
  float[] getRowChances()
399
    {
400
    float[] chances = new float[3];
401

    
402
    chances[0] = 0.5f;
403
    chances[1] = 0.5f;
404
    chances[2] = 1.0f;
405

    
406
    return chances;
407
    }
408

    
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410
// PUBLIC API
411

    
412
  public Static3D[] getRotationAxis()
413
    {
414
    return ROT_AXIS;
415
    }
416

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

    
419
  public int getBasicAngle()
420
    {
421
    return 3;
422
    }
423

    
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425

    
426
  public int computeRowFromOffset(float offset)
427
    {
428
    return offset<0.5f ? 0:2;
429
    }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

    
433
  public float returnRotationFactor(float offset)
434
    {
435
    return 1.0f;
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
441
    {
442
    int numAxis = ROTATION_AXIS.length;
443

    
444
    if( oldRotAxis == START_AXIS )
445
      {
446
      return rnd.nextInt(numAxis);
447
      }
448
    else
449
      {
450
      int newVector = rnd.nextInt(numAxis-1);
451
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
452
      }
453
    }
454

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

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

    
463
}
(4-4/18)