Project

General

Profile

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

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

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.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
import org.distorted.library.main.DistortedEffects;
36
import org.distorted.library.main.DistortedTexture;
37
import org.distorted.library.mesh.MeshBase;
38
import org.distorted.library.mesh.MeshJoined;
39
import org.distorted.library.mesh.MeshRectangles;
40
import org.distorted.library.mesh.MeshTriangles;
41
import org.distorted.library.type.Static1D;
42
import org.distorted.library.type.Static3D;
43
import org.distorted.library.type.Static4D;
44

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

    
47
public 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
  private static final float ANGLE_FACES = (float)((180/Math.PI)*(2*Math.asin(SQ3/3))); // angle between two faces of a tetrahedron
52

    
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
           0xffffff00, 0xffffffff,   // (right-YELLOW) (left  -WHITE)
65
           0xff0000ff, 0xff00ff00,   // (top  -BLUE  ) (bottom-GREEN)
66
           0xffff0000, 0xffb5651d    // (front-RED   ) (back  -BROWN)
67
         };
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
           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
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
77
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
78
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
79
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
80
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
81
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
82
           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
         };
102

    
103
  private static MeshBase mMesh;
104

    
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
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
228

    
229
  float getScreenRatio()
230
    {
231
    return 1.0f;
232
    }
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
  int getNumCubitFaces()
251
    {
252
    return 4;
253
    }
254

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

    
257
  Static3D[] getCubitPositions(int size)
258
    {
259
    return CENTERS;
260
    }
261

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

    
264
  MeshBase createCubitMesh(int cubit)
265
    {
266
    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

    
272
    return mesh;
273
    }
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
}
(4-4/10)