Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikObject.java @ 0e5ad27c

1 fdec60a3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 1f9772f3 Leszek Koltunski
package org.distorted.objects;
21 fdec60a3 Leszek Koltunski
22 27a70eae Leszek Koltunski
import android.content.SharedPreferences;
23 411c6285 Leszek Koltunski
import android.graphics.Bitmap;
24
import android.graphics.Canvas;
25
import android.graphics.Paint;
26 27a70eae Leszek Koltunski
27
import org.distorted.library.effect.Effect;
28
import org.distorted.library.effect.MatrixEffectQuaternion;
29
import org.distorted.library.effect.MatrixEffectScale;
30
import org.distorted.library.effect.VertexEffectSink;
31
import org.distorted.library.main.DistortedEffects;
32
import org.distorted.library.main.DistortedNode;
33
import org.distorted.library.main.DistortedTexture;
34 b32444ee Leszek Koltunski
import org.distorted.library.mesh.MeshBase;
35 97c012ae Leszek Koltunski
import org.distorted.library.mesh.MeshRectangles;
36 27a70eae Leszek Koltunski
import org.distorted.library.message.EffectListener;
37 f16ff19d Leszek Koltunski
import org.distorted.library.type.Dynamic1D;
38 27a70eae Leszek Koltunski
import org.distorted.library.type.Static1D;
39
import org.distorted.library.type.Static3D;
40
import org.distorted.library.type.Static4D;
41 4f9f99a2 Leszek Koltunski
42 0333d81e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
43
44 27a70eae Leszek Koltunski
public abstract class RubikObject extends DistortedNode
45 fdec60a3 Leszek Koltunski
  {
46 fb6a40c8 Leszek Koltunski
  public static final int NODE_FBO_SIZE = 600;
47
48 7289fd6c Leszek Koltunski
  private static final int TEXTURE_HEIGHT = 128;
49 a10ada2a Leszek Koltunski
  final float[] LEGAL_QUATS;
50 efef689c Leszek Koltunski
  final Static3D[] ROTATION_AXIS;
51 27a70eae Leszek Koltunski
52 f0fa83ae Leszek Koltunski
  static float OBJECT_SCREEN_RATIO;
53
54 f16ff19d Leszek Koltunski
  private static final int POST_ROTATION_MILLISEC = 500;
55 a10ada2a Leszek Koltunski
  private final int NUM_CUBITS;
56 9224ffd2 Leszek Koltunski
  private int mRotRowBitmap;
57 efef689c Leszek Koltunski
  private int mRotAxis;
58 49f67f9b Leszek Koltunski
  private Static3D[] mOrigPos;
59 fb6a40c8 Leszek Koltunski
  private Static3D mNodeScale;
60 27a70eae Leszek Koltunski
  private Static4D mQuatAccumulated;
61 b32444ee Leszek Koltunski
  private Cubit[] mCubits;
62 49f67f9b Leszek Koltunski
  private int mSize;
63 aa171dee Leszek Koltunski
  private RubikObjectList mList;
64 27a70eae Leszek Koltunski
65 e844c116 Leszek Koltunski
  float mStart, mStep;
66 fdec60a3 Leszek Koltunski
67 27a70eae Leszek Koltunski
  Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
68
  DistortedTexture mTexture;
69
70
  VertexEffectSink mSinkEffect;
71
  MatrixEffectScale mScaleEffect;
72
  MatrixEffectQuaternion mQuatCEffect;
73
  MatrixEffectQuaternion mQuatAEffect;
74
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76 fdec60a3 Leszek Koltunski
77 aa171dee Leszek Koltunski
  RubikObject(int size, int fov, Static4D quatCur, Static4D quatAcc, DistortedTexture nodeTexture,
78 a31d25de Leszek Koltunski
              MeshRectangles nodeMesh, DistortedEffects nodeEffects, int[][] moves, RubikObjectList list)
79 fdec60a3 Leszek Koltunski
    {
80 411c6285 Leszek Koltunski
    super(nodeTexture,nodeEffects,nodeMesh);
81 fdec60a3 Leszek Koltunski
82 ba740a0c Leszek Koltunski
    resizeFBO(NODE_FBO_SIZE, NODE_FBO_SIZE);
83 d41742f7 Leszek Koltunski
84 aa171dee Leszek Koltunski
    mList = list;
85 49f67f9b Leszek Koltunski
    mOrigPos = getCubitPositions(size);
86 10a2e360 Leszek Koltunski
87 f16ff19d Leszek Koltunski
    LEGAL_QUATS = getLegalQuats();
88 49f67f9b Leszek Koltunski
    NUM_CUBITS  = mOrigPos.length;
89 efef689c Leszek Koltunski
    ROTATION_AXIS = getRotationAxis();
90 f0fa83ae Leszek Koltunski
    OBJECT_SCREEN_RATIO = getScreenRatio();
91 a10ada2a Leszek Koltunski
92 27a70eae Leszek Koltunski
    mSize = size;
93 49f67f9b Leszek Koltunski
    computeStartAndStep(mOrigPos);
94 fb6a40c8 Leszek Koltunski
    mNodeScale= new Static3D(1,1,1);
95
    mQuatAccumulated = quatAcc;
96
    mSinkEffect  = getSink(mSize);
97 e844c116 Leszek Koltunski
98 27a70eae Leszek Koltunski
    mRotationAngleStatic = new Static1D(0);
99
    mRotationAngleMiddle = new Static1D(0);
100
    mRotationAngleFinal  = new Static1D(0);
101
102 5ba13c05 Leszek Koltunski
    Static3D center = new Static3D(0,0,0);
103 fb6a40c8 Leszek Koltunski
    float scale = OBJECT_SCREEN_RATIO*NODE_FBO_SIZE/mSize;
104
    mScaleEffect = new MatrixEffectScale(new Static3D(scale,scale,scale));
105 5ba13c05 Leszek Koltunski
    mQuatCEffect = new MatrixEffectQuaternion(quatCur, center);
106
    mQuatAEffect = new MatrixEffectQuaternion(quatAcc, center);
107 27a70eae Leszek Koltunski
108
    MatrixEffectScale nodeScaleEffect = new MatrixEffectScale(mNodeScale);
109 411c6285 Leszek Koltunski
    nodeEffects.apply(nodeScaleEffect);
110 a10ada2a Leszek Koltunski
111
    mCubits = new Cubit[NUM_CUBITS];
112 5974d2ae Leszek Koltunski
    mTexture = new DistortedTexture();
113 a10ada2a Leszek Koltunski
114
    int vertices = (int)(24.0f/mSize + 2.0f);
115
116
    for(int i=0; i<NUM_CUBITS; i++)
117
      {
118 89a11f7b Leszek Koltunski
      MeshBase cubitMesh = createCubitMesh(i,vertices);
119 49f67f9b Leszek Koltunski
      mCubits[i] = new Cubit(this,cubitMesh,mOrigPos[i]);
120 efef689c Leszek Koltunski
      textureCubitMesh(cubitMesh,i);
121 a10ada2a Leszek Koltunski
122
      attach(mCubits[i].mNode);
123
      }
124 7381193e Leszek Koltunski
125 aa171dee Leszek Koltunski
    setupPosition(moves);
126
127 4888e97c Leszek Koltunski
    setProjection(fov, 0.1f);
128 27a70eae Leszek Koltunski
    }
129
130 efef689c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
131
132
  private void textureCubitMesh(MeshBase mesh, int cubit)
133
    {
134
    boolean belongs;
135
    final int numFaces = getNumFaces();
136
    final Static4D[] maps = new Static4D[numFaces];
137
    final float ratio = 1.0f/(numFaces+1);
138
139 97d2f701 Leszek Koltunski
    if( 2*ROTATION_AXIS.length == numFaces )  // i.e. there are faces on both ends of the axis (cube)
140 efef689c Leszek Koltunski
      {
141
      for(int i=0; i<numFaces; i++)
142
        {
143 66cbdd21 Leszek Koltunski
        belongs = isOnFace(cubit, i/2, i%2==0 ? mSize-1:0 );
144 efef689c Leszek Koltunski
        maps[i] = new Static4D( (belongs?i:6)*ratio, 0.0f, ratio, 1.0f);
145
        }
146
      }
147 97d2f701 Leszek Koltunski
    else if( ROTATION_AXIS.length == numFaces )  // just a single face on the right end of an axis (pyraminx)
148 efef689c Leszek Koltunski
      {
149
      for(int i=0; i<numFaces; i++)
150
        {
151 66cbdd21 Leszek Koltunski
        belongs = isOnFace(cubit, i, 0 );
152 efef689c Leszek Koltunski
        maps[i] = new Static4D( (belongs?i:6)*ratio, 0.0f, ratio, 1.0f);
153
        }
154
      }
155
156
    mesh.setTextureMap(maps);
157
    }
158
159 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
160 97d2f701 Leszek Koltunski
// Cast centers of all Cubits on the first rotation Axis and compute the leftmost and rightmost
161
// one. From there compute the 'start' (i.e. the leftmost) and 'step' (i.e. distance between two
162
// consecutive).
163
// it is assumed that other rotation axis have the same 'start' and 'step' - this is the case with
164
// the Cube and the Pyraminx.
165
// Start and Step are then needed to compute which rotation row (with respect to a given axis) a
166
// given Cubit belongs to.
167 e844c116 Leszek Koltunski
168
  private void computeStartAndStep(Static3D[] pos)
169
    {
170
    float min = Float.MAX_VALUE;
171
    float max = Float.MIN_VALUE;
172
    float axisX = ROTATION_AXIS[0].get0();
173
    float axisY = ROTATION_AXIS[0].get1();
174
    float axisZ = ROTATION_AXIS[0].get2();
175
    float tmp;
176
177
    for(int i=0; i<NUM_CUBITS; i++)
178
      {
179
      tmp = pos[i].get0()*axisX + pos[i].get1()*axisY + pos[i].get2()*axisZ;
180
      if( tmp<min ) min=tmp;
181
      if( tmp>max ) max=tmp;
182
      }
183
184
    mStart = min;
185
    mStep  = (max-min+1.0f)/mSize;
186
    }
187
188 efef689c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
189
190 9224ffd2 Leszek Koltunski
  private boolean belongsToRotation( int cubit, int axis, int rowBitmap)
191 efef689c Leszek Koltunski
    {
192 9224ffd2 Leszek Koltunski
    int cubitRow = (int)(mCubits[cubit].mRotationRow[axis]+0.5f);
193
    return ((1<<cubitRow)&rowBitmap)!=0;
194 66cbdd21 Leszek Koltunski
    }
195
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197
// we cannot use belongsToRotation for deciding if to texture a face. Counterexample: the 'rotated'
198
// tetrahedrons of Pyraminx nearby the edge: they belong to rotation but their face which is rotated
199
// away from the face of the Pyraminx shouldn't be textured.
200
201
  private boolean isOnFace( int cubit, int axis, int row)
202
    {
203
    final float MAX_ERROR = 0.0001f;
204
    float diff = mCubits[cubit].mRotationRow[axis] - row;
205
    return diff*diff < MAX_ERROR;
206 efef689c Leszek Koltunski
    }
207
208 f16ff19d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
209
210 a10ada2a Leszek Koltunski
  private void resetRotationAngle(Dynamic1D rotationAngle)
211 f16ff19d Leszek Koltunski
    {
212
    rotationAngle.setDuration(POST_ROTATION_MILLISEC);
213
    rotationAngle.resetToBeginning();
214
    rotationAngle.removeAll();
215
    rotationAngle.add(mRotationAngleStatic);
216
    rotationAngle.add(mRotationAngleMiddle);
217
    rotationAngle.add(mRotationAngleFinal);
218
    }
219
220 aa171dee Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
221 a31d25de Leszek Koltunski
// note the minus in front of the sin() - we rotate counterclockwise
222
// when looking towards the direction where the axis increases in values.
223 aa171dee Leszek Koltunski
224 a31d25de Leszek Koltunski
  private Static4D makeQuaternion(int axisIndex, int angleInDegrees)
225 aa171dee Leszek Koltunski
    {
226 a31d25de Leszek Koltunski
    Static3D axis = ROTATION_AXIS[axisIndex];
227
228
    while( angleInDegrees<0 ) angleInDegrees += 360;
229
    angleInDegrees %= 360;
230
    
231
    float cosA = (float)Math.cos(Math.PI*angleInDegrees/360);
232
    float sinA =-(float)Math.sqrt(1-cosA*cosA);
233
234
    return new Static4D(axis.get0()*sinA, axis.get1()*sinA, axis.get2()*sinA, cosA);
235
    }
236
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238
239
  private void setupPosition(int[][] moves)
240
    {
241
    if( moves!=null )
242
      {
243
      Static4D quat;
244
      int axis, rowBitmap, angle;
245
      int corr = (360/getBasicAngle());
246
247
      for(int[] move: moves)
248
        {
249
        axis     = move[0];
250
        rowBitmap= move[1];
251
        angle    = move[2]*corr;
252
        quat     = makeQuaternion(axis,angle);
253
254
        for(int j=0; j<NUM_CUBITS; j++)
255
          if( belongsToRotation(j,axis,rowBitmap) )
256
            {
257
            mCubits[j].removeRotationNow(quat);
258
            }
259
        }
260
      }
261 aa171dee Leszek Koltunski
    }
262
263 fa0f7a56 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
264
265
  int getCubitFaceColorIndex(int cubit, int face)
266
    {
267
    return mCubits[cubit].getColorIndex(face);
268
    }
269
270 49f67f9b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
271
// Clamp all rotated positions to one of those original ones to avoid accumulating errors.
272
273
  void clampPos(Static3D pos)
274
    {
275
    float currError, minError = Float.MAX_VALUE;
276
    int minErrorIndex= -1;
277
    float x = pos.get0();
278
    float y = pos.get1();
279
    float z = pos.get2();
280
    float xo,yo,zo;
281
282
    for(int i=0; i<NUM_CUBITS; i++)
283
      {
284
      xo = mOrigPos[i].get0();
285
      yo = mOrigPos[i].get1();
286
      zo = mOrigPos[i].get2();
287
288
      currError = (xo-x)*(xo-x) + (yo-y)*(yo-y) + (zo-z)*(zo-z);
289
290
      if( currError<minError )
291
        {
292
        minError = currError;
293
        minErrorIndex = i;
294
        }
295
      }
296
297
    pos.set( mOrigPos[minErrorIndex] );
298
    }
299
300 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
301
// the getFaceColors + final black in a horizontal strip.
302
303
  public void createTexture()
304
    {
305
    Bitmap bitmap;
306
307
    final int numColors = getNumFaces();
308
309
    Paint paint = new Paint();
310
    bitmap = Bitmap.createBitmap( (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
311
    Canvas canvas = new Canvas(bitmap);
312
313
    paint.setAntiAlias(true);
314
    paint.setTextAlign(Paint.Align.CENTER);
315
    paint.setStyle(Paint.Style.FILL);
316
317
    paint.setColor(0xff000000);
318
    canvas.drawRect(0, 0, (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, paint);
319
320
    for(int i=0; i<numColors; i++)
321
      {
322 ca292407 Leszek Koltunski
      createFaceTexture(canvas, paint, i, i*TEXTURE_HEIGHT, 0, TEXTURE_HEIGHT);
323 411c6285 Leszek Koltunski
      }
324
325
    mTexture.setTexture(bitmap);
326
    }
327
328 dd73fdab Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
329
330 27a70eae Leszek Koltunski
  public int getSize()
331 fdec60a3 Leszek Koltunski
    {
332 27a70eae Leszek Koltunski
    return mSize;
333 fdec60a3 Leszek Koltunski
    }
334
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336
337 27a70eae Leszek Koltunski
  public void continueRotation(float angleInDegrees)
338 fdec60a3 Leszek Koltunski
    {
339 27a70eae Leszek Koltunski
    mRotationAngleStatic.set0(angleInDegrees);
340 fdec60a3 Leszek Koltunski
    }
341
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
344 27a70eae Leszek Koltunski
  public Static4D getRotationQuat()
345
      {
346
      return mQuatAccumulated;
347
      }
348
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350
351 5ba13c05 Leszek Koltunski
  public void recomputeScaleFactor(int scrWidth, int scrHeight)
352 fdec60a3 Leszek Koltunski
    {
353 f0fa83ae Leszek Koltunski
    float factor = Math.min(scrWidth,scrHeight);
354 5ba13c05 Leszek Koltunski
    mNodeScale.set(factor,factor,factor);
355 fdec60a3 Leszek Koltunski
    }
356 27a70eae Leszek Koltunski
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358
359 a10ada2a Leszek Koltunski
  public void savePreferences(SharedPreferences.Editor editor)
360
    {
361
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].savePreferences(editor);
362
    }
363 f16ff19d Leszek Koltunski
364 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
365 27a70eae Leszek Koltunski
366 a10ada2a Leszek Koltunski
  public void restorePreferences(SharedPreferences preferences)
367
    {
368
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].restorePreferences(preferences);
369
    }
370 27a70eae Leszek Koltunski
371 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
372 74686c71 Leszek Koltunski
373 a10ada2a Leszek Koltunski
  public long finishRotationNow(EffectListener listener)
374
    {
375
    boolean first = true;
376
    long effectID=0;
377
378
    for(int i=0; i<NUM_CUBITS; i++)
379
      {
380 9224ffd2 Leszek Koltunski
      if( belongsToRotation(i,mRotAxis,mRotRowBitmap) )
381 a10ada2a Leszek Koltunski
        {
382
        if( first )
383
          {
384
          first=false;
385
          effectID = mCubits[i].finishRotationNow(listener);
386
          }
387
        resetRotationAngle(mCubits[i].mRotationAngle);
388
        }
389
      }
390
391
    return effectID;
392
    }
393
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395
396
  public void releaseResources()
397
    {
398
    mTexture.markForDeletion();
399
400
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].releaseResources();
401
    }
402
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404
405
  public void apply(Effect effect, int position)
406
    {
407
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].mEffect.apply(effect, position);
408
    }
409
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411
412
  public void remove(long effectID)
413
    {
414
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].mEffect.abortById(effectID);
415
    }
416 74686c71 Leszek Koltunski
417 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
418
419
  public void solve()
420
    {
421
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].solve();
422
    }
423
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425
426
  public boolean isSolved()
427
    {
428
    Static4D q = mCubits[0].mQuatScramble;
429
430 94ad5a8f Leszek Koltunski
    for(int i=1; i<NUM_CUBITS; i++)
431 a10ada2a Leszek Koltunski
      {
432 94ad5a8f Leszek Koltunski
      if( !mCubits[i].thereIsNoVisibleDifference(q) ) return false;
433 a10ada2a Leszek Koltunski
      }
434
435
    return true;
436
    }
437
438 1f9772f3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
439
440
  public void resetAllTextureMaps()
441
    {
442
    for(int i=0; i<NUM_CUBITS; i++)
443
      {
444
      textureCubitMesh( mCubits[i].getMesh() , i );
445
      }
446
    }
447
448
///////////////////////////////////////////////////////////////////////////////////////////////////
449
450
  public void setTextureMap(int cubit, int face, int newColor)
451
    {
452
    final int numFaces = getNumFaces();
453
    final float ratio = 1.0f/(numFaces+1);
454
455
    final Static4D[] maps = new Static4D[numFaces];
456
    maps[face] = new Static4D( newColor*ratio, 0.0f, ratio, 1.0f);
457
458
    mCubits[cubit].getMesh().setTextureMap(maps);
459
    }
460
461 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
462
463 efef689c Leszek Koltunski
  public void beginNewRotation(int axis, int row )
464 a10ada2a Leszek Koltunski
    {
465 9cd7695f Leszek Koltunski
    if( axis<0 || axis>=ROTATION_AXIS.length )
466
      {
467
      android.util.Log.e("object", "invalid rotation axis: "+axis);
468
      return;
469
      }
470
    if( row<0 || row>=mSize )
471
      {
472
      android.util.Log.e("object", "invalid rotation row: "+row);
473
      return;
474
      }
475
476 9224ffd2 Leszek Koltunski
    mRotAxis       = axis;
477
    mRotRowBitmap  = (1<<row);
478 a10ada2a Leszek Koltunski
479
    mRotationAngleStatic.set0(0.0f);
480
481
    for(int i=0; i<NUM_CUBITS; i++)
482 9224ffd2 Leszek Koltunski
      if( belongsToRotation(i,mRotAxis,mRotRowBitmap) )
483 a10ada2a Leszek Koltunski
        {
484
        mCubits[i].beginNewRotation(axis);
485
        }
486
     }
487
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489
490 9224ffd2 Leszek Koltunski
  public long addNewRotation( int axis, int rowBitmap, int angle, long durationMillis, EffectListener listener )
491 a10ada2a Leszek Koltunski
     {
492
     long effectID=0;
493
     boolean first = true;
494
495 9224ffd2 Leszek Koltunski
     mRotAxis       = axis;
496
     mRotRowBitmap  = rowBitmap;
497 a10ada2a Leszek Koltunski
498
     mRotationAngleStatic.set0(0.0f);
499
500
     for(int i=0; i<NUM_CUBITS; i++)
501 9224ffd2 Leszek Koltunski
       if( belongsToRotation(i,mRotAxis,mRotRowBitmap) )
502 a10ada2a Leszek Koltunski
         {
503
         mCubits[i].addNewRotation(axis,durationMillis,angle);
504
505
         if( first )
506
           {
507
           first = false;
508
           effectID = mCubits[i].setUpCallback(listener);
509
           }
510
         }
511
512
     return effectID;
513
     }
514
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516
517
  public void removeRotationNow()
518
     {
519
     boolean first = true;
520
     Static4D quat = null;
521
522
     for(int i=0; i<NUM_CUBITS; i++)
523 9224ffd2 Leszek Koltunski
       if( belongsToRotation(i,mRotAxis,mRotRowBitmap) )
524 a10ada2a Leszek Koltunski
         {
525
         if( first )
526
           {
527
           first = false;
528 3c4a326c Leszek Koltunski
           quat = mCubits[i].returnRotationQuat(mRotAxis);
529 a10ada2a Leszek Koltunski
           }
530
531
         mCubits[i].removeRotationNow(quat);
532
         }
533
534
     mRotationAngleStatic.set0(0);
535
     }
536
537 aa171dee Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
538
539 a31d25de Leszek Koltunski
  public void initializeObject(int[][] moves)
540 aa171dee Leszek Koltunski
    {
541
    solve();
542
    setupPosition(moves);
543
    }
544
545 9621255f Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
546
547
  public int getCubit(float[] point3D)
548
    {
549
    float dist, minDist = Float. MAX_VALUE;
550
    int currentBest=-1;
551
    float multiplier = returnMultiplier();
552
553
    point3D[0] *= multiplier;
554
    point3D[1] *= multiplier;
555
    point3D[2] *= multiplier;
556
557
    for(int i=0; i<NUM_CUBITS; i++)
558
      {
559
      dist = mCubits[i].getDistSquared(point3D);
560
      if( dist<minDist )
561
        {
562
        minDist = dist;
563
        currentBest = i;
564
        }
565
      }
566
567
    return currentBest;
568
    }
569
570 0e5ad27c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
571
572
  public int computeNearestAngle(float angle)
573
    {
574
    final int NEAREST = 360/getBasicAngle();
575
576
    int tmp = (int)((angle+NEAREST/2)/NEAREST);
577
    if( angle< -(NEAREST*0.5) ) tmp-=1;
578
579
    return NEAREST*tmp;
580
    }
581
582 aa171dee Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
583
584
  public RubikObjectList getObjectList()
585
    {
586
    return mList;
587
    }
588
589 10a2e360 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
590
591 f0fa83ae Leszek Koltunski
  abstract float getScreenRatio();
592
  abstract VertexEffectSink getSink(int size);
593 10a2e360 Leszek Koltunski
  abstract Static3D[] getCubitPositions(int size);
594 a10ada2a Leszek Koltunski
  abstract float[] getLegalQuats();
595 411c6285 Leszek Koltunski
  abstract int getNumFaces();
596 89a11f7b Leszek Koltunski
  abstract MeshBase createCubitMesh(int cubit, int vertices);
597 7289fd6c Leszek Koltunski
  abstract void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side);
598 12ad3fca Leszek Koltunski
  public abstract Static3D[] getRotationAxis();
599 e844c116 Leszek Koltunski
  public abstract int getBasicAngle();
600 9621255f Leszek Koltunski
  public abstract float returnMultiplier();
601 e46e17fb Leszek Koltunski
  public abstract float returnRotationFactor(float offset);
602 20931cf6 Leszek Koltunski
  public abstract String retObjectString();
603 5cf34c5f Leszek Koltunski
  public abstract float[] getRowChances();
604 fdec60a3 Leszek Koltunski
  }