Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikDino.java @ 3717a94e

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
  float getBasicStep()
277
    {
278
    return SQ3;
279
    }
280

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

    
283
  int getNumStickerTypes()
284
    {
285
    return 1;
286
    }
287

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

    
290
  int getNumCubitFaces()
291
    {
292
    return 4;
293
    }
294

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

    
297
  Static3D[] getCubitPositions(int size)
298
    {
299
    return CENTERS;
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  MeshBase createCubitMesh(int cubit)
305
    {
306
    if( mMesh==null ) createBasicMesh();
307

    
308
    MeshBase mesh = mMesh.copy(true);
309
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[cubit], new Static3D(0,0,0) );
310
    mesh.apply(quat,0xffffffff,0);
311

    
312
    return mesh;
313
    }
314

    
315
///////////////////////////////////////////////////////////////////////////////////////////////////
316

    
317
  int getFaceColor(int cubit, int cubitface, int size)
318
    {
319
    switch(cubitface)
320
      {
321
      case 0 : return mFaceMap[2*cubit];
322
      case 1 : return mFaceMap[2*cubit+1];
323
      default: return NUM_FACES;
324
      }
325
    }
326

    
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

    
329
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side)
330
    {
331
    float STROKE = 0.04f*side;
332
    float L= left;
333
    float H= 0.333f*side;
334
    float LEN = 0.5f*side;
335

    
336
    paint.setAntiAlias(true);
337
    paint.setStrokeWidth(STROKE);
338
    paint.setColor(FACE_COLORS[face]);
339
    paint.setStyle(Paint.Style.FILL);
340

    
341
    canvas.drawRect(left,top,left+side,top+side,paint);
342

    
343
    paint.setColor(INTERIOR_COLOR);
344
    paint.setStyle(Paint.Style.STROKE);
345

    
346
    canvas.drawLine( L      , H,  L+2*LEN, H    , paint);
347
    canvas.drawLine( L      , H,  L+  LEN, H+LEN, paint);
348
    canvas.drawLine( L+2*LEN, H,  L+  LEN, H+LEN, paint);
349

    
350
    float S1 = 0.150f*side;
351
    float S2 = 0.090f*side;
352
    float X  = 0.7f*S2;
353
    float Y  = 0.2f*S1;
354

    
355
    float LA = left+0.500f*side;
356
    float RA = left;
357
    float TA = 0.333f*side;
358
    float BA = 0.833f*side;
359

    
360
    canvas.drawArc( RA+X        , TA     , RA+X+S2  , TA+S2, 135,135, false, paint);
361
    canvas.drawArc( RA+side-S2-X, TA     , RA+side-X, TA+S2, 270,135, false, paint);
362
    canvas.drawArc( LA-S1/2     , BA-S1-Y, LA+S1/2  , BA-Y ,  45, 90, false, paint);
363
    }
364

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

    
367
  float returnMultiplier()
368
    {
369
    return 2.0f;
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  float[] getRowChances()
375
    {
376
    float[] chances = new float[3];
377

    
378
    chances[0] = 0.5f;
379
    chances[1] = 0.5f;
380
    chances[2] = 1.0f;
381

    
382
    return chances;
383
    }
384

    
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386
// PUBLIC API
387

    
388
  public Static3D[] getRotationAxis()
389
    {
390
    return ROT_AXIS;
391
    }
392

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

    
395
  public int getBasicAngle()
396
    {
397
    return 3;
398
    }
399

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

    
402
  public int computeRowFromOffset(float offset)
403
    {
404
    return offset<0.5f ? 0:2;
405
    }
406

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

    
409
  public float returnRotationFactor(float offset)
410
    {
411
    return 1.0f;
412
    }
413

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

    
416
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
417
    {
418
    int numAxis = ROTATION_AXIS.length;
419

    
420
    if( oldRotAxis == START_AXIS )
421
      {
422
      return rnd.nextInt(numAxis);
423
      }
424
    else
425
      {
426
      int newVector = rnd.nextInt(numAxis-1);
427
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
428
      }
429
    }
430

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

    
433
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
434
    {
435
    float rowFloat = rnd.nextFloat();
436

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

    
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472
// remember about the double cover or unit quaternions!
473

    
474
  private int mulQuat(int q1, int q2)
475
    {
476
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
477

    
478
    float rX = result.get0();
479
    float rY = result.get1();
480
    float rZ = result.get2();
481
    float rW = result.get3();
482

    
483
    final float MAX_ERROR = 0.1f;
484
    float dX,dY,dZ,dW;
485

    
486
    for(int i=0; i<QUATS.length; i++)
487
      {
488
      dX = QUATS[i].get0() - rX;
489
      dY = QUATS[i].get1() - rY;
490
      dZ = QUATS[i].get2() - rZ;
491
      dW = QUATS[i].get3() - rW;
492

    
493
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
494
          dY<MAX_ERROR && dY>-MAX_ERROR &&
495
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
496
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
497

    
498
      dX = QUATS[i].get0() + rX;
499
      dY = QUATS[i].get1() + rY;
500
      dZ = QUATS[i].get2() + rZ;
501
      dW = QUATS[i].get3() + rW;
502

    
503
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
504
          dY<MAX_ERROR && dY>-MAX_ERROR &&
505
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
506
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
507
      }
508

    
509
    return -1;
510
    }
511

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

    
530
  public boolean isSolved()
531
    {
532
    int qX = CUBITS[0].mQuatIndex;
533
    int qY = CUBITS[1].mQuatIndex;
534
    int qZ = CUBITS[4].mQuatIndex;
535

    
536
    if( CUBITS[2].mQuatIndex != qX || CUBITS[8].mQuatIndex != qX || CUBITS[10].mQuatIndex != qX ||
537
        CUBITS[3].mQuatIndex != qY || CUBITS[9].mQuatIndex != qY || CUBITS[11].mQuatIndex != qY ||
538
        CUBITS[5].mQuatIndex != qZ || CUBITS[6].mQuatIndex != qZ || CUBITS[ 7].mQuatIndex != qZ  )
539
      {
540
      return false;
541
      }
542

    
543
    return ( qX==qY && qX==qZ ) || ( qY==mulQuat(qX,2) && qZ==mulQuat(qX,8) );
544
    }
545

    
546
///////////////////////////////////////////////////////////////////////////////////////////////////
547
// only needed for solvers - there are no Dino solvers ATM)
548

    
549
  public String retObjectString()
550
    {
551
    return "";
552
    }
553

    
554
}
(3-3/14)