Project

General

Profile

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

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

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 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 f16ff19d Leszek Koltunski
import org.distorted.magic.RubikSurfaceView;
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
47 f16ff19d Leszek Koltunski
  private static final int POST_ROTATION_MILLISEC = 500;
48
  private final float[] LEGAL_QUATS;
49
50 27a70eae Leszek Koltunski
  private Static3D mMove, mScale, mNodeMove, mNodeScale;
51
  private Static4D mQuatAccumulated;
52
  private DistortedTexture mNodeTexture;
53
54
  int mSize, mRotAxis, mRotRow;
55 fdec60a3 Leszek Koltunski
56 27a70eae Leszek Koltunski
  Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
57
  DistortedTexture mTexture;
58
59
  VertexEffectSink mSinkEffect;
60
  MatrixEffectMove mMoveEffect;
61
  MatrixEffectScale mScaleEffect;
62
  MatrixEffectQuaternion mQuatCEffect;
63
  MatrixEffectQuaternion mQuatAEffect;
64
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66 fdec60a3 Leszek Koltunski
67 97c012ae Leszek Koltunski
  RubikObject(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects)
68 fdec60a3 Leszek Koltunski
    {
69 27a70eae Leszek Koltunski
    super(texture,effects,mesh);
70 fdec60a3 Leszek Koltunski
71 f16ff19d Leszek Koltunski
    LEGAL_QUATS = getLegalQuats();
72 27a70eae Leszek Koltunski
    mNodeTexture = texture;
73
    mSize = size;
74
75
    mRotationAngleStatic = new Static1D(0);
76
    mRotationAngleMiddle = new Static1D(0);
77
    mRotationAngleFinal  = new Static1D(0);
78
79
    mMove     = new Static3D(0,0,0);
80
    mScale    = new Static3D(1,1,1);
81
    mNodeMove = new Static3D(0,0,0);
82
    mNodeScale= new Static3D(1,1,1);
83
84
    mQuatAccumulated = quatAcc;
85
86
    Static3D sinkCenter = new Static3D(TEXTURE_SIZE*0.5f, TEXTURE_SIZE*0.5f, TEXTURE_SIZE*0.5f);
87
    Static3D matrCenter = new Static3D(0,0,0);
88
    Static4D region = new Static4D(0,0,0, TEXTURE_SIZE*0.72f);
89
90
    mSinkEffect = new VertexEffectSink( new Static1D(getSinkStrength()), sinkCenter, region );
91
    mMoveEffect = new MatrixEffectMove(mMove);
92
    mScaleEffect = new MatrixEffectScale(mScale);
93
    mQuatCEffect = new MatrixEffectQuaternion(quatCur, matrCenter);
94
    mQuatAEffect = new MatrixEffectQuaternion(quatAcc, matrCenter);
95
96
    MatrixEffectMove  nodeMoveEffect  = new MatrixEffectMove(mNodeMove);
97
    MatrixEffectScale nodeScaleEffect = new MatrixEffectScale(mNodeScale);
98
99
    effects.apply(nodeScaleEffect);
100
    effects.apply(nodeMoveEffect);
101
    }
102
103 f16ff19d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
104
// Because of quatMultiplication, errors can accumulate - so to avoid this, we
105
// correct the value of the 'scramble' quat to what it should be - one of the legal quats from the
106
// list LEGAL_QUATS.
107
//
108
// We also have to remember that the group of unit quaternions is a double-cover of rotations
109
// in 3D ( q represents the same rotation as -q ) - so invert if needed.
110
111
    void normalizeScrambleQuat(Static4D quat)
112
      {
113
      float x = quat.get0();
114
      float y = quat.get1();
115
      float z = quat.get2();
116
      float w = quat.get3();
117
      float diff;
118
119
      for(float legal: LEGAL_QUATS)
120
        {
121
        diff = x-legal;
122
        if( diff*diff<0.01f ) x = legal;
123
        diff = y-legal;
124
        if( diff*diff<0.01f ) y = legal;
125
        diff = z-legal;
126
        if( diff*diff<0.01f ) z = legal;
127
        diff = w-legal;
128
        if( diff*diff<0.01f ) w = legal;
129
        }
130
131
      if( w<0 )
132
        {
133
        w = -w;
134
        z = -z;
135
        y = -y;
136
        x = -x;
137
        }
138
      else if( w==0 )
139
        {
140
        if( z<0 )
141
          {
142
          z = -z;
143
          y = -y;
144
          x = -x;
145
          }
146
        else if( z==0 )
147
          {
148
          if( y<0 )
149
            {
150
            y = -y;
151
            x = -x;
152
            }
153
          else if( y==0 )
154
            {
155
            if( x<0 )
156
              {
157
              x = -x;
158
              }
159
            }
160
          }
161
        }
162
163
      quat.set(x,y,z,w);
164
      }
165
166 27a70eae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
167
168
  int computeNearestAngle(float angle)
169
    {
170
    final int NEAREST = 90;
171
172
    int tmp = (int)((angle+NEAREST/2)/NEAREST);
173
    if( angle< -(NEAREST*0.5) ) tmp-=1;
174
175
    return NEAREST*tmp;
176 fdec60a3 Leszek Koltunski
    }
177
178 f16ff19d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
179
180
  void resetRotationAngle(Dynamic1D rotationAngle)
181
    {
182
    rotationAngle.setDuration(POST_ROTATION_MILLISEC);
183
    rotationAngle.resetToBeginning();
184
    rotationAngle.removeAll();
185
    rotationAngle.add(mRotationAngleStatic);
186
    rotationAngle.add(mRotationAngleMiddle);
187
    rotationAngle.add(mRotationAngleFinal);
188
    }
189
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191
192
  void modifyCurrentPosition(Static3D currentPosition, Static4D quat)
193
    {
194
    float diff = 0.5f*(mSize-1);
195
    float cubitCenterX = currentPosition.get0() - diff;
196
    float cubitCenterY = currentPosition.get1() - diff;
197
    float cubitCenterZ = currentPosition.get2() - diff;
198
199
    Static4D cubitCenter =  new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
200
    Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
201
202
    float rotatedX = rotatedCenter.get0() + diff;
203
    float rotatedY = rotatedCenter.get1() + diff;
204
    float rotatedZ = rotatedCenter.get2() + diff;
205
206
    int roundedX = (int)(rotatedX+0.1f);
207
    int roundedY = (int)(rotatedY+0.1f);
208
    int roundedZ = (int)(rotatedZ+0.1f);
209
210
    currentPosition.set(roundedX, roundedY, roundedZ);
211
    }
212
213 fdec60a3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
214
215 27a70eae Leszek Koltunski
  private float getSinkStrength()
216 dd73fdab Leszek Koltunski
    {
217 27a70eae Leszek Koltunski
    switch(mSize)
218
      {
219
      case 1 : return 1.1f;
220
      case 2 : return 1.5f;
221
      case 3 : return 1.8f;
222
      case 4 : return 2.0f;
223
      default: return 3.0f - 4.0f/mSize;
224
      }
225 dd73fdab Leszek Koltunski
    }
226
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228
229 27a70eae Leszek Koltunski
  public int getSize()
230 fdec60a3 Leszek Koltunski
    {
231 27a70eae Leszek Koltunski
    return mSize;
232 fdec60a3 Leszek Koltunski
    }
233
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235
236 27a70eae Leszek Koltunski
  public void continueRotation(float angleInDegrees)
237 fdec60a3 Leszek Koltunski
    {
238 27a70eae Leszek Koltunski
    mRotationAngleStatic.set0(angleInDegrees);
239 fdec60a3 Leszek Koltunski
    }
240
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242
243 27a70eae Leszek Koltunski
  public Static4D getRotationQuat()
244
      {
245
      return mQuatAccumulated;
246
      }
247
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249
250
  public void recomputeScaleFactor(int screenWidth, int screenHeight)
251 fdec60a3 Leszek Koltunski
    {
252 27a70eae Leszek Koltunski
    int texW = mNodeTexture.getWidth();
253
    int texH = mNodeTexture.getHeight();
254
255
    if( (float)texH/texW > (float)screenHeight/screenWidth )
256
      {
257
      int w = (screenHeight*texW)/texH;
258
      float factor = (float)screenHeight/texH;
259
      mNodeMove.set((screenWidth-w)*0.5f ,0, 0);
260
      mNodeScale.set(factor,factor,factor);
261
      }
262
    else
263
      {
264
      int h = (screenWidth*texH)/texW;
265
      float factor = (float)screenWidth/texW;
266
      mNodeMove.set(0,(screenHeight-h)*0.5f,0);
267
      mNodeScale.set(factor,factor,factor);
268
      }
269
270
    float scaleFactor = (OBJECT_SCREEN_RATIO*texW/(TEXTURE_SIZE*mSize));
271
272
    mMove.set( texW*0.5f , texH*0.5f , 0.0f );
273
    mScale.set(scaleFactor,scaleFactor,scaleFactor);
274 fdec60a3 Leszek Koltunski
    }
275 27a70eae Leszek Koltunski
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277
278 f16ff19d Leszek Koltunski
  abstract float[] getLegalQuats();
279
280 27a70eae Leszek Koltunski
  public abstract void savePreferences(SharedPreferences.Editor editor);
281
  public abstract void restorePreferences(SharedPreferences preferences);
282
283
  public abstract void beginNewRotation(int vector, int row );
284
  public abstract long addNewRotation(int vector, int row, int angle, long durationMillis, EffectListener listener );
285
  public abstract long finishRotationNow(EffectListener listener);
286
  public abstract void removeRotationNow();
287
288
  public abstract void apply(Effect effect, int position);
289
  public abstract void remove(long effectID);
290 74686c71 Leszek Koltunski
291
  public abstract void releaseResources();
292
  public abstract void createTexture();
293
294 27a70eae Leszek Koltunski
  public abstract void solve();
295
  public abstract boolean isSolved();
296 fdec60a3 Leszek Koltunski
  }