Project

General

Profile

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

magiccube / src / main / java / org / distorted / object / RubikObject.java @ 3c4a326c

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
24
import org.distorted.library.effect.Effect;
25
import org.distorted.library.effect.MatrixEffectMove;
26
import org.distorted.library.effect.MatrixEffectQuaternion;
27
import org.distorted.library.effect.MatrixEffectScale;
28
import org.distorted.library.effect.VertexEffectSink;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedNode;
31
import org.distorted.library.main.DistortedTexture;
32 a10ada2a Leszek Koltunski
import org.distorted.library.mesh.MeshCubes;
33 97c012ae Leszek Koltunski
import org.distorted.library.mesh.MeshRectangles;
34 27a70eae Leszek Koltunski
import org.distorted.library.message.EffectListener;
35 f16ff19d Leszek Koltunski
import org.distorted.library.type.Dynamic1D;
36 27a70eae Leszek Koltunski
import org.distorted.library.type.Static1D;
37
import org.distorted.library.type.Static3D;
38
import org.distorted.library.type.Static4D;
39 4f9f99a2 Leszek Koltunski
40 0333d81e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
41
42 27a70eae Leszek Koltunski
public abstract class RubikObject extends DistortedNode
43 fdec60a3 Leszek Koltunski
  {
44 27a70eae Leszek Koltunski
  static final float OBJECT_SCREEN_RATIO = 0.5f;
45
  static final int TEXTURE_SIZE = 100;
46 a10ada2a Leszek Koltunski
  final float[] LEGAL_QUATS;
47 27a70eae Leszek Koltunski
48 f16ff19d Leszek Koltunski
  private static final int POST_ROTATION_MILLISEC = 500;
49 a10ada2a Leszek Koltunski
  private final int NUM_CUBITS;
50
  private final int[][] CUBIT_POSITIONS;
51 3c4a326c Leszek Koltunski
  private int mRotRow;
52
  private Static3D mRotAxis;
53 27a70eae Leszek Koltunski
  private Static3D mMove, mScale, mNodeMove, mNodeScale;
54
  private Static4D mQuatAccumulated;
55
  private DistortedTexture mNodeTexture;
56
57 a10ada2a Leszek Koltunski
  int mSize;
58 fdec60a3 Leszek Koltunski
59 27a70eae Leszek Koltunski
  Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
60
  DistortedTexture mTexture;
61
62
  VertexEffectSink mSinkEffect;
63
  MatrixEffectMove mMoveEffect;
64
  MatrixEffectScale mScaleEffect;
65
  MatrixEffectQuaternion mQuatCEffect;
66
  MatrixEffectQuaternion mQuatAEffect;
67
68 a10ada2a Leszek Koltunski
  private Cubit[] mCubits;
69
70 27a70eae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
71 fdec60a3 Leszek Koltunski
72 97c012ae Leszek Koltunski
  RubikObject(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects)
73 fdec60a3 Leszek Koltunski
    {
74 27a70eae Leszek Koltunski
    super(texture,effects,mesh);
75 fdec60a3 Leszek Koltunski
76 f16ff19d Leszek Koltunski
    LEGAL_QUATS = getLegalQuats();
77 a10ada2a Leszek Koltunski
    NUM_CUBITS  = getNumCubits(size);
78
    CUBIT_POSITIONS = getCubitPositions(size);
79
80 27a70eae Leszek Koltunski
    mNodeTexture = texture;
81
    mSize = size;
82
83
    mRotationAngleStatic = new Static1D(0);
84
    mRotationAngleMiddle = new Static1D(0);
85
    mRotationAngleFinal  = new Static1D(0);
86
87
    mMove     = new Static3D(0,0,0);
88
    mScale    = new Static3D(1,1,1);
89
    mNodeMove = new Static3D(0,0,0);
90
    mNodeScale= new Static3D(1,1,1);
91
92
    mQuatAccumulated = quatAcc;
93
94
    Static3D sinkCenter = new Static3D(TEXTURE_SIZE*0.5f, TEXTURE_SIZE*0.5f, TEXTURE_SIZE*0.5f);
95
    Static3D matrCenter = new Static3D(0,0,0);
96
    Static4D region = new Static4D(0,0,0, TEXTURE_SIZE*0.72f);
97
98
    mSinkEffect = new VertexEffectSink( new Static1D(getSinkStrength()), sinkCenter, region );
99
    mMoveEffect = new MatrixEffectMove(mMove);
100
    mScaleEffect = new MatrixEffectScale(mScale);
101
    mQuatCEffect = new MatrixEffectQuaternion(quatCur, matrCenter);
102
    mQuatAEffect = new MatrixEffectQuaternion(quatAcc, matrCenter);
103
104
    MatrixEffectMove  nodeMoveEffect  = new MatrixEffectMove(mNodeMove);
105
    MatrixEffectScale nodeScaleEffect = new MatrixEffectScale(mNodeScale);
106
107
    effects.apply(nodeScaleEffect);
108
    effects.apply(nodeMoveEffect);
109 a10ada2a Leszek Koltunski
110
111
    mCubits = new Cubit[NUM_CUBITS];
112
113
    mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
114
115
    int vertices = (int)(24.0f/mSize + 2.0f);
116
117
    for(int i=0; i<NUM_CUBITS; i++)
118
      {
119
      int x = CUBIT_POSITIONS[i][0];
120
      int y = CUBIT_POSITIONS[i][1];
121
      int z = CUBIT_POSITIONS[i][2];
122
123
      mCubits[i] = new Cubit( this ,createMesh(vertices,x,y,z), new Static3D(x,y,z) );
124
      attach(mCubits[i].mNode);
125
      }
126 27a70eae Leszek Koltunski
    }
127
128 f16ff19d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
129
130 a10ada2a Leszek Koltunski
  private void resetRotationAngle(Dynamic1D rotationAngle)
131 f16ff19d Leszek Koltunski
    {
132
    rotationAngle.setDuration(POST_ROTATION_MILLISEC);
133
    rotationAngle.resetToBeginning();
134
    rotationAngle.removeAll();
135
    rotationAngle.add(mRotationAngleStatic);
136
    rotationAngle.add(mRotationAngleMiddle);
137
    rotationAngle.add(mRotationAngleFinal);
138
    }
139
140 fdec60a3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
141
142 27a70eae Leszek Koltunski
  private float getSinkStrength()
143 dd73fdab Leszek Koltunski
    {
144 27a70eae Leszek Koltunski
    switch(mSize)
145
      {
146
      case 1 : return 1.1f;
147
      case 2 : return 1.5f;
148
      case 3 : return 1.8f;
149
      case 4 : return 2.0f;
150
      default: return 3.0f - 4.0f/mSize;
151
      }
152 dd73fdab Leszek Koltunski
    }
153
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
156 27a70eae Leszek Koltunski
  public int getSize()
157 fdec60a3 Leszek Koltunski
    {
158 27a70eae Leszek Koltunski
    return mSize;
159 fdec60a3 Leszek Koltunski
    }
160
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162
163 27a70eae Leszek Koltunski
  public void continueRotation(float angleInDegrees)
164 fdec60a3 Leszek Koltunski
    {
165 27a70eae Leszek Koltunski
    mRotationAngleStatic.set0(angleInDegrees);
166 fdec60a3 Leszek Koltunski
    }
167
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169
170 27a70eae Leszek Koltunski
  public Static4D getRotationQuat()
171
      {
172
      return mQuatAccumulated;
173
      }
174
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176
177
  public void recomputeScaleFactor(int screenWidth, int screenHeight)
178 fdec60a3 Leszek Koltunski
    {
179 27a70eae Leszek Koltunski
    int texW = mNodeTexture.getWidth();
180
    int texH = mNodeTexture.getHeight();
181
182
    if( (float)texH/texW > (float)screenHeight/screenWidth )
183
      {
184
      int w = (screenHeight*texW)/texH;
185
      float factor = (float)screenHeight/texH;
186
      mNodeMove.set((screenWidth-w)*0.5f ,0, 0);
187
      mNodeScale.set(factor,factor,factor);
188
      }
189
    else
190
      {
191
      int h = (screenWidth*texH)/texW;
192
      float factor = (float)screenWidth/texW;
193
      mNodeMove.set(0,(screenHeight-h)*0.5f,0);
194
      mNodeScale.set(factor,factor,factor);
195
      }
196
197
    float scaleFactor = (OBJECT_SCREEN_RATIO*texW/(TEXTURE_SIZE*mSize));
198
199
    mMove.set( texW*0.5f , texH*0.5f , 0.0f );
200
    mScale.set(scaleFactor,scaleFactor,scaleFactor);
201 fdec60a3 Leszek Koltunski
    }
202 27a70eae Leszek Koltunski
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
205 a10ada2a Leszek Koltunski
  public void savePreferences(SharedPreferences.Editor editor)
206
    {
207
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].savePreferences(editor);
208
    }
209 f16ff19d Leszek Koltunski
210 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
211 27a70eae Leszek Koltunski
212 a10ada2a Leszek Koltunski
  public void restorePreferences(SharedPreferences preferences)
213
    {
214
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].restorePreferences(preferences);
215
    }
216 27a70eae Leszek Koltunski
217 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
218 74686c71 Leszek Koltunski
219 a10ada2a Leszek Koltunski
  public long finishRotationNow(EffectListener listener)
220
    {
221
    boolean first = true;
222
    long effectID=0;
223
224
    for(int i=0; i<NUM_CUBITS; i++)
225
      {
226
      if( belongsToRotation(mCubits[i].mCurrentPosition,mRotAxis,mRotRow) )
227
        {
228
        if( first )
229
          {
230
          first=false;
231
          effectID = mCubits[i].finishRotationNow(listener);
232
          }
233
        resetRotationAngle(mCubits[i].mRotationAngle);
234
        }
235
      }
236
237
    return effectID;
238
    }
239
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241
242
  public void releaseResources()
243
    {
244
    mTexture.markForDeletion();
245
246
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].releaseResources();
247
    }
248
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250
251
  public void apply(Effect effect, int position)
252
    {
253
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].mEffect.apply(effect, position);
254
    }
255
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257
258
  public void remove(long effectID)
259
    {
260
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].mEffect.abortById(effectID);
261
    }
262 74686c71 Leszek Koltunski
263 a10ada2a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
264
265
  public void solve()
266
    {
267
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].solve();
268
    }
269
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271
272
  public boolean isSolved()
273
    {
274
    Static4D q = mCubits[0].mQuatScramble;
275
276
    float x = q.get0();
277
    float y = q.get1();
278
    float z = q.get2();
279
    float w = q.get3();
280
281
    for(int i=0; i<NUM_CUBITS; i++)
282
      {
283
      q = mCubits[i].mQuatScramble;
284
285
      if( q.get0()!=x || q.get1()!=y || q.get2()!=z || q.get3()!=w ) return false;
286
      }
287
288
    return true;
289
    }
290
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292
293 3c4a326c Leszek Koltunski
  public void beginNewRotation(Static3D axis, int row )
294 a10ada2a Leszek Koltunski
    {
295 3c4a326c Leszek Koltunski
    mRotAxis = axis;
296 a10ada2a Leszek Koltunski
    mRotRow  = row;
297
298
    mRotationAngleStatic.set0(0.0f);
299
300
    for(int i=0; i<NUM_CUBITS; i++)
301 3c4a326c Leszek Koltunski
      if( belongsToRotation( mCubits[i].mCurrentPosition,axis,mRotRow) )
302 a10ada2a Leszek Koltunski
        {
303
        mCubits[i].beginNewRotation(axis);
304
        }
305
     }
306
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308
309 3c4a326c Leszek Koltunski
  public long addNewRotation( Static3D axis, int row, int angle, long durationMillis, EffectListener listener )
310 a10ada2a Leszek Koltunski
     {
311
     long effectID=0;
312
     boolean first = true;
313
314 3c4a326c Leszek Koltunski
     mRotAxis = axis;
315 a10ada2a Leszek Koltunski
     mRotRow  = row;
316
317
     mRotationAngleStatic.set0(0.0f);
318
319
     for(int i=0; i<NUM_CUBITS; i++)
320 3c4a326c Leszek Koltunski
       if( belongsToRotation(mCubits[i].mCurrentPosition,axis,mRotRow) )
321 a10ada2a Leszek Koltunski
         {
322
         mCubits[i].addNewRotation(axis,durationMillis,angle);
323
324
         if( first )
325
           {
326
           first = false;
327
           effectID = mCubits[i].setUpCallback(listener);
328
           }
329
         }
330
331
     return effectID;
332
     }
333
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335
336
  public void removeRotationNow()
337
     {
338
     boolean first = true;
339
     Static4D quat = null;
340
341
     for(int i=0; i<NUM_CUBITS; i++)
342
       if( belongsToRotation(mCubits[i].mCurrentPosition,mRotAxis,mRotRow) )
343
         {
344
         if( first )
345
           {
346
           first = false;
347 3c4a326c Leszek Koltunski
           quat = mCubits[i].returnRotationQuat(mRotAxis);
348 a10ada2a Leszek Koltunski
           }
349
350
         mCubits[i].removeRotationNow(quat);
351
         }
352
353
     mRotationAngleStatic.set0(0);
354
     }
355
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357
358
  abstract int getNumCubits(int size);
359
  abstract int[][] getCubitPositions(int size);
360
  abstract float[] getLegalQuats();
361 3c4a326c Leszek Koltunski
  abstract boolean belongsToRotation(Static3D position, Static3D axis, int row);
362 a10ada2a Leszek Koltunski
  abstract MeshCubes createMesh(int vertices,int x, int y, int z);
363
364
  public abstract void createTexture();
365 fdec60a3 Leszek Koltunski
  }