Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
package org.distorted.object;
21

    
22
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
import org.distorted.library.mesh.MeshBase;
32
import org.distorted.library.mesh.MeshRectangles;
33
import org.distorted.library.message.EffectListener;
34
import org.distorted.library.type.Dynamic1D;
35
import org.distorted.library.type.Static1D;
36
import org.distorted.library.type.Static3D;
37
import org.distorted.library.type.Static4D;
38

    
39
import static org.distorted.magic.RubikRenderer.NODE_FBO_SIZE;
40

    
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

    
43
public abstract class RubikObject extends DistortedNode
44
  {
45
  static final float OBJECT_SCREEN_RATIO = 0.5f;
46
  final float[] LEGAL_QUATS;
47

    
48
  private static final int POST_ROTATION_MILLISEC = 500;
49
  private final int NUM_CUBITS;
50
  private int mRotRow;
51
  private Static3D mRotAxis;
52
  private Static3D mScale, mNodeScale;
53
  private Static4D mQuatAccumulated;
54
  private Cubit[] mCubits;
55

    
56
  int mSize;
57

    
58
  Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
59
  DistortedTexture mTexture;
60

    
61
  VertexEffectSink mSinkEffect;
62
  MatrixEffectScale mScaleEffect;
63
  MatrixEffectQuaternion mQuatCEffect;
64
  MatrixEffectQuaternion mQuatAEffect;
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  RubikObject(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects)
69
    {
70
    super(texture,effects,mesh);
71

    
72
    resizeFBO(NODE_FBO_SIZE, NODE_FBO_SIZE);
73

    
74
    LEGAL_QUATS = getLegalQuats();
75
    NUM_CUBITS  = getNumCubits(size);
76

    
77
    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
    Static3D center = new Static3D(0,0,0);
89
    Static4D region = new Static4D(0,0,0,0.72f);
90

    
91
    mSinkEffect = new VertexEffectSink( new Static1D(getSinkStrength()), center, region );
92
    mScaleEffect = new MatrixEffectScale(mScale);
93
    mQuatCEffect = new MatrixEffectQuaternion(quatCur, center);
94
    mQuatAEffect = new MatrixEffectQuaternion(quatAcc, center);
95

    
96
    MatrixEffectScale nodeScaleEffect = new MatrixEffectScale(mNodeScale);
97
    effects.apply(nodeScaleEffect);
98

    
99
    mCubits = new Cubit[NUM_CUBITS];
100
    mTexture = new DistortedTexture();
101

    
102
    int vertices = (int)(24.0f/mSize + 2.0f);
103
    int[][] positions = getCubitPositions(size);
104

    
105
    for(int i=0; i<NUM_CUBITS; i++)
106
      {
107
      int x = positions[i][0];
108
      int y = positions[i][1];
109
      int z = positions[i][2];
110

    
111
      mCubits[i] = new Cubit( this ,createCubitMesh(vertices,x,y,z), new Static3D(x,y,z) );
112
      attach(mCubits[i].mNode);
113
      }
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
  private void resetRotationAngle(Dynamic1D rotationAngle)
119
    {
120
    rotationAngle.setDuration(POST_ROTATION_MILLISEC);
121
    rotationAngle.resetToBeginning();
122
    rotationAngle.removeAll();
123
    rotationAngle.add(mRotationAngleStatic);
124
    rotationAngle.add(mRotationAngleMiddle);
125
    rotationAngle.add(mRotationAngleFinal);
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  private float getSinkStrength()
131
    {
132
    switch(mSize)
133
      {
134
      case 1 : return 1.1f;
135
      case 2 : return 1.5f;
136
      case 3 : return 1.8f;
137
      case 4 : return 2.0f;
138
      default: return 3.0f - 4.0f/mSize;
139
      }
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

    
144
  public int getSize()
145
    {
146
    return mSize;
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  public void continueRotation(float angleInDegrees)
152
    {
153
    mRotationAngleStatic.set0(angleInDegrees);
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

    
158
  public Static4D getRotationQuat()
159
      {
160
      return mQuatAccumulated;
161
      }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  public void recomputeScaleFactor(int scrWidth, int scrHeight)
166
    {
167
    float factor = scrWidth>scrHeight ? scrHeight : scrWidth;
168
    float scaleFactor = OBJECT_SCREEN_RATIO*NODE_FBO_SIZE/mSize;
169

    
170
    mNodeScale.set(factor,factor,factor);
171
    mScale.set(scaleFactor,scaleFactor,scaleFactor);
172
    }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

    
176
  public void savePreferences(SharedPreferences.Editor editor)
177
    {
178
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].savePreferences(editor);
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

    
183
  public void restorePreferences(SharedPreferences preferences)
184
    {
185
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].restorePreferences(preferences);
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

    
190
  public long finishRotationNow(EffectListener listener)
191
    {
192
    boolean first = true;
193
    long effectID=0;
194

    
195
    for(int i=0; i<NUM_CUBITS; i++)
196
      {
197
      if( belongsToRotation(mCubits[i].mCurrentPosition,mRotAxis,mRotRow) )
198
        {
199
        if( first )
200
          {
201
          first=false;
202
          effectID = mCubits[i].finishRotationNow(listener);
203
          }
204
        resetRotationAngle(mCubits[i].mRotationAngle);
205
        }
206
      }
207

    
208
    return effectID;
209
    }
210

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

    
213
  public void releaseResources()
214
    {
215
    mTexture.markForDeletion();
216

    
217
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].releaseResources();
218
    }
219

    
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221

    
222
  public void apply(Effect effect, int position)
223
    {
224
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].mEffect.apply(effect, position);
225
    }
226

    
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

    
229
  public void remove(long effectID)
230
    {
231
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].mEffect.abortById(effectID);
232
    }
233

    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

    
236
  public void solve()
237
    {
238
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].solve();
239
    }
240

    
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242

    
243
  public boolean isSolved()
244
    {
245
    Static4D q = mCubits[0].mQuatScramble;
246

    
247
    float x = q.get0();
248
    float y = q.get1();
249
    float z = q.get2();
250
    float w = q.get3();
251

    
252
    for(int i=0; i<NUM_CUBITS; i++)
253
      {
254
      q = mCubits[i].mQuatScramble;
255

    
256
      if( q.get0()!=x || q.get1()!=y || q.get2()!=z || q.get3()!=w ) return false;
257
      }
258

    
259
    return true;
260
    }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263

    
264
  public void beginNewRotation(Static3D axis, int row )
265
    {
266
    mRotAxis = axis;
267
    mRotRow  = row;
268

    
269
    mRotationAngleStatic.set0(0.0f);
270

    
271
    for(int i=0; i<NUM_CUBITS; i++)
272
      if( belongsToRotation( mCubits[i].mCurrentPosition,axis,mRotRow) )
273
        {
274
        mCubits[i].beginNewRotation(axis);
275
        }
276
     }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  public long addNewRotation( Static3D axis, int row, int angle, long durationMillis, EffectListener listener )
281
     {
282
     long effectID=0;
283
     boolean first = true;
284

    
285
     mRotAxis = axis;
286
     mRotRow  = row;
287

    
288
     mRotationAngleStatic.set0(0.0f);
289

    
290
     for(int i=0; i<NUM_CUBITS; i++)
291
       if( belongsToRotation(mCubits[i].mCurrentPosition,axis,mRotRow) )
292
         {
293
         mCubits[i].addNewRotation(axis,durationMillis,angle);
294

    
295
         if( first )
296
           {
297
           first = false;
298
           effectID = mCubits[i].setUpCallback(listener);
299
           }
300
         }
301

    
302
     return effectID;
303
     }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

    
307
  public void removeRotationNow()
308
     {
309
     boolean first = true;
310
     Static4D quat = null;
311

    
312
     for(int i=0; i<NUM_CUBITS; i++)
313
       if( belongsToRotation(mCubits[i].mCurrentPosition,mRotAxis,mRotRow) )
314
         {
315
         if( first )
316
           {
317
           first = false;
318
           quat = mCubits[i].returnRotationQuat(mRotAxis);
319
           }
320

    
321
         mCubits[i].removeRotationNow(quat);
322
         }
323

    
324
     mRotationAngleStatic.set0(0);
325
     }
326

    
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

    
329
  abstract int getNumCubits(int size);
330
  abstract int[][] getCubitPositions(int size);
331
  abstract float[] getLegalQuats();
332
  abstract boolean belongsToRotation(Static3D position, Static3D axis, int row);
333
  abstract MeshBase createCubitMesh(int vertices, int x, int y, int z);
334

    
335
  public abstract void createTexture();
336
  }
(4-4/6)