Project

General

Profile

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

magiccube / src / main / java / org / distorted / object / RubikObject.java @ 36273130

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