Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyObject.java @ eaf87d1d

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 ccf9fec5 Leszek Koltunski
import android.content.res.Resources;
24 411c6285 Leszek Koltunski
import android.graphics.Bitmap;
25
import android.graphics.Canvas;
26
import android.graphics.Paint;
27 27a70eae Leszek Koltunski
28 27e6c301 Leszek Koltunski
import com.google.firebase.crashlytics.FirebaseCrashlytics;
29
30 27a70eae Leszek Koltunski
import org.distorted.library.effect.Effect;
31 19f0f767 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectMove;
32 27a70eae Leszek Koltunski
import org.distorted.library.effect.MatrixEffectQuaternion;
33
import org.distorted.library.effect.MatrixEffectScale;
34 10585385 Leszek Koltunski
import org.distorted.library.effect.VertexEffectQuaternion;
35 27e6c301 Leszek Koltunski
import org.distorted.library.effect.VertexEffectRotate;
36 27a70eae Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
37 c7e23561 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
38 27a70eae Leszek Koltunski
import org.distorted.library.main.DistortedNode;
39
import org.distorted.library.main.DistortedTexture;
40 b32444ee Leszek Koltunski
import org.distorted.library.mesh.MeshBase;
41 ccf9fec5 Leszek Koltunski
import org.distorted.library.mesh.MeshFile;
42 19f0f767 Leszek Koltunski
import org.distorted.library.mesh.MeshJoined;
43 efa8aa48 Leszek Koltunski
import org.distorted.library.mesh.MeshSquare;
44 27a70eae Leszek Koltunski
import org.distorted.library.message.EffectListener;
45 27e6c301 Leszek Koltunski
import org.distorted.library.type.Dynamic1D;
46 27a70eae Leszek Koltunski
import org.distorted.library.type.Static1D;
47
import org.distorted.library.type.Static3D;
48
import org.distorted.library.type.Static4D;
49 25445dcf Leszek Koltunski
import org.distorted.main.BuildConfig;
50 221a4090 Leszek Koltunski
import org.distorted.main.RubikSurfaceView;
51 4f9f99a2 Leszek Koltunski
52 ccf9fec5 Leszek Koltunski
import java.io.DataInputStream;
53
import java.io.IOException;
54
import java.io.InputStream;
55 7c969a6d Leszek Koltunski
import java.util.Random;
56 ccf9fec5 Leszek Koltunski
57 0333d81e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
58
59 9c2f0c91 Leszek Koltunski
public abstract class TwistyObject extends DistortedNode
60 fdec60a3 Leszek Koltunski
  {
61 ece1b58d Leszek Koltunski
  static final int COLOR_YELLOW = 0xffffff00;
62
  static final int COLOR_WHITE  = 0xffffffff;
63
  static final int COLOR_BLUE   = 0xff0000ff;
64 323b217c Leszek Koltunski
  static final int COLOR_GREEN  = 0xff00bb00;
65 28b54fe3 Leszek Koltunski
  static final int COLOR_RED    = 0xff990000;
66 848c7953 Leszek Koltunski
  static final int COLOR_ORANGE = 0xffff6200;
67 33b4138b Leszek Koltunski
  static final int COLOR_GREY   = 0xff727c7b;
68 5581ba2b Leszek Koltunski
  static final int COLOR_VIOLET = 0xff7700bb;
69 ee526fe0 Leszek Koltunski
  static final int COLOR_BLACK  = 0xff000000;
70 ece1b58d Leszek Koltunski
71 b89898c5 Leszek Koltunski
  static final int TEXTURE_HEIGHT = 256;
72 ae755eda Leszek Koltunski
  static final int NUM_STICKERS_IN_ROW = 4;
73 b89898c5 Leszek Koltunski
74 3f3ff476 Leszek Koltunski
  static final float SQ2 = (float)Math.sqrt(2);
75
  static final float SQ3 = (float)Math.sqrt(3);
76 bbc6da6c Leszek Koltunski
  static final float SQ5 = (float)Math.sqrt(5);
77 3f3ff476 Leszek Koltunski
  static final float SQ6 = (float)Math.sqrt(6);
78
79 ee526fe0 Leszek Koltunski
  private static final float NODE_RATIO = 1.40f;
80
  private static final float MAX_SIZE_CHANGE = 1.35f;
81 81f4fd77 Leszek Koltunski
  private static final float MIN_SIZE_CHANGE = 0.75f;
82 c7b00dfb Leszek Koltunski
83 32f4e2a7 Leszek Koltunski
  private static final boolean mCreateFromDMesh = true;
84 19f0f767 Leszek Koltunski
85 8cccfb10 Leszek Koltunski
  private static final Static3D CENTER = new Static3D(0,0,0);
86 27e6c301 Leszek Koltunski
  private static final int POST_ROTATION_MILLISEC = 500;
87
88 efef689c Leszek Koltunski
  final Static3D[] ROTATION_AXIS;
89 98904e45 Leszek Koltunski
  final Static4D[] QUATS;
90 6b6504fe Leszek Koltunski
  final Cubit[] CUBITS;
91 470820a7 Leszek Koltunski
  final int NUM_FACES;
92 eab9d8f8 Leszek Koltunski
  final int NUM_TEXTURES;
93 8f53e513 Leszek Koltunski
  final int NUM_CUBIT_FACES;
94 1ebc4767 Leszek Koltunski
  final int NUM_AXIS;
95 6b6504fe Leszek Koltunski
  final int NUM_CUBITS;
96 a97e02b7 Leszek Koltunski
  final float[] CUTS;
97
  final int NUM_CUTS;
98 27a70eae Leszek Koltunski
99 b30695c6 Leszek Koltunski
  private static float mInitScreenRatio;
100
  private static float mObjectScreenRatio = 1.0f;
101 e6cf7283 Leszek Koltunski
  private static final float[] mTmp1 = new float[4];
102
  private static final float[] mTmp2 = new float[4];
103 f0fa83ae Leszek Koltunski
104 5b893eee Leszek Koltunski
  private final int mNodeSize;
105 e6cf7283 Leszek Koltunski
  private final float[][] mOrigPos;
106 03aa05d5 Leszek Koltunski
  private final Static3D mNodeScale;
107
  private final Static4D mQuat;
108
  private final int mNumLayers, mRealSize;
109
  private final ObjectList mList;
110
  private final DistortedEffects mEffects;
111
  private final VertexEffectRotate mRotateEffect;
112
  private final Dynamic1D mRotationAngle;
113
  private final Static3D mRotationAxis;
114
  private final Static3D mObjectScale;
115
  private final int[] mQuatDebug;
116 30bc2d91 Leszek Koltunski
  private final float mCameraDist;
117 03aa05d5 Leszek Koltunski
  private int mNumTexRows, mNumTexCols;
118 9224ffd2 Leszek Koltunski
  private int mRotRowBitmap;
119 efef689c Leszek Koltunski
  private int mRotAxis;
120 470820a7 Leszek Koltunski
  private MeshBase mMesh;
121 27a70eae Leszek Koltunski
122 7c969a6d Leszek Koltunski
  float[] mRowChances;
123 27a70eae Leszek Koltunski
  Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
124
  DistortedTexture mTexture;
125
  MatrixEffectScale mScaleEffect;
126 4da7d87a Leszek Koltunski
  MatrixEffectQuaternion mQuatEffect;
127 27a70eae Leszek Koltunski
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129 fdec60a3 Leszek Koltunski
130 db875721 Leszek Koltunski
  TwistyObject(int numLayers, int realSize, Static4D quat, DistortedTexture nodeTexture, MeshSquare nodeMesh,
131 9c2f0c91 Leszek Koltunski
               DistortedEffects nodeEffects, int[][] moves, ObjectList list, Resources res, int screenWidth)
132 fdec60a3 Leszek Koltunski
    {
133 411c6285 Leszek Koltunski
    super(nodeTexture,nodeEffects,nodeMesh);
134 fdec60a3 Leszek Koltunski
135 5b893eee Leszek Koltunski
    mNodeSize = screenWidth;
136
137 c7b00dfb Leszek Koltunski
    resizeFBO(mNodeSize, (int)(NODE_RATIO*mNodeSize));
138 d41742f7 Leszek Koltunski
139 d99f3a48 Leszek Koltunski
    mNumLayers = numLayers;
140
    mRealSize = realSize;
141 aa171dee Leszek Koltunski
    mList = list;
142 d99f3a48 Leszek Koltunski
    mOrigPos = getCubitPositions(mNumLayers);
143 10a2e360 Leszek Koltunski
144 98904e45 Leszek Koltunski
    QUATS = getQuats();
145 49f67f9b Leszek Koltunski
    NUM_CUBITS  = mOrigPos.length;
146 efef689c Leszek Koltunski
    ROTATION_AXIS = getRotationAxis();
147 1ebc4767 Leszek Koltunski
    NUM_AXIS = ROTATION_AXIS.length;
148 b30695c6 Leszek Koltunski
    mInitScreenRatio = getScreenRatio();
149 470820a7 Leszek Koltunski
    NUM_FACES = getNumFaces();
150 8f53e513 Leszek Koltunski
    NUM_CUBIT_FACES = getNumCubitFaces();
151 a64e07d0 Leszek Koltunski
    NUM_TEXTURES = getNumStickerTypes(mNumLayers)*NUM_FACES;
152 d99f3a48 Leszek Koltunski
    CUTS = getCuts(mNumLayers);
153 68b5f9c5 Leszek Koltunski
    NUM_CUTS = CUTS== null ? 0: CUTS.length;
154 a10ada2a Leszek Koltunski
155 a15078bb Leszek Koltunski
    mQuatDebug = new int[NUM_CUBITS];
156
157 b30695c6 Leszek Koltunski
    if( mObjectScreenRatio>MAX_SIZE_CHANGE) mObjectScreenRatio = MAX_SIZE_CHANGE;
158
    if( mObjectScreenRatio<MIN_SIZE_CHANGE) mObjectScreenRatio = MIN_SIZE_CHANGE;
159
160 c7b00dfb Leszek Koltunski
    mNodeScale= new Static3D(1,NODE_RATIO,1);
161 4da7d87a Leszek Koltunski
    mQuat = quat;
162 e844c116 Leszek Koltunski
163 a64e07d0 Leszek Koltunski
    mRowChances = getRowChances(mNumLayers);
164 7c969a6d Leszek Koltunski
165 27e6c301 Leszek Koltunski
    mRotationAngle= new Dynamic1D();
166
    mRotationAxis = new Static3D(1,0,0);
167 8cccfb10 Leszek Koltunski
    mRotateEffect = new VertexEffectRotate(mRotationAngle, mRotationAxis, CENTER);
168 27e6c301 Leszek Koltunski
169 27a70eae Leszek Koltunski
    mRotationAngleStatic = new Static1D(0);
170
    mRotationAngleMiddle = new Static1D(0);
171
    mRotationAngleFinal  = new Static1D(0);
172
173 d99f3a48 Leszek Koltunski
    float scale  = mObjectScreenRatio*mInitScreenRatio*mNodeSize/mRealSize;
174 19f0f767 Leszek Koltunski
    mObjectScale = new Static3D(scale,scale,scale);
175 c7b00dfb Leszek Koltunski
    mScaleEffect = new MatrixEffectScale(mObjectScale);
176 4da7d87a Leszek Koltunski
    mQuatEffect  = new MatrixEffectQuaternion(quat, CENTER);
177 27a70eae Leszek Koltunski
178
    MatrixEffectScale nodeScaleEffect = new MatrixEffectScale(mNodeScale);
179 411c6285 Leszek Koltunski
    nodeEffects.apply(nodeScaleEffect);
180 a10ada2a Leszek Koltunski
181 ae755eda Leszek Koltunski
    mNumTexCols = NUM_STICKERS_IN_ROW;
182
    mNumTexRows = (NUM_TEXTURES+1)/NUM_STICKERS_IN_ROW;
183
184
    if( mNumTexCols*mNumTexRows < NUM_TEXTURES+1 ) mNumTexRows++;
185
186 6b6504fe Leszek Koltunski
    CUBITS = new Cubit[NUM_CUBITS];
187 19f0f767 Leszek Koltunski
    createMeshAndCubits(list,res);
188 7381193e Leszek Koltunski
189 19f0f767 Leszek Koltunski
    mTexture = new DistortedTexture();
190 470820a7 Leszek Koltunski
    mEffects = new DistortedEffects();
191 10585385 Leszek Koltunski
192 98904e45 Leszek Koltunski
    int num_quats = QUATS.length;
193 10585385 Leszek Koltunski
    for(int q=0; q<num_quats; q++)
194
      {
195 98904e45 Leszek Koltunski
      VertexEffectQuaternion vq = new VertexEffectQuaternion(QUATS[q],CENTER);
196 10585385 Leszek Koltunski
      vq.setMeshAssociation(0,q);
197
      mEffects.apply(vq);
198
      }
199
200 27e6c301 Leszek Koltunski
    mEffects.apply(mRotateEffect);
201 4da7d87a Leszek Koltunski
    mEffects.apply(mQuatEffect);
202 470820a7 Leszek Koltunski
    mEffects.apply(mScaleEffect);
203
204 dfbb340a Leszek Koltunski
    // Now postprocessed effects (the glow when you solve an object) require component centers. In
205 b376bfd7 Leszek Koltunski
    // order for the effect to be in front of the object, we need to set the center to be behind it.
206 dfbb340a Leszek Koltunski
    getMesh().setComponentCenter(0,0,0,-0.1f);
207
208 470820a7 Leszek Koltunski
    attach( new DistortedNode(mTexture,mEffects,mMesh) );
209
210 aa171dee Leszek Koltunski
    setupPosition(moves);
211
212 30bc2d91 Leszek Koltunski
    float fov = list.getFOV();
213
    double halfFOV = fov * (Math.PI/360);
214
    mCameraDist = 0.5f*NODE_RATIO / (float)Math.tan(halfFOV);
215
216
    setProjection( fov, 0.1f);
217 27a70eae Leszek Koltunski
    }
218
219 e6cf7283 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
220
221
  private Static3D getPos(float[] origPos)
222
    {
223
    int len = origPos.length/3;
224
    float sumX = 0.0f;
225
    float sumY = 0.0f;
226
    float sumZ = 0.0f;
227
228
    for(int i=0; i<len; i++)
229
      {
230
      sumX += origPos[3*i  ];
231
      sumY += origPos[3*i+1];
232
      sumZ += origPos[3*i+2];
233
      }
234
235
    sumX /= len;
236
    sumY /= len;
237
    sumZ /= len;
238
239
    return new Static3D(sumX,sumY,sumZ);
240
    }
241
242 19f0f767 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
243
244 9c2f0c91 Leszek Koltunski
  private void createMeshAndCubits(ObjectList list, Resources res)
245 19f0f767 Leszek Koltunski
    {
246
    if( mCreateFromDMesh )
247
      {
248 d99f3a48 Leszek Koltunski
      int sizeIndex = ObjectList.getSizeIndex(list.ordinal(),mNumLayers);
249 19f0f767 Leszek Koltunski
      int resourceID= list.getResourceIDs()[sizeIndex];
250
251
      InputStream is = res.openRawResource(resourceID);
252
      DataInputStream dos = new DataInputStream(is);
253
      mMesh = new MeshFile(dos);
254
255
      try
256
        {
257
        is.close();
258
        }
259
      catch(IOException e)
260
        {
261
        android.util.Log.e("meshFile", "Error closing InputStream: "+e.toString());
262
        }
263
264
      for(int i=0; i<NUM_CUBITS; i++)
265
        {
266 6b6504fe Leszek Koltunski
        CUBITS[i] = new Cubit(this,mOrigPos[i]);
267
        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0);
268 19f0f767 Leszek Koltunski
        }
269 eaee1ddc Leszek Koltunski
270
      if( shouldResetTextureMaps() ) resetAllTextureMaps();
271 19f0f767 Leszek Koltunski
      }
272
    else
273
      {
274
      MeshBase[] cubitMesh = new MeshBase[NUM_CUBITS];
275
276
      for(int i=0; i<NUM_CUBITS; i++)
277
        {
278 6b6504fe Leszek Koltunski
        CUBITS[i] = new Cubit(this,mOrigPos[i]);
279 a64e07d0 Leszek Koltunski
        cubitMesh[i] = createCubitMesh(i,mNumLayers);
280 e6cf7283 Leszek Koltunski
        Static3D pos = getPos(mOrigPos[i]);
281
        cubitMesh[i].apply(new MatrixEffectMove(pos),1,0);
282 6b6504fe Leszek Koltunski
        cubitMesh[i].setEffectAssociation(0, CUBITS[i].computeAssociation(), 0);
283 19f0f767 Leszek Koltunski
        }
284
285
      mMesh = new MeshJoined(cubitMesh);
286
      resetAllTextureMaps();
287
      }
288
    }
289
290 c7b00dfb Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
291
292
  public void setObjectRatio(float sizeChange)
293
    {
294
    mObjectScreenRatio *= (1.0f+sizeChange)/2;
295
296 b30695c6 Leszek Koltunski
    if( mObjectScreenRatio>MAX_SIZE_CHANGE) mObjectScreenRatio = MAX_SIZE_CHANGE;
297
    if( mObjectScreenRatio<MIN_SIZE_CHANGE) mObjectScreenRatio = MIN_SIZE_CHANGE;
298 c7b00dfb Leszek Koltunski
299 d99f3a48 Leszek Koltunski
    float scale = mObjectScreenRatio*mInitScreenRatio*mNodeSize/mRealSize;
300 c7b00dfb Leszek Koltunski
    mObjectScale.set(scale,scale,scale);
301
    }
302
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304
305
  static float getObjectRatio()
306
    {
307 b30695c6 Leszek Koltunski
    return mObjectScreenRatio*mInitScreenRatio;
308 c7b00dfb Leszek Koltunski
    }
309
310 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
311
312 e6cf7283 Leszek Koltunski
  int computeRow(float[] pos, int rotIndex)
313 e844c116 Leszek Koltunski
    {
314 e6cf7283 Leszek Koltunski
    int ret=0;
315
    int len = pos.length / 3;
316 a97e02b7 Leszek Koltunski
    Static3D axis = ROTATION_AXIS[rotIndex];
317 e6cf7283 Leszek Koltunski
    float axisX = axis.get0();
318
    float axisY = axis.get1();
319
    float axisZ = axis.get2();
320
321
    for(int i=0; i<len; i++)
322
      {
323
      ret |= computeRow(pos[3*i]*axisX + pos[3*i+1]*axisY + pos[3*i+2]*axisZ);
324
      }
325
326
    return ret;
327
    }
328
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330 e844c116 Leszek Koltunski
331 e6cf7283 Leszek Koltunski
  private int computeRow(float casted)
332
    {
333 a97e02b7 Leszek Koltunski
    for(int i=0; i<NUM_CUTS; i++)
334 e844c116 Leszek Koltunski
      {
335 e6cf7283 Leszek Koltunski
      if( casted<CUTS[i] ) return (1<<i);
336 e844c116 Leszek Koltunski
      }
337
338 f0450fcc Leszek Koltunski
    return (1<<NUM_CUTS);
339 e844c116 Leszek Koltunski
    }
340
341 985f3dfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
342
343
  private boolean wasRotateApplied()
344
    {
345
    return mEffects.exists(mRotateEffect.getID());
346
    }
347
348 efef689c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
349
350 9224ffd2 Leszek Koltunski
  private boolean belongsToRotation( int cubit, int axis, int rowBitmap)
351 efef689c Leszek Koltunski
    {
352 f0450fcc Leszek Koltunski
    return (CUBITS[cubit].mRotationRow[axis] & rowBitmap) != 0;
353 66cbdd21 Leszek Koltunski
    }
354
355 aa171dee Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
356 a31d25de Leszek Koltunski
// note the minus in front of the sin() - we rotate counterclockwise
357
// when looking towards the direction where the axis increases in values.
358 aa171dee Leszek Koltunski
359 a31d25de Leszek Koltunski
  private Static4D makeQuaternion(int axisIndex, int angleInDegrees)
360 aa171dee Leszek Koltunski
    {
361 a31d25de Leszek Koltunski
    Static3D axis = ROTATION_AXIS[axisIndex];
362
363
    while( angleInDegrees<0 ) angleInDegrees += 360;
364
    angleInDegrees %= 360;
365
    
366
    float cosA = (float)Math.cos(Math.PI*angleInDegrees/360);
367
    float sinA =-(float)Math.sqrt(1-cosA*cosA);
368
369
    return new Static4D(axis.get0()*sinA, axis.get1()*sinA, axis.get2()*sinA, cosA);
370
    }
371
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373
374 8bbac3c2 Leszek Koltunski
  private synchronized void setupPosition(int[][] moves)
375 a31d25de Leszek Koltunski
    {
376
    if( moves!=null )
377
      {
378
      Static4D quat;
379 818431ed Leszek Koltunski
      int index, axis, rowBitmap, angle;
380 a31d25de Leszek Koltunski
      int corr = (360/getBasicAngle());
381
382
      for(int[] move: moves)
383
        {
384
        axis     = move[0];
385
        rowBitmap= move[1];
386
        angle    = move[2]*corr;
387
        quat     = makeQuaternion(axis,angle);
388
389
        for(int j=0; j<NUM_CUBITS; j++)
390
          if( belongsToRotation(j,axis,rowBitmap) )
391
            {
392 6b6504fe Leszek Koltunski
            index = CUBITS[j].removeRotationNow(quat);
393
            mMesh.setEffectAssociation(j, CUBITS[j].computeAssociation(),index);
394 a31d25de Leszek Koltunski
            }
395
        }
396
      }
397 aa171dee Leszek Koltunski
    }
398
399 fa0f7a56 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
400
401
  int getCubitFaceColorIndex(int cubit, int face)
402
    {
403 470820a7 Leszek Koltunski
    Static4D texMap = mMesh.getTextureMap(NUM_FACES*cubit + face);
404 064ccc31 Leszek Koltunski
405
    int x = (int)(texMap.get0()/texMap.get2());
406
    int y = (int)(texMap.get1()/texMap.get3());
407
408
    return (mNumTexRows-1-y)*NUM_STICKERS_IN_ROW + x;
409 fa0f7a56 Leszek Koltunski
    }
410
411 ce366b42 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
412
// normal, not bandaged, object.
413
414
  int computeBitmapFromRow(int rowBitmap, int axis)
415
    {
416
    return rowBitmap;
417
    }
418
419 49f67f9b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
420
// Clamp all rotated positions to one of those original ones to avoid accumulating errors.
421
422 e6cf7283 Leszek Koltunski
  void clampPos(float[] pos, int offset)
423 49f67f9b Leszek Koltunski
    {
424
    float currError, minError = Float.MAX_VALUE;
425 e6cf7283 Leszek Koltunski
    int minErrorIndex1 = -1;
426
    int minErrorIndex2 = -1;
427
428
    float x = pos[offset  ];
429
    float y = pos[offset+1];
430
    float z = pos[offset+2];
431
432 49f67f9b Leszek Koltunski
    float xo,yo,zo;
433
434
    for(int i=0; i<NUM_CUBITS; i++)
435
      {
436 e6cf7283 Leszek Koltunski
      int len = mOrigPos[i].length / 3;
437 49f67f9b Leszek Koltunski
438 e6cf7283 Leszek Koltunski
      for(int j=0; j<len; j++)
439 49f67f9b Leszek Koltunski
        {
440 e6cf7283 Leszek Koltunski
        xo = mOrigPos[i][3*j  ];
441
        yo = mOrigPos[i][3*j+1];
442
        zo = mOrigPos[i][3*j+2];
443
444
        currError = (xo-x)*(xo-x) + (yo-y)*(yo-y) + (zo-z)*(zo-z);
445
446
        if( currError<minError )
447
          {
448
          minError = currError;
449
          minErrorIndex1 = i;
450
          minErrorIndex2 = j;
451
          }
452 49f67f9b Leszek Koltunski
        }
453
      }
454
455 e6cf7283 Leszek Koltunski
    pos[offset  ] = mOrigPos[minErrorIndex1][3*minErrorIndex2  ];
456
    pos[offset+1] = mOrigPos[minErrorIndex1][3*minErrorIndex2+1];
457
    pos[offset+2] = mOrigPos[minErrorIndex1][3*minErrorIndex2+2];
458 49f67f9b Leszek Koltunski
    }
459
460 221a4090 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
461
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
462
// then if it were rotated by quaternion 'quat'.
463
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
464
// middle squares get interchanged. No visible difference!
465
//
466
// So: this is true iff the cubit
467
// a) is a corner or edge and the quaternions are the same
468
// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
469
470 722b2512 Leszek Koltunski
  boolean thereIsVisibleDifference(Cubit cubit, int quatIndex)
471 221a4090 Leszek Koltunski
    {
472 722b2512 Leszek Koltunski
    if ( cubit.mQuatIndex == quatIndex ) return false;
473 221a4090 Leszek Koltunski
474
    int belongsToHowManyFaces = 0;
475 f0450fcc Leszek Koltunski
    int bitmap = (1<<(getNumLayers()-1)) + 1;
476 221a4090 Leszek Koltunski
477
    for(int i=0; i<NUM_AXIS; i++)
478
      {
479 f0450fcc Leszek Koltunski
      if( (cubit.mRotationRow[i] & bitmap) != 0 ) belongsToHowManyFaces++;
480 221a4090 Leszek Koltunski
      }
481
482
    switch(belongsToHowManyFaces)
483
      {
484 722b2512 Leszek Koltunski
      case 0 : return false;  // 'inside' cubit that does not lie on any face
485 221a4090 Leszek Koltunski
      case 1 :                // cubit that lies inside one of the faces
486 e6cf7283 Leszek Koltunski
               float[] orig   = cubit.getOrigPosition();
487 221a4090 Leszek Koltunski
               Static4D quat1 = QUATS[quatIndex];
488
               Static4D quat2 = QUATS[cubit.mQuatIndex];
489
490 e6cf7283 Leszek Koltunski
               Static4D cubitCenter = new Static4D( orig[0], orig[1], orig[2], 0);              // not used for bandaged objects,
491
               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );   // only check the first position
492 221a4090 Leszek Koltunski
               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
493
494 e6cf7283 Leszek Koltunski
               rotated1.get(mTmp1, 0, 0, 0);
495
               rotated2.get(mTmp2, 0, 0, 0);
496 221a4090 Leszek Koltunski
497
               for(int i=0; i<NUM_AXIS; i++)
498
                 {
499 e6cf7283 Leszek Koltunski
                 if( (computeRow(mTmp1,i) & computeRow(mTmp2,i) & bitmap) != 0 ) return false;
500 221a4090 Leszek Koltunski
                 }
501 722b2512 Leszek Koltunski
               return true;
502 221a4090 Leszek Koltunski
503 722b2512 Leszek Koltunski
      default: return true;  // edge or corner
504 221a4090 Leszek Koltunski
      }
505
    }
506
507 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
508 ae755eda Leszek Koltunski
// the getFaceColors + final black in a grid (so that we do not exceed the maximum texture size)
509 411c6285 Leszek Koltunski
510
  public void createTexture()
511
    {
512
    Bitmap bitmap;
513
514
    Paint paint = new Paint();
515 ae755eda Leszek Koltunski
    bitmap = Bitmap.createBitmap( mNumTexCols*TEXTURE_HEIGHT, mNumTexRows*TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
516 411c6285 Leszek Koltunski
    Canvas canvas = new Canvas(bitmap);
517
518
    paint.setAntiAlias(true);
519
    paint.setTextAlign(Paint.Align.CENTER);
520
    paint.setStyle(Paint.Style.FILL);
521
522 ee526fe0 Leszek Koltunski
    paint.setColor(COLOR_BLACK);
523 ae755eda Leszek Koltunski
    canvas.drawRect(0, 0, mNumTexCols*TEXTURE_HEIGHT, mNumTexRows*TEXTURE_HEIGHT, paint);
524 411c6285 Leszek Koltunski
525 ae755eda Leszek Koltunski
    int tex = 0;
526
527
    for(int row=0; row<mNumTexRows; row++)
528
      for(int col=0; col<mNumTexCols; col++)
529
        {
530
        if( tex>=NUM_TEXTURES ) break;
531
        createFaceTexture(canvas, paint, tex, col*TEXTURE_HEIGHT, row*TEXTURE_HEIGHT);
532
        tex++;
533
        }
534 411c6285 Leszek Koltunski
535 c7e23561 Leszek Koltunski
    if( !mTexture.setTexture(bitmap) )
536
      {
537
      int max = DistortedLibrary.getMaxTextureSize();
538
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
539
      crashlytics.log("failed to set texture of size "+bitmap.getWidth()+"x"+bitmap.getHeight()+" max is "+max);
540
      }
541 411c6285 Leszek Koltunski
    }
542
543 dd73fdab Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
544
545 d99f3a48 Leszek Koltunski
  public int getNumLayers()
546 fdec60a3 Leszek Koltunski
    {
547 d99f3a48 Leszek Koltunski
    return mNumLayers;
548 fdec60a3 Leszek Koltunski
    }
549
550
///////////////////////////////////////////////////////////////////////////////////////////////////
551
552 27a70eae Leszek Koltunski
  public void continueRotation(float angleInDegrees)
553 fdec60a3 Leszek Koltunski
    {
554 27a70eae Leszek Koltunski
    mRotationAngleStatic.set0(angleInDegrees);
555 fdec60a3 Leszek Koltunski
    }
556
557
///////////////////////////////////////////////////////////////////////////////////////////////////
558
559 27a70eae Leszek Koltunski
  public Static4D getRotationQuat()
560
      {
561 4da7d87a Leszek Koltunski
      return mQuat;
562 27a70eae Leszek Koltunski
      }
563
564
///////////////////////////////////////////////////////////////////////////////////////////////////
565
566 f18e8fae Leszek Koltunski
  public void recomputeScaleFactor(int scrWidth)
567 fdec60a3 Leszek Koltunski
    {
568 3717a94e Leszek Koltunski
    mNodeScale.set(scrWidth,NODE_RATIO*scrWidth,scrWidth);
569 fdec60a3 Leszek Koltunski
    }
570 27a70eae Leszek Koltunski
571
///////////////////////////////////////////////////////////////////////////////////////////////////
572
573 a10ada2a Leszek Koltunski
  public void savePreferences(SharedPreferences.Editor editor)
574
    {
575 6b6504fe Leszek Koltunski
    for(int i=0; i<NUM_CUBITS; i++) CUBITS[i].savePreferences(editor);
576 a10ada2a Leszek Koltunski
    }
577 f16ff19d Leszek Koltunski
578 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
579 27a70eae Leszek Koltunski
580 8bbac3c2 Leszek Koltunski
  public synchronized void restorePreferences(SharedPreferences preferences)
581 a10ada2a Leszek Koltunski
    {
582 fc3c5170 Leszek Koltunski
    boolean error = false;
583
584 2fcad75d Leszek Koltunski
    for(int i=0; i<NUM_CUBITS; i++)
585
      {
586 a15078bb Leszek Koltunski
      mQuatDebug[i] = CUBITS[i].restorePreferences(preferences);
587 1d6c1eea Leszek Koltunski
588 fc3c5170 Leszek Koltunski
      if( mQuatDebug[i]>=0 && mQuatDebug[i]<QUATS.length)
589 1d6c1eea Leszek Koltunski
        {
590 fc3c5170 Leszek Koltunski
        CUBITS[i].modifyCurrentPosition(QUATS[mQuatDebug[i]]);
591
        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),mQuatDebug[i]);
592
        }
593
      else
594
        {
595
        error = true;
596 1d6c1eea Leszek Koltunski
        }
597 fc3c5170 Leszek Koltunski
      }
598 1d6c1eea Leszek Koltunski
599 fc3c5170 Leszek Koltunski
    if( error )
600
      {
601
      for(int i=0; i<NUM_CUBITS; i++)
602
        {
603
        CUBITS[i].solve();
604
        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),0);
605
        }
606
      recordQuatsState("Failed to restorePreferences");
607 a15078bb Leszek Koltunski
      }
608
    }
609
610
///////////////////////////////////////////////////////////////////////////////////////////////////
611
612
  public void recordQuatsState(String message)
613
    {
614
    StringBuilder quats = new StringBuilder();
615
616
    for(int j=0; j<NUM_CUBITS; j++)
617
      {
618
      quats.append(mQuatDebug[j]);
619
      quats.append(" ");
620 2fcad75d Leszek Koltunski
      }
621 a15078bb Leszek Koltunski
622 25445dcf Leszek Koltunski
    if( BuildConfig.DEBUG )
623
      {
624 2d9d9d62 Leszek Koltunski
      android.util.Log.e("quats" , quats.toString());
625 25445dcf Leszek Koltunski
      android.util.Log.e("object", mList.name()+"_"+mNumLayers);
626
      }
627
    else
628
      {
629
      Exception ex = new Exception(message);
630
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
631
      crashlytics.setCustomKey("quats" , quats.toString());
632
      crashlytics.setCustomKey("object", mList.name()+"_"+mNumLayers );
633
      crashlytics.recordException(ex);
634
      }
635 a10ada2a Leszek Koltunski
    }
636 27a70eae Leszek Koltunski
637 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
638
639
  public void releaseResources()
640
    {
641
    mTexture.markForDeletion();
642 54342a21 Leszek Koltunski
    mMesh.markForDeletion();
643
    mEffects.markForDeletion();
644
645
    for(int j=0; j<NUM_CUBITS; j++)
646
      {
647
      CUBITS[j].releaseResources();
648
      }
649 a10ada2a Leszek Koltunski
    }
650
651
///////////////////////////////////////////////////////////////////////////////////////////////////
652
653
  public void apply(Effect effect, int position)
654
    {
655 8cccfb10 Leszek Koltunski
    mEffects.apply(effect, position);
656 a10ada2a Leszek Koltunski
    }
657
658
///////////////////////////////////////////////////////////////////////////////////////////////////
659
660
  public void remove(long effectID)
661
    {
662 8cccfb10 Leszek Koltunski
    mEffects.abortById(effectID);
663 a10ada2a Leszek Koltunski
    }
664 74686c71 Leszek Koltunski
665 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
666
667 8bbac3c2 Leszek Koltunski
  public synchronized void solve()
668 a10ada2a Leszek Koltunski
    {
669 98904e45 Leszek Koltunski
    for(int i=0; i<NUM_CUBITS; i++)
670
      {
671 6b6504fe Leszek Koltunski
      CUBITS[i].solve();
672
      mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0);
673 a10ada2a Leszek Koltunski
      }
674
    }
675
676 1f9772f3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
677
678
  public void resetAllTextureMaps()
679
    {
680 ae755eda Leszek Koltunski
    final float ratioW = 1.0f/mNumTexCols;
681
    final float ratioH = 1.0f/mNumTexRows;
682
    int color, row, col;
683 380162cb Leszek Koltunski
684 ad73edd5 Leszek Koltunski
    for(int cubit=0; cubit<NUM_CUBITS; cubit++)
685 1f9772f3 Leszek Koltunski
      {
686 8f53e513 Leszek Koltunski
      final Static4D[] maps = new Static4D[NUM_CUBIT_FACES];
687 ad73edd5 Leszek Koltunski
688 f6d06256 Leszek Koltunski
      for(int cubitface=0; cubitface<NUM_CUBIT_FACES; cubitface++)
689 ad73edd5 Leszek Koltunski
        {
690 d99f3a48 Leszek Koltunski
        color = getFaceColor(cubit,cubitface,mNumLayers);
691 ae755eda Leszek Koltunski
        row = (mNumTexRows-1) - color/mNumTexCols;
692
        col = color%mNumTexCols;
693
        maps[cubitface] = new Static4D( col*ratioW, row*ratioH, ratioW, ratioH);
694 ad73edd5 Leszek Koltunski
        }
695
696 8f53e513 Leszek Koltunski
      mMesh.setTextureMap(maps,NUM_CUBIT_FACES*cubit);
697 1f9772f3 Leszek Koltunski
      }
698
    }
699
700
///////////////////////////////////////////////////////////////////////////////////////////////////
701
702
  public void setTextureMap(int cubit, int face, int newColor)
703
    {
704 064ccc31 Leszek Koltunski
    final float ratioW = 1.0f/mNumTexCols;
705
    final float ratioH = 1.0f/mNumTexRows;
706 8f53e513 Leszek Koltunski
    final Static4D[] maps = new Static4D[NUM_CUBIT_FACES];
707 064ccc31 Leszek Koltunski
    int row = (mNumTexRows-1) - newColor/mNumTexCols;
708
    int col = newColor%mNumTexCols;
709 1f9772f3 Leszek Koltunski
710 064ccc31 Leszek Koltunski
    maps[face] = new Static4D( col*ratioW, row*ratioH, ratioW, ratioH);
711 8f53e513 Leszek Koltunski
    mMesh.setTextureMap(maps,NUM_CUBIT_FACES*cubit);
712 1f9772f3 Leszek Koltunski
    }
713
714 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
715
716 8bbac3c2 Leszek Koltunski
  public synchronized void beginNewRotation(int axis, int row )
717 a10ada2a Leszek Koltunski
    {
718 9cd7695f Leszek Koltunski
    if( axis<0 || axis>=ROTATION_AXIS.length )
719
      {
720
      android.util.Log.e("object", "invalid rotation axis: "+axis);
721
      return;
722
      }
723 d99f3a48 Leszek Koltunski
    if( row<0 || row>=mNumLayers )
724 9cd7695f Leszek Koltunski
      {
725
      android.util.Log.e("object", "invalid rotation row: "+row);
726
      return;
727
      }
728
729 27e6c301 Leszek Koltunski
    mRotAxis     = axis;
730 ce366b42 Leszek Koltunski
    mRotRowBitmap= computeBitmapFromRow( (1<<row),axis );
731 a10ada2a Leszek Koltunski
    mRotationAngleStatic.set0(0.0f);
732 27e6c301 Leszek Koltunski
    mRotationAxis.set( ROTATION_AXIS[axis] );
733
    mRotationAngle.add(mRotationAngleStatic);
734 9c2f0c91 Leszek Koltunski
    mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis* ObjectList.MAX_OBJECT_SIZE) , -1);
735 27e6c301 Leszek Koltunski
    }
736 a10ada2a Leszek Koltunski
737
///////////////////////////////////////////////////////////////////////////////////////////////////
738
739 8bbac3c2 Leszek Koltunski
  public synchronized long addNewRotation( int axis, int rowBitmap, int angle, long durationMillis, EffectListener listener )
740 27e6c301 Leszek Koltunski
    {
741 985f3dfa Leszek Koltunski
    if( wasRotateApplied() )
742
      {
743
      mRotAxis     = axis;
744 ce366b42 Leszek Koltunski
      mRotRowBitmap= computeBitmapFromRow( rowBitmap,axis );
745 985f3dfa Leszek Koltunski
746
      mRotationAngleStatic.set0(0.0f);
747
      mRotationAxis.set( ROTATION_AXIS[axis] );
748
      mRotationAngle.setDuration(durationMillis);
749
      mRotationAngle.resetToBeginning();
750
      mRotationAngle.add(new Static1D(0));
751
      mRotationAngle.add(new Static1D(angle));
752
      mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis* ObjectList.MAX_OBJECT_SIZE) , -1);
753
      mRotateEffect.notifyWhenFinished(listener);
754
755
      return mRotateEffect.getID();
756
      }
757 27e6c301 Leszek Koltunski
758 985f3dfa Leszek Koltunski
    return 0;
759 27e6c301 Leszek Koltunski
    }
760 a10ada2a Leszek Koltunski
761 27e6c301 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
762 a10ada2a Leszek Koltunski
763 168b6b56 Leszek Koltunski
  public long finishRotationNow(EffectListener listener, int nearestAngleInDegrees)
764 27e6c301 Leszek Koltunski
    {
765 985f3dfa Leszek Koltunski
    if( wasRotateApplied() )
766
      {
767
      float angle = getAngle();
768
      mRotationAngleStatic.set0(angle);
769
      mRotationAngleFinal.set0(nearestAngleInDegrees);
770
      mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-angle)*0.2f );
771
772
      mRotationAngle.setDuration(POST_ROTATION_MILLISEC);
773
      mRotationAngle.resetToBeginning();
774
      mRotationAngle.removeAll();
775
      mRotationAngle.add(mRotationAngleStatic);
776
      mRotationAngle.add(mRotationAngleMiddle);
777
      mRotationAngle.add(mRotationAngleFinal);
778
      mRotateEffect.notifyWhenFinished(listener);
779
780
      return mRotateEffect.getID();
781
      }
782 27e6c301 Leszek Koltunski
783 985f3dfa Leszek Koltunski
    return 0;
784 27e6c301 Leszek Koltunski
    }
785 001cc0e4 Leszek Koltunski
786
///////////////////////////////////////////////////////////////////////////////////////////////////
787
788 27e6c301 Leszek Koltunski
  private float getAngle()
789 001cc0e4 Leszek Koltunski
    {
790 27e6c301 Leszek Koltunski
    int pointNum = mRotationAngle.getNumPoints();
791 001cc0e4 Leszek Koltunski
792 27e6c301 Leszek Koltunski
    if( pointNum>=1 )
793 001cc0e4 Leszek Koltunski
      {
794 27e6c301 Leszek Koltunski
      return mRotationAngle.getPoint(pointNum-1).get0();
795
      }
796
    else
797
      {
798
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
799
      crashlytics.log("points in RotationAngle: "+pointNum);
800
      return 0;
801 001cc0e4 Leszek Koltunski
      }
802
    }
803
804 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
805
806 8bbac3c2 Leszek Koltunski
  public synchronized void removeRotationNow()
807 168b6b56 Leszek Koltunski
    {
808
    float angle = getAngle();
809
    double nearestAngleInRadians = angle*Math.PI/180;
810
    float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
811
    float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
812
    float axisX = ROTATION_AXIS[mRotAxis].get0();
813
    float axisY = ROTATION_AXIS[mRotAxis].get1();
814
    float axisZ = ROTATION_AXIS[mRotAxis].get2();
815
    Static4D quat = new Static4D( axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
816
817
    mRotationAngle.removeAll();
818
    mRotationAngleStatic.set0(0);
819
820
    for(int i=0; i<NUM_CUBITS; i++)
821
      if( belongsToRotation(i,mRotAxis,mRotRowBitmap) )
822
        {
823 6b6504fe Leszek Koltunski
        int index = CUBITS[i].removeRotationNow(quat);
824
        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),index);
825 168b6b56 Leszek Koltunski
        }
826
    }
827 a10ada2a Leszek Koltunski
828 aa171dee Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
829
830 a31d25de Leszek Koltunski
  public void initializeObject(int[][] moves)
831 aa171dee Leszek Koltunski
    {
832
    solve();
833
    setupPosition(moves);
834
    }
835
836 9621255f Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
837
838
  public int getCubit(float[] point3D)
839
    {
840 418aa554 Leszek Koltunski
    float dist, minDist = Float.MAX_VALUE;
841 9621255f Leszek Koltunski
    int currentBest=-1;
842
    float multiplier = returnMultiplier();
843
844
    point3D[0] *= multiplier;
845
    point3D[1] *= multiplier;
846
    point3D[2] *= multiplier;
847
848
    for(int i=0; i<NUM_CUBITS; i++)
849
      {
850 6b6504fe Leszek Koltunski
      dist = CUBITS[i].getDistSquared(point3D);
851 9621255f Leszek Koltunski
      if( dist<minDist )
852
        {
853
        minDist = dist;
854
        currentBest = i;
855
        }
856
      }
857
858
    return currentBest;
859
    }
860
861 0e5ad27c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
862
863 168b6b56 Leszek Koltunski
  public int computeNearestAngle(float angle, float speed)
864 0e5ad27c Leszek Koltunski
    {
865
    final int NEAREST = 360/getBasicAngle();
866
867 4c864c68 Leszek Koltunski
    int tmp = (int)((angle+NEAREST/2)/NEAREST);
868
    if( angle< -(NEAREST*0.5) ) tmp-=1;
869 168b6b56 Leszek Koltunski
870 4c864c68 Leszek Koltunski
    if( tmp!=0 ) return NEAREST*tmp;
871 168b6b56 Leszek Koltunski
872 c7b00dfb Leszek Koltunski
    return speed> 1.2f ? NEAREST*(angle>0 ? 1:-1) : 0;
873 0e5ad27c Leszek Koltunski
    }
874
875 30bc2d91 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
876
877
  public float getCameraDist()
878
    {
879
    return mCameraDist;
880
    }
881
882 5b893eee Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
883
884
  public int getNodeSize()
885
    {
886
    return mNodeSize;
887
    }
888
889 aa171dee Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
890
891 9c2f0c91 Leszek Koltunski
  public ObjectList getObjectList()
892 aa171dee Leszek Koltunski
    {
893
    return mList;
894
    }
895
896 10a2e360 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
897
898 f0fa83ae Leszek Koltunski
  abstract float getScreenRatio();
899 e6cf7283 Leszek Koltunski
  abstract float[][] getCubitPositions(int numLayers);
900 10585385 Leszek Koltunski
  abstract Static4D[] getQuats();
901 411c6285 Leszek Koltunski
  abstract int getNumFaces();
902 a64e07d0 Leszek Koltunski
  abstract int getNumStickerTypes(int numLayers);
903 8f53e513 Leszek Koltunski
  abstract int getNumCubitFaces();
904 a64e07d0 Leszek Koltunski
  abstract MeshBase createCubitMesh(int cubit, int numLayers);
905 ae755eda Leszek Koltunski
  abstract void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top);
906
  abstract int getFaceColor(int cubit, int cubitface, int numLayers);
907 fb377dae Leszek Koltunski
  abstract float returnMultiplier();
908 a64e07d0 Leszek Koltunski
  abstract float[] getRowChances(int numLayers);
909 ae755eda Leszek Koltunski
  abstract float[] getCuts(int numLayers);
910 eaee1ddc Leszek Koltunski
  abstract boolean shouldResetTextureMaps();
911 7c969a6d Leszek Koltunski
912 6b6504fe Leszek Koltunski
  public abstract boolean isSolved();
913 12ad3fca Leszek Koltunski
  public abstract Static3D[] getRotationAxis();
914 e844c116 Leszek Koltunski
  public abstract int getBasicAngle();
915 20931cf6 Leszek Koltunski
  public abstract String retObjectString();
916 5043d5d0 Leszek Koltunski
  public abstract void randomizeNewScramble(int[][] scramble, Random rnd, int numScramble);
917 6fd4a72c Leszek Koltunski
  public abstract int getObjectName(int numLayers);
918
  public abstract int getInventor(int numLayers);
919
  public abstract int getComplexity(int numLayers);
920 fdec60a3 Leszek Koltunski
  }