Project

General

Profile

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

magiccube / src / main / java / org / distorted / object / RubikObject.java @ 9224ffd2

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