Project

General

Profile

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

magiccube / src / main / java / org / distorted / object / RubikObject.java @ 411c6285

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 27a70eae Leszek Koltunski
  static final float OBJECT_SCREEN_RATIO = 0.5f;
50 a10ada2a Leszek Koltunski
  final float[] LEGAL_QUATS;
51 27a70eae Leszek Koltunski
52 f16ff19d Leszek Koltunski
  private static final int POST_ROTATION_MILLISEC = 500;
53 a10ada2a Leszek Koltunski
  private final int NUM_CUBITS;
54 3c4a326c Leszek Koltunski
  private int mRotRow;
55
  private Static3D mRotAxis;
56 5ba13c05 Leszek Koltunski
  private Static3D mScale, mNodeScale;
57 27a70eae Leszek Koltunski
  private Static4D mQuatAccumulated;
58 b32444ee Leszek Koltunski
  private Cubit[] mCubits;
59 27a70eae Leszek Koltunski
60 a10ada2a Leszek Koltunski
  int mSize;
61 fdec60a3 Leszek Koltunski
62 27a70eae Leszek Koltunski
  Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
63
  DistortedTexture mTexture;
64
65
  VertexEffectSink mSinkEffect;
66
  MatrixEffectScale mScaleEffect;
67
  MatrixEffectQuaternion mQuatCEffect;
68
  MatrixEffectQuaternion mQuatAEffect;
69
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71 fdec60a3 Leszek Koltunski
72 411c6285 Leszek Koltunski
  RubikObject(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture nodeTexture, MeshRectangles nodeMesh, DistortedEffects nodeEffects)
73 fdec60a3 Leszek Koltunski
    {
74 411c6285 Leszek Koltunski
    super(nodeTexture,nodeEffects,nodeMesh);
75 fdec60a3 Leszek Koltunski
76 ba740a0c Leszek Koltunski
    resizeFBO(NODE_FBO_SIZE, NODE_FBO_SIZE);
77 d41742f7 Leszek Koltunski
78 f16ff19d Leszek Koltunski
    LEGAL_QUATS = getLegalQuats();
79 a10ada2a Leszek Koltunski
    NUM_CUBITS  = getNumCubits(size);
80
81 27a70eae Leszek Koltunski
    mSize = size;
82
83
    mRotationAngleStatic = new Static1D(0);
84
    mRotationAngleMiddle = new Static1D(0);
85
    mRotationAngleFinal  = new Static1D(0);
86
87
    mScale    = new Static3D(1,1,1);
88
    mNodeScale= new Static3D(1,1,1);
89
90
    mQuatAccumulated = quatAcc;
91
92 5ba13c05 Leszek Koltunski
    Static3D center = new Static3D(0,0,0);
93 5974d2ae Leszek Koltunski
    Static4D region = new Static4D(0,0,0,0.72f);
94 27a70eae Leszek Koltunski
95 5ba13c05 Leszek Koltunski
    mSinkEffect = new VertexEffectSink( new Static1D(getSinkStrength()), center, region );
96 27a70eae Leszek Koltunski
    mScaleEffect = new MatrixEffectScale(mScale);
97 5ba13c05 Leszek Koltunski
    mQuatCEffect = new MatrixEffectQuaternion(quatCur, center);
98
    mQuatAEffect = new MatrixEffectQuaternion(quatAcc, center);
99 27a70eae Leszek Koltunski
100
    MatrixEffectScale nodeScaleEffect = new MatrixEffectScale(mNodeScale);
101 411c6285 Leszek Koltunski
    nodeEffects.apply(nodeScaleEffect);
102 a10ada2a Leszek Koltunski
103
    mCubits = new Cubit[NUM_CUBITS];
104 5974d2ae Leszek Koltunski
    mTexture = new DistortedTexture();
105 a10ada2a Leszek Koltunski
106
    int vertices = (int)(24.0f/mSize + 2.0f);
107 b32444ee Leszek Koltunski
    int[][] positions = getCubitPositions(size);
108 a10ada2a Leszek Koltunski
109
    for(int i=0; i<NUM_CUBITS; i++)
110
      {
111 b32444ee Leszek Koltunski
      int x = positions[i][0];
112
      int y = positions[i][1];
113
      int z = positions[i][2];
114 a10ada2a Leszek Koltunski
115 411c6285 Leszek Koltunski
      MeshBase cubit = createCubitMesh(vertices);
116
      textureCubitMesh(cubit,x,y,z);
117
118
      mCubits[i] = new Cubit( this , cubit, new Static3D(x,y,z) );
119 a10ada2a Leszek Koltunski
      attach(mCubits[i].mNode);
120
      }
121 27a70eae Leszek Koltunski
    }
122
123 f16ff19d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
124
125 a10ada2a Leszek Koltunski
  private void resetRotationAngle(Dynamic1D rotationAngle)
126 f16ff19d Leszek Koltunski
    {
127
    rotationAngle.setDuration(POST_ROTATION_MILLISEC);
128
    rotationAngle.resetToBeginning();
129
    rotationAngle.removeAll();
130
    rotationAngle.add(mRotationAngleStatic);
131
    rotationAngle.add(mRotationAngleMiddle);
132
    rotationAngle.add(mRotationAngleFinal);
133
    }
134
135 fdec60a3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
136
137 27a70eae Leszek Koltunski
  private float getSinkStrength()
138 dd73fdab Leszek Koltunski
    {
139 27a70eae Leszek Koltunski
    switch(mSize)
140
      {
141
      case 1 : return 1.1f;
142
      case 2 : return 1.5f;
143
      case 3 : return 1.8f;
144
      case 4 : return 2.0f;
145
      default: return 3.0f - 4.0f/mSize;
146
      }
147 dd73fdab Leszek Koltunski
    }
148
149 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
150
// the getFaceColors + final black in a horizontal strip.
151
152
  public void createTexture()
153
    {
154
    Bitmap bitmap;
155
156
    final int numColors = getNumFaces();
157
158
    Paint paint = new Paint();
159
    bitmap = Bitmap.createBitmap( (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
160
    Canvas canvas = new Canvas(bitmap);
161
162
    paint.setAntiAlias(true);
163
    paint.setTextAlign(Paint.Align.CENTER);
164
    paint.setStyle(Paint.Style.FILL);
165
166
    paint.setColor(0xff000000);
167
    canvas.drawRect(0, 0, (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, paint);
168
169
    for(int i=0; i<numColors; i++)
170
      {
171
      createFaceTexture(canvas,paint,i);
172
      }
173
174
    mTexture.setTexture(bitmap);
175
    }
176
177 dd73fdab Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
178
179 27a70eae Leszek Koltunski
  public int getSize()
180 fdec60a3 Leszek Koltunski
    {
181 27a70eae Leszek Koltunski
    return mSize;
182 fdec60a3 Leszek Koltunski
    }
183
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185
186 27a70eae Leszek Koltunski
  public void continueRotation(float angleInDegrees)
187 fdec60a3 Leszek Koltunski
    {
188 27a70eae Leszek Koltunski
    mRotationAngleStatic.set0(angleInDegrees);
189 fdec60a3 Leszek Koltunski
    }
190
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193 27a70eae Leszek Koltunski
  public Static4D getRotationQuat()
194
      {
195
      return mQuatAccumulated;
196
      }
197
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199
200 5ba13c05 Leszek Koltunski
  public void recomputeScaleFactor(int scrWidth, int scrHeight)
201 fdec60a3 Leszek Koltunski
    {
202 ba740a0c Leszek Koltunski
    float factor = scrWidth>scrHeight ? scrHeight : scrWidth;
203
    float scaleFactor = OBJECT_SCREEN_RATIO*NODE_FBO_SIZE/mSize;
204 27a70eae Leszek Koltunski
205 5ba13c05 Leszek Koltunski
    mNodeScale.set(factor,factor,factor);
206 27a70eae Leszek Koltunski
    mScale.set(scaleFactor,scaleFactor,scaleFactor);
207 fdec60a3 Leszek Koltunski
    }
208 27a70eae Leszek Koltunski
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
211 a10ada2a Leszek Koltunski
  public void savePreferences(SharedPreferences.Editor editor)
212
    {
213
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].savePreferences(editor);
214
    }
215 f16ff19d Leszek Koltunski
216 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
217 27a70eae Leszek Koltunski
218 a10ada2a Leszek Koltunski
  public void restorePreferences(SharedPreferences preferences)
219
    {
220
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].restorePreferences(preferences);
221
    }
222 27a70eae Leszek Koltunski
223 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
224 74686c71 Leszek Koltunski
225 a10ada2a Leszek Koltunski
  public long finishRotationNow(EffectListener listener)
226
    {
227
    boolean first = true;
228
    long effectID=0;
229
230
    for(int i=0; i<NUM_CUBITS; i++)
231
      {
232
      if( belongsToRotation(mCubits[i].mCurrentPosition,mRotAxis,mRotRow) )
233
        {
234
        if( first )
235
          {
236
          first=false;
237
          effectID = mCubits[i].finishRotationNow(listener);
238
          }
239
        resetRotationAngle(mCubits[i].mRotationAngle);
240
        }
241
      }
242
243
    return effectID;
244
    }
245
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247
248
  public void releaseResources()
249
    {
250
    mTexture.markForDeletion();
251
252
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].releaseResources();
253
    }
254
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256
257
  public void apply(Effect effect, int position)
258
    {
259
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].mEffect.apply(effect, position);
260
    }
261
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263
264
  public void remove(long effectID)
265
    {
266
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].mEffect.abortById(effectID);
267
    }
268 74686c71 Leszek Koltunski
269 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
270
271
  public void solve()
272
    {
273
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].solve();
274
    }
275
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277
278
  public boolean isSolved()
279
    {
280
    Static4D q = mCubits[0].mQuatScramble;
281
282
    float x = q.get0();
283
    float y = q.get1();
284
    float z = q.get2();
285
    float w = q.get3();
286
287
    for(int i=0; i<NUM_CUBITS; i++)
288
      {
289
      q = mCubits[i].mQuatScramble;
290
291
      if( q.get0()!=x || q.get1()!=y || q.get2()!=z || q.get3()!=w ) return false;
292
      }
293
294
    return true;
295
    }
296
297
///////////////////////////////////////////////////////////////////////////////////////////////////
298
299 3c4a326c Leszek Koltunski
  public void beginNewRotation(Static3D axis, int row )
300 a10ada2a Leszek Koltunski
    {
301 3c4a326c Leszek Koltunski
    mRotAxis = axis;
302 a10ada2a Leszek Koltunski
    mRotRow  = row;
303
304
    mRotationAngleStatic.set0(0.0f);
305
306
    for(int i=0; i<NUM_CUBITS; i++)
307 3c4a326c Leszek Koltunski
      if( belongsToRotation( mCubits[i].mCurrentPosition,axis,mRotRow) )
308 a10ada2a Leszek Koltunski
        {
309
        mCubits[i].beginNewRotation(axis);
310
        }
311
     }
312
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314
315 3c4a326c Leszek Koltunski
  public long addNewRotation( Static3D axis, int row, int angle, long durationMillis, EffectListener listener )
316 a10ada2a Leszek Koltunski
     {
317
     long effectID=0;
318
     boolean first = true;
319
320 3c4a326c Leszek Koltunski
     mRotAxis = axis;
321 a10ada2a Leszek Koltunski
     mRotRow  = row;
322
323
     mRotationAngleStatic.set0(0.0f);
324
325
     for(int i=0; i<NUM_CUBITS; i++)
326 3c4a326c Leszek Koltunski
       if( belongsToRotation(mCubits[i].mCurrentPosition,axis,mRotRow) )
327 a10ada2a Leszek Koltunski
         {
328
         mCubits[i].addNewRotation(axis,durationMillis,angle);
329
330
         if( first )
331
           {
332
           first = false;
333
           effectID = mCubits[i].setUpCallback(listener);
334
           }
335
         }
336
337
     return effectID;
338
     }
339
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341
342
  public void removeRotationNow()
343
     {
344
     boolean first = true;
345
     Static4D quat = null;
346
347
     for(int i=0; i<NUM_CUBITS; i++)
348
       if( belongsToRotation(mCubits[i].mCurrentPosition,mRotAxis,mRotRow) )
349
         {
350
         if( first )
351
           {
352
           first = false;
353 3c4a326c Leszek Koltunski
           quat = mCubits[i].returnRotationQuat(mRotAxis);
354 a10ada2a Leszek Koltunski
           }
355
356
         mCubits[i].removeRotationNow(quat);
357
         }
358
359
     mRotationAngleStatic.set0(0);
360
     }
361
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363
364
  abstract int getNumCubits(int size);
365
  abstract int[][] getCubitPositions(int size);
366
  abstract float[] getLegalQuats();
367 411c6285 Leszek Koltunski
  abstract int getNumFaces();
368
  abstract void createFaceTexture(Canvas canvas, Paint paint, int face);
369
  abstract MeshBase createCubitMesh(int vertices);
370 a10ada2a Leszek Koltunski
371 411c6285 Leszek Koltunski
  abstract boolean belongsToRotation(Static3D position, Static3D axis, int row);
372
  abstract void textureCubitMesh(MeshBase mesh, int x, int y, int z);
373 fdec60a3 Leszek Koltunski
  }