Project

General

Profile

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

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

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 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
           0xffffff00, 0xffffffff,   // FACE_AXIS[0] (right-YELLOW) FACE_AXIS[1] (left  -WHITE)
73
           0xff0000ff, 0xff00ff00,   // FACE_AXIS[2] (top  -BLUE  ) FACE_AXIS[3] (bottom-GREEN)
74
           0xffff0000, 0xffb5651d    // FACE_AXIS[4] (front-RED   ) FACE_AXIS[5] (back  -BROWN)
75
         };
76

    
77
  // All legal rotation quats of a RubikDino
78
  private 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 final int[] mFaceMap = {4,2, 0,4, 4,3, 1,4,
112
                                         2,0, 3,0, 3,1, 2,1,
113
                                         5,2, 0,5, 5,3, 1,5 };
114

    
115
  private static MeshBase mMesh;
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  RubikDino(int size, Static4D quat, DistortedTexture texture,
120
            MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
121
    {
122
    super(size, 60, quat, texture, mesh, effects, moves, RubikObjectList.DINO, res, scrWidth);
123
    }
124

    
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126

    
127
  private void createBasicMesh()
128
    {
129
    final float ANGLE = (float)((180/Math.PI)*(Math.atan(SQ2)));
130

    
131
    final int MESHES=4;
132

    
133
    float D = 0.02f;
134
    float E = 0.5f*SQ2;
135
    float F = 0.5f;
136

    
137
    float[] bands0 = { 1.0f    , 0,
138
                       1.0f-2*D, D*0.25f,
139
                       1.0f-4*D, D*0.35f,
140
                       1.0f-8*D, D*0.6f,
141
                       0.60f   , D*1.0f,
142
                       0.30f   , D*1.375f,
143
                       0.0f    , D*1.4f };
144

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

    
147
    MeshBase[] meshes = new MeshPolygon[MESHES];
148
    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 5);
149
    meshes[0].setEffectAssociation(0,1,0);
150
    meshes[1] = meshes[0].copy(true);
151
    meshes[1].setEffectAssociation(0,2,0);
152

    
153
    float[] bands1 = { 1.0f    , 0,
154
                       0.50f   , 0.10f,
155
                       0.0f    , 0.20f };
156

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

    
159
    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
160
    meshes[2].setEffectAssociation(0,4,0);
161
    meshes[3] = meshes[2].copy(true);
162
    meshes[3].setEffectAssociation(0,8,0);
163

    
164
    mMesh = new MeshJoined(meshes);
165

    
166
    Static3D a0 = new Static3D(     0,-3*F,    0 );
167
    Static3D a1 = new Static3D(     0,   0, -3*F );
168
    Static3D a2 = new Static3D(  -3*F,   0,    0 );
169
    Static3D a3 = new Static3D(  +3*F,   0,    0 );
170

    
171
    Static3D v0 = new Static3D(     0,-3*F/2, 3*F/2 );
172
    Static3D v1 = new Static3D(     0, 3*F/2,-3*F/2 );
173
    Static3D v2 = new Static3D(  -3*F, 3*F/2, 3*F/2 );
174
    Static3D v3 = new Static3D(  +3*F, 3*F/2, 3*F/2 );
175

    
176
    float d1 = 1.0f;
177
    float d2 =-0.10f;
178
    float d3 =-0.10f;
179
    float d4 = 0.40f;
180

    
181
    Static3D dCen0 = new Static3D( d1*a0.get0(), d1*a0.get1(), d1*a0.get2() );
182
    Static3D dCen1 = new Static3D( d1*a1.get0(), d1*a1.get1(), d1*a1.get2() );
183
    Static3D dCen2 = new Static3D( d1*a2.get0(), d1*a2.get1(), d1*a2.get2() );
184
    Static3D dCen3 = new Static3D( d1*a3.get0(), d1*a3.get1(), d1*a3.get2() );
185

    
186
    Static3D dVec0 = new Static3D( d3*v0.get0(), d3*v0.get1(), d3*v0.get2() );
187
    Static3D dVec1 = new Static3D( d3*v1.get0(), d3*v1.get1(), d3*v1.get2() );
188
    Static3D dVec2 = new Static3D( d2*v2.get0(), d2*v2.get1(), d2*v2.get2() );
189
    Static3D dVec3 = new Static3D( d2*v3.get0(), d2*v3.get1(), d2*v3.get2() );
190

    
191
    Static4D dReg  = new Static4D(0,0,0,d4);
192
    Static1D dRad  = new Static1D(1);
193

    
194
    Static1D angle1 = new Static1D(+ANGLE);
195
    Static1D angle2 = new Static1D(-ANGLE);
196

    
197
    Static3D axisX  = new Static3D(1,0,0);
198
    Static3D axisY  = new Static3D(0,1,0);
199
    Static3D axisZ  = new Static3D(0,-1,1);
200

    
201
    Static3D center0= new Static3D(0,0,0);
202
    Static3D center1= new Static3D(0,-3*F,0);
203

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

    
215
    VertexEffectDeform  effect10= new VertexEffectDeform(dVec0, dRad, dCen0, dReg);
216
    VertexEffectDeform  effect11= new VertexEffectDeform(dVec1, dRad, dCen1, dReg);
217
    VertexEffectDeform  effect12= new VertexEffectDeform(dVec2, dRad, dCen2, dReg);
218
    VertexEffectDeform  effect13= new VertexEffectDeform(dVec3, dRad, dCen3, dReg);
219

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

    
235
    mMesh.apply(effect0);
236
    mMesh.apply(effect1);
237
    mMesh.apply(effect2);
238
    mMesh.apply(effect3);
239
    mMesh.apply(effect4);
240
    mMesh.apply(effect5);
241
    mMesh.apply(effect6);
242
    mMesh.apply(effect7);
243
    mMesh.apply(effect8);
244
    mMesh.apply(effect9);
245
    mMesh.apply(effect10);
246
    mMesh.apply(effect11);
247
    mMesh.apply(effect12);
248
    mMesh.apply(effect13);
249

    
250
    mMesh.mergeEffComponents();
251
    }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

    
255
  float getScreenRatio()
256
    {
257
    return 0.5f;
258
    }
259

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

    
262
  Static4D[] getQuats()
263
    {
264
    return QUATS;
265
    }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

    
269
  int getNumFaces()
270
    {
271
    return FACE_COLORS.length;
272
    }
273

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
  int getNumStickerTypes()
277
    {
278
    return 1;
279
    }
280

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282

    
283
  int getNumCubitFaces()
284
    {
285
    return 4;
286
    }
287

    
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

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

    
295
///////////////////////////////////////////////////////////////////////////////////////////////////
296

    
297
  MeshBase createCubitMesh(int cubit)
298
    {
299
    if( mMesh==null ) createBasicMesh();
300

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

    
305
    return mesh;
306
    }
307

    
308
///////////////////////////////////////////////////////////////////////////////////////////////////
309

    
310
  int getFaceColor(int cubit, int cubitface, int size)
311
    {
312
    switch(cubitface)
313
      {
314
      case 0 : return mFaceMap[2*cubit];
315
      case 1 : return mFaceMap[2*cubit+1];
316
      default: return NUM_FACES;
317
      }
318
    }
319

    
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321

    
322
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side)
323
    {
324
    float STROKE = 0.04f*side;
325
    float L= left;
326
    float H= 0.333f*side;
327
    float LEN = 0.5f*side;
328

    
329
    paint.setAntiAlias(true);
330
    paint.setStrokeWidth(STROKE);
331
    paint.setColor(FACE_COLORS[face]);
332
    paint.setStyle(Paint.Style.FILL);
333

    
334
    canvas.drawRect(left,top,left+side,top+side,paint);
335

    
336
    paint.setColor(INTERIOR_COLOR);
337
    paint.setStyle(Paint.Style.STROKE);
338

    
339
    canvas.drawLine( L      , H,  L+2*LEN, H    , paint);
340
    canvas.drawLine( L      , H,  L+  LEN, H+LEN, paint);
341
    canvas.drawLine( L+2*LEN, H,  L+  LEN, H+LEN, paint);
342

    
343
    float S1 = 0.150f*side;
344
    float S2 = 0.090f*side;
345
    float X  = 0.7f*S2;
346
    float Y  = 0.2f*S1;
347

    
348
    float LA = left+0.500f*side;
349
    float RA = left;
350
    float TA = 0.333f*side;
351
    float BA = 0.833f*side;
352

    
353
    canvas.drawArc( RA+X        , TA     , RA+X+S2  , TA+S2, 135,135, false, paint);
354
    canvas.drawArc( RA+side-S2-X, TA     , RA+side-X, TA+S2, 270,135, false, paint);
355
    canvas.drawArc( LA-S1/2     , BA-S1-Y, LA+S1/2  , BA-Y ,  45, 90, false, paint);
356
    }
357

    
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359

    
360
  float returnMultiplier()
361
    {
362
    return 2.0f;
363
    }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  float[] getRowChances()
368
    {
369
    float[] chances = new float[3];
370

    
371
    chances[0] = 0.5f;
372
    chances[1] = 0.5f;
373
    chances[2] = 1.0f;
374

    
375
    return chances;
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379
// PUBLIC API
380

    
381
  public Static3D[] getRotationAxis()
382
    {
383
    return ROT_AXIS;
384
    }
385

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387

    
388
  public int getBasicAngle()
389
    {
390
    return 3;
391
    }
392

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

    
395
  public int computeRowFromOffset(float offset)
396
    {
397
    return offset<0.5f ? 0:2;
398
    }
399

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

    
402
  public float returnRotationFactor(float offset)
403
    {
404
    return 1.0f;
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

    
409
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
410
    {
411
    int numAxis = ROTATION_AXIS.length;
412

    
413
    if( oldRotAxis == START_AXIS )
414
      {
415
      return rnd.nextInt(numAxis);
416
      }
417
    else
418
      {
419
      int newVector = rnd.nextInt(numAxis-1);
420
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
421
      }
422
    }
423

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

    
426
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
427
    {
428
    float rowFloat = rnd.nextFloat();
429

    
430
    switch(oldRotAxis)
431
      {
432
      case 0 : switch(newRotAxis)
433
                 {
434
                 case 1:
435
                 case 2: return oldRow;
436
                 case 3: return 2-oldRow;
437
                 default: android.util.Log.e("dino", "error: oldRotAxis="+oldRotAxis+" newRotAxis:"+newRotAxis);
438
                 }
439
      case 1 : switch(newRotAxis)
440
                 {
441
                 case 0:
442
                 case 3: return oldRow;
443
                 case 2: return 2-oldRow;
444
                 default: android.util.Log.e("dino", "error: oldRotAxis="+oldRotAxis+" newRotAxis:"+newRotAxis);
445
                 }
446
      case 2 : switch(newRotAxis)
447
                 {
448
                 case 0:
449
                 case 3: return oldRow;
450
                 case 1: return 2-oldRow;
451
                 default: android.util.Log.e("dino", "error: oldRotAxis="+oldRotAxis+" newRotAxis:"+newRotAxis);
452
                 }
453
      case 3 : switch(newRotAxis)
454
                 {
455
                 case 1:
456
                 case 2: return oldRow;
457
                 case 0: return 2-oldRow;
458
                 default: android.util.Log.e("dino", "error: oldRotAxis="+oldRotAxis+" newRotAxis:"+newRotAxis);
459
                 }
460
      default: return rowFloat<=0.5f ? 0:2;
461
      }
462
    }
463

    
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465
// remember about the double cover or unit quaternions!
466

    
467
  private int mulQuat(int q1, int q2)
468
    {
469
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
470

    
471
    float rX = result.get0();
472
    float rY = result.get1();
473
    float rZ = result.get2();
474
    float rW = result.get3();
475

    
476
    final float MAX_ERROR = 0.1f;
477
    float dX,dY,dZ,dW;
478

    
479
    for(int i=0; i<QUATS.length; i++)
480
      {
481
      dX = QUATS[i].get0() - rX;
482
      dY = QUATS[i].get1() - rY;
483
      dZ = QUATS[i].get2() - rZ;
484
      dW = QUATS[i].get3() - rW;
485

    
486
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
487
          dY<MAX_ERROR && dY>-MAX_ERROR &&
488
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
489
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
490

    
491
      dX = QUATS[i].get0() + rX;
492
      dY = QUATS[i].get1() + rY;
493
      dZ = QUATS[i].get2() + rZ;
494
      dW = QUATS[i].get3() + rW;
495

    
496
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
497
          dY<MAX_ERROR && dY>-MAX_ERROR &&
498
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
499
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
500
      }
501

    
502
    return -1;
503
    }
504

    
505
///////////////////////////////////////////////////////////////////////////////////////////////////
506
// Dino is solved if and only if:
507
//
508
// All four 'X' cubits (i.e. those whose longest edge goes along the X axis) are rotated
509
// by the same quaternion qX, similarly all four 'Y' cubits by the same qY and all four 'Z'
510
// by the same qZ, and then either:
511
//
512
// a) qX = qY = qZ
513
// b) qY = qX*Q2 and qZ = qX*Q8  (i.e. swap of WHITE and YELLOW faces)
514
// c) qX = qY*Q2 and qZ = qY*Q10 (i.e. swap of BLUE and GREEN faces)
515
// d) qX = qZ*Q8 and qY = qZ*Q10 (i.e. swap of RED and BROWN faces)
516
//
517
// BUT: cases b), c) and d) are really the same - it's all just a mirror image of the original.
518
//
519
// X cubits: 0, 2, 8, 10
520
// Y cubits: 1, 3, 9, 11
521
// Z cubits: 4, 5, 6, 7
522

    
523
  public boolean isSolved()
524
    {
525
    int qX = CUBITS[0].mQuatIndex;
526
    int qY = CUBITS[1].mQuatIndex;
527
    int qZ = CUBITS[4].mQuatIndex;
528

    
529
    if( CUBITS[2].mQuatIndex != qX || CUBITS[8].mQuatIndex != qX || CUBITS[10].mQuatIndex != qX ||
530
        CUBITS[3].mQuatIndex != qY || CUBITS[9].mQuatIndex != qY || CUBITS[11].mQuatIndex != qY ||
531
        CUBITS[5].mQuatIndex != qZ || CUBITS[6].mQuatIndex != qZ || CUBITS[ 7].mQuatIndex != qZ  )
532
      {
533
      return false;
534
      }
535

    
536
    return ( qX==qY && qX==qZ ) || ( qY==mulQuat(qX,2) && qZ==mulQuat(qX,8) );
537
    }
538

    
539
///////////////////////////////////////////////////////////////////////////////////////////////////
540
// TODO  (only needed for solvers - there are no Dino solvers ATM)
541

    
542
  public String retObjectString()
543
    {
544
    return "";
545
    }
546

    
547
}
(3-3/12)