Project

General

Profile

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

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

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