Project

General

Profile

« Previous | Next » 

Revision 70b76549

Added by Leszek Koltunski over 4 years ago

More work on Cubit.

View differences:

src/main/java/org/distorted/object/Cubit.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 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.MatrixEffectMove;
25
import org.distorted.library.effect.MatrixEffectQuaternion;
26
import org.distorted.library.effect.MatrixEffectRotate;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedNode;
29
import org.distorted.library.mesh.MeshCubes;
30
import org.distorted.library.message.EffectListener;
31
import org.distorted.library.type.Dynamic1D;
32
import org.distorted.library.type.Static1D;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35
import org.distorted.magic.RubikSurfaceView;
36

  
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

  
39
class Cubit
40
  {
41
  private static final Static3D matrCenter = new Static3D(0,0,0);
42

  
43
  private final Static3D mOrigPosition;
44

  
45
  private RubikObject mParent;
46
  private MeshCubes mCube;
47
  private Static3D mRotationAxis;
48
  private MatrixEffectRotate mRotateEffect;
49

  
50
  Dynamic1D mRotationAngle;
51
  Static3D mCurrentPosition;
52
  DistortedNode mNode;
53
  DistortedEffects mEffect;
54
  Static4D mQuatScramble;
55

  
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57
// Because of quatMultiplication, errors can accumulate - so to avoid this, we
58
// correct the value of the 'scramble' quat to what it should be - one of the legal quats from the
59
// list LEGAL_QUATS.
60
//
61
// We also have to remember that the group of unit quaternions is a double-cover of rotations
62
// in 3D ( q represents the same rotation as -q ) - so invert if needed.
63

  
64
  private void normalizeScrambleQuat(Static4D quat)
65
    {
66
    float x = quat.get0();
67
    float y = quat.get1();
68
    float z = quat.get2();
69
    float w = quat.get3();
70
    float diff;
71

  
72
    for(float legal: mParent.LEGAL_QUATS)
73
      {
74
      diff = x-legal;
75
      if( diff*diff<0.01f ) x = legal;
76
      diff = y-legal;
77
      if( diff*diff<0.01f ) y = legal;
78
      diff = z-legal;
79
      if( diff*diff<0.01f ) z = legal;
80
      diff = w-legal;
81
      if( diff*diff<0.01f ) w = legal;
82
      }
83

  
84
    if( w<0 )
85
      {
86
      w = -w;
87
      z = -z;
88
      y = -y;
89
      x = -x;
90
      }
91
    else if( w==0 )
92
      {
93
      if( z<0 )
94
        {
95
        z = -z;
96
        y = -y;
97
        x = -x;
98
        }
99
      else if( z==0 )
100
        {
101
        if( y<0 )
102
          {
103
          y = -y;
104
          x = -x;
105
          }
106
        else if( y==0 )
107
          {
108
          if( x<0 )
109
            {
110
            x = -x;
111
            }
112
          }
113
        }
114
      }
115

  
116
    quat.set(x,y,z,w);
117
    }
118

  
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

  
121
  private int computeNearestAngle(float angle)
122
    {
123
    final int NEAREST = 90;
124

  
125
    int tmp = (int)((angle+NEAREST/2)/NEAREST);
126
    if( angle< -(NEAREST*0.5) ) tmp-=1;
127

  
128
    return NEAREST*tmp;
129
    }
130

  
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

  
133
  private void modifyCurrentPosition(Static3D currentPosition, Static4D quat)
134
    {
135
    float diff = 0.5f*(mParent.mSize-1);
136
    float cubitCenterX = currentPosition.get0() - diff;
137
    float cubitCenterY = currentPosition.get1() - diff;
138
    float cubitCenterZ = currentPosition.get2() - diff;
139

  
140
    Static4D cubitCenter =  new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
141
    Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
142

  
143
    float rotatedX = rotatedCenter.get0() + diff;
144
    float rotatedY = rotatedCenter.get1() + diff;
145
    float rotatedZ = rotatedCenter.get2() + diff;
146

  
147
    int roundedX = (int)(rotatedX+0.1f);
148
    int roundedY = (int)(rotatedY+0.1f);
149
    int roundedZ = (int)(rotatedZ+0.1f);
150

  
151
    currentPosition.set(roundedX, roundedY, roundedZ);
152
    }
153

  
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

  
156
  Cubit(RubikObject parent, MeshCubes mesh, Static3D position)
157
    {
158
    float x = position.get0();
159
    float y = position.get1();
160
    float z = position.get2();
161

  
162
    float nc = mParent.mSize*0.5f;
163
    int TS = RubikObject.TEXTURE_SIZE;
164
    Static3D vector = new Static3D(TS*(x-nc), TS*(y-nc), TS*(z-nc));
165

  
166
    mParent          = parent;
167
    mCube            = mesh;
168
    mOrigPosition    = new Static3D(x,y,z);
169
    mQuatScramble    = new Static4D(0,0,0,1);
170
    mRotationAngle   = new Dynamic1D();
171
    mRotationAxis    = new Static3D(1,0,0);
172
    mCurrentPosition = position;
173
    mRotateEffect    = new MatrixEffectRotate(mRotationAngle, mRotationAxis, matrCenter);
174

  
175
    mEffect = new DistortedEffects();
176
    mEffect.apply(mParent.mSinkEffect);
177
    mEffect.apply( new MatrixEffectMove(vector) );
178
    mEffect.apply( new MatrixEffectQuaternion(mQuatScramble, matrCenter));
179
    mEffect.apply(mRotateEffect);
180
    mEffect.apply(mParent.mQuatAEffect);
181
    mEffect.apply(mParent.mQuatCEffect);
182
    mEffect.apply(mParent.mScaleEffect);
183
    mEffect.apply(mParent.mMoveEffect);
184

  
185
    mNode = new DistortedNode(mParent.mTexture,mEffect,mCube);
186
    }
187

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

  
190
  void savePreferences(SharedPreferences.Editor editor)
191
    {
192
    String number = mOrigPosition.get0()+"_"+mOrigPosition.get1()+"_"+mOrigPosition.get2();
193

  
194
    editor.putFloat("qx_"+number, mQuatScramble.get0());
195
    editor.putFloat("qy_"+number, mQuatScramble.get1());
196
    editor.putFloat("qz_"+number, mQuatScramble.get2());
197
    editor.putFloat("qw_"+number, mQuatScramble.get3());
198
    }
199

  
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

  
202
  void restorePreferences(SharedPreferences preferences)
203
    {
204
    String number = mOrigPosition.get0()+"_"+mOrigPosition.get1()+"_"+mOrigPosition.get2();
205

  
206
    float qx = preferences.getFloat("qx_"+number, 0.0f);
207
    float qy = preferences.getFloat("qy_"+number, 0.0f);
208
    float qz = preferences.getFloat("qz_"+number, 0.0f);
209
    float qw = preferences.getFloat("qw_"+number, 1.0f);
210

  
211
    mQuatScramble.set(qx,qy,qz,qw);
212
    modifyCurrentPosition( mCurrentPosition, mQuatScramble);
213
    }
214

  
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

  
217
  long finishRotationNow(EffectListener listener)
218
    {
219
    int pointNum = mRotationAngle.getNumPoints();
220

  
221
    if( pointNum>=1 )
222
      {
223
      float startingAngle = mRotationAngle.getPoint(pointNum-1).get0();
224
      int nearestAngleInDegrees = computeNearestAngle(startingAngle);
225
      mParent.mRotationAngleStatic.set0(startingAngle);
226
      mParent.mRotationAngleFinal.set0(nearestAngleInDegrees);
227
      mParent.mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-startingAngle)*0.2f );
228
      return setUpCallback(listener);
229
      }
230

  
231
    return 0;
232
    }
233

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

  
236
  Static4D returnRotationQuat(float qx,float qy,float qz)
237
    {
238
    int pointNum = mRotationAngle.getNumPoints();
239

  
240
    if( pointNum>=1 )
241
      {
242
      float startingAngle = mRotationAngle.getPoint(pointNum-1).get0();
243
      int nearestAngleInDegrees = computeNearestAngle(startingAngle);
244
      double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
245
      float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
246
      float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
247
      return new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
248
      }
249

  
250
    return null;
251
    }
252

  
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

  
255
  void removeRotationNow(Static4D quat)
256
    {
257
    mRotationAngle.removeAll();
258
    mQuatScramble.set(RubikSurfaceView.quatMultiply(quat,mQuatScramble));
259
    normalizeScrambleQuat( mQuatScramble );
260
    modifyCurrentPosition( mCurrentPosition,quat);
261
    }
262

  
263
///////////////////////////////////////////////////////////////////////////////////////////////////
264
// all DistortedTextures, DistortedNodes, DistortedFramebuffers, DistortedScreens and all types of
265
// Meshes HAVE TO be markedForDeletion when they are no longer needed- otherwise we have a major
266
// memory leak.
267

  
268
  void releaseResources()
269
    {
270
    mCube.markForDeletion();
271
    mNode.markForDeletion();
272
    }
273

  
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

  
276
  void solve()
277
    {
278
    mQuatScramble.set(0,0,0,1);
279
    mCurrentPosition.set(mOrigPosition);
280
    }
281

  
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283

  
284
  void beginNewRotation(Static3D axis)
285
    {
286
    mRotationAxis.set(axis);
287
    mRotationAngle.add(mParent.mRotationAngleStatic);
288
    }
289

  
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

  
292
  void addNewRotation(Static3D axis, long durationMillis, int angle)
293
    {
294
    mRotationAxis.set(axis);
295
    mRotationAngle.setDuration(durationMillis);
296
    mRotationAngle.resetToBeginning();
297
    mRotationAngle.add(new Static1D(0));
298
    mRotationAngle.add(new Static1D(angle));
299
    }
300

  
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

  
303
  long setUpCallback(EffectListener listener)
304
    {
305
    mRotateEffect.notifyWhenFinished(listener);
306
    return mRotateEffect.getID();
307
    }
308
}
src/main/java/org/distorted/object/RubikCube.java
25 25
import android.graphics.Paint;
26 26

  
27 27
import org.distorted.library.effect.Effect;
28
import org.distorted.library.effect.MatrixEffectMove;
29
import org.distorted.library.effect.MatrixEffectQuaternion;
30
import org.distorted.library.effect.MatrixEffectRotate;
31 28
import org.distorted.library.main.DistortedEffects;
32
import org.distorted.library.main.DistortedNode;
33 29
import org.distorted.library.main.DistortedTexture;
34 30
import org.distorted.library.mesh.MeshCubes;
35 31
import org.distorted.library.mesh.MeshRectangles;
36 32
import org.distorted.library.message.EffectListener;
37
import org.distorted.library.type.Dynamic1D;
38
import org.distorted.library.type.Static1D;
39 33
import org.distorted.library.type.Static3D;
40 34
import org.distorted.library.type.Static4D;
41
import org.distorted.magic.RubikSurfaceView;
42 35

  
43 36
import static org.distorted.object.RubikObjectList.VECTX;
44 37
import static org.distorted.object.RubikObjectList.VECTY;
......
51 44
    private static final Static3D VectX = new Static3D(1,0,0);
52 45
    private static final Static3D VectY = new Static3D(0,1,0);
53 46
    private static final Static3D VectZ = new Static3D(0,0,1);
47
    private static final Static4D mapFront, mapBack, mapLeft, mapRight, mapTop, mapBottom, mapBlack;
54 48

  
55
    private static final Static3D matrCenter = new Static3D(0,0,0);
56

  
57
    /////////////////////////////////////////////////////////////////////////////////
49
    private Cubit[][][] mCubits;
58 50

  
59
    private class Cubit
51
    static
60 52
      {
61
      private final Static3D mOrigPosition;
62

  
63
      DistortedNode mNode;
64
      MeshCubes mCube;
65
      DistortedEffects mEffect;
66
      Static4D mQuatScramble;
67
      Static3D mRotationAxis;
68
      Dynamic1D mRotationAngle;
69
      Static3D mCurrentPosition;
70

  
71
      MatrixEffectRotate mRotateEffect;
72

  
73
    /////////////////////////////////////////////////////////////////////////////////
74

  
75
      Cubit(MeshCubes mesh,Static3D vector, Static3D position)
76
        {
77
        mOrigPosition = new Static3D( position.get0(), position.get1(), position.get2() );
78

  
79
        mCube = mesh;
80
        mQuatScramble    = new Static4D(0,0,0,1);
81
        mRotationAngle   = new Dynamic1D();
82
        mRotationAxis    = new Static3D(1,0,0);
83
        mCurrentPosition = position;
84
        mRotateEffect    = new MatrixEffectRotate(mRotationAngle, mRotationAxis, matrCenter);
85

  
86
        mEffect = new DistortedEffects();
87
        mEffect.apply(mSinkEffect);
88
        mEffect.apply( new MatrixEffectMove(vector) );
89
        mEffect.apply( new MatrixEffectQuaternion(mQuatScramble, matrCenter));
90
        mEffect.apply(mRotateEffect);
91
        mEffect.apply(mQuatAEffect);
92
        mEffect.apply(mQuatCEffect);
93
        mEffect.apply(mScaleEffect);
94
        mEffect.apply(mMoveEffect);
95

  
96
        mNode = new DistortedNode(mTexture,mEffect,mCube);
97
        }
98

  
99
    /////////////////////////////////////////////////////////////////////////////////
100

  
101
      void savePreferences(SharedPreferences.Editor editor)
102
        {
103
        String number = mOrigPosition.get0()+"_"+mOrigPosition.get1()+"_"+mOrigPosition.get2();
104

  
105
        editor.putFloat("qx_"+number, mQuatScramble.get0());
106
        editor.putFloat("qy_"+number, mQuatScramble.get1());
107
        editor.putFloat("qz_"+number, mQuatScramble.get2());
108
        editor.putFloat("qw_"+number, mQuatScramble.get3());
109
        }
110

  
111
    /////////////////////////////////////////////////////////////////////////////////
112

  
113
      void restorePreferences(SharedPreferences preferences)
114
        {
115
        String number = mOrigPosition.get0()+"_"+mOrigPosition.get1()+"_"+mOrigPosition.get2();
116

  
117
        float qx = preferences.getFloat("qx_"+number, 0.0f);
118
        float qy = preferences.getFloat("qy_"+number, 0.0f);
119
        float qz = preferences.getFloat("qz_"+number, 0.0f);
120
        float qw = preferences.getFloat("qw_"+number, 1.0f);
121

  
122
        mQuatScramble.set(qx,qy,qz,qw);
123
        modifyCurrentPosition( mCurrentPosition, mQuatScramble);
124
        }
125

  
126
    /////////////////////////////////////////////////////////////////////////////////
127

  
128
      long finishRotationNow(EffectListener listener)
129
        {
130
        int pointNum = mRotationAngle.getNumPoints();
131

  
132
        if( pointNum>=1 )
133
          {
134
          float startingAngle = mRotationAngle.getPoint(pointNum-1).get0();
135
          int nearestAngleInDegrees = computeNearestAngle(startingAngle);
136
          mRotationAngleStatic.set0(startingAngle);
137
          mRotationAngleFinal.set0(nearestAngleInDegrees);
138
          mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-startingAngle)*0.2f );
139
          return setUpCallback(listener);
140
          }
141
        else
142
          {
143
          return 0;
144
          }
145
        }
146

  
147
    /////////////////////////////////////////////////////////////////////////////////
148

  
149
      Static4D returnRotationQuat(float qx,float qy,float qz)
150
        {
151
        int pointNum = mRotationAngle.getNumPoints();
152

  
153
        if( pointNum>=1 )
154
          {
155
          float startingAngle = mRotationAngle.getPoint(pointNum-1).get0();
156
          int nearestAngleInDegrees = computeNearestAngle(startingAngle);
157
          double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
158
          float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
159
          float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
160
          return new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
161
          }
162
        else
163
          {
164
          return null;
165
          }
166
        }
167

  
168
    /////////////////////////////////////////////////////////////////////////////////
169

  
170
      void removeRotationNow(Static4D quat)
171
        {
172
        mRotationAngle.removeAll();
173
        mQuatScramble.set(RubikSurfaceView.quatMultiply(quat,mQuatScramble));
174
        normalizeScrambleQuat( mQuatScramble );
175
        modifyCurrentPosition( mCurrentPosition,quat);
176
        }
177

  
178
    /////////////////////////////////////////////////////////////////////////////////
179

  
180
      void releaseResources()
181
        {
182
        mCube.markForDeletion();
183
        mNode.markForDeletion();
184
        }
185

  
186
    /////////////////////////////////////////////////////////////////////////////////
187

  
188
      void solve()
189
        {
190
        mQuatScramble.set(0,0,0,1);
191
        mCurrentPosition.set(mOrigPosition);
192
        }
193

  
194
    /////////////////////////////////////////////////////////////////////////////////
195

  
196
      void beginNewRotation(Static3D axis)
197
        {
198
        mRotationAxis.set(axis);
199
        mRotationAngle.add(mRotationAngleStatic);
200
        }
201

  
202
    /////////////////////////////////////////////////////////////////////////////////
203

  
204
      void addNewRotation(Static3D axis, long durationMillis, int angle)
205
        {
206
        mRotationAxis.set(axis);
207
        mRotationAngle.setDuration(durationMillis);
208
        mRotationAngle.resetToBeginning();
209
        mRotationAngle.add(new Static1D(0));
210
        mRotationAngle.add(new Static1D(angle));
211
        }
53
      // 3x2 bitmap = 6 squares:
54
      //
55
      // RED     GREEN   BLUE
56
      // YELLOW  WHITE   BROWN
212 57

  
58
      final float ze = 0.0f;
59
      final float ot = 1.0f/3.0f;
60
      final float tt = 2.0f/3.0f;
61
      final float oh = 1.0f/2.0f;
62
      final float of = 1.0f/40.0f;
213 63

  
214
    /////////////////////////////////////////////////////////////////////////////////
64
      mapFront = new Static4D(ze,oh, ze+ot,oh+oh);
65
      mapBack  = new Static4D(tt,ze, tt+ot,ze+oh);
66
      mapLeft  = new Static4D(ot,ze, ot+ot,ze+oh);
67
      mapRight = new Static4D(ze,ze, ze+ot,ze+oh);
68
      mapTop   = new Static4D(tt,oh, tt+ot,oh+oh);
69
      mapBottom= new Static4D(ot,oh, ot+ot,oh+oh);
215 70

  
216
      long setUpCallback(EffectListener listener)
217
        {
218
        mRotateEffect.notifyWhenFinished(listener);
219
        return mRotateEffect.getID();
220
        }
71
      mapBlack = new Static4D(ze,ze, ze+of,ze+of);
221 72
      }
222 73

  
223
    private Cubit[][][] mCubits;
224

  
225 74
///////////////////////////////////////////////////////////////////////////////////////////////////
226
// All legal rotation quats must have all four of their components equal to either
227
// 0, 1, -1, 0.5, -0.5 or +-sqrt(2)/2.
75
// All legal rotation quats of a RubikCube of any size must have all four of their components
76
// equal to either 0, 1, -1, 0.5, -0.5 or +-sqrt(2)/2.
228 77

  
229 78
    float[] getLegalQuats()
230 79
      {
......
252 101
      {
253 102
      super(size,quatCur,quatAcc,texture,mesh,effects);
254 103

  
255
      mRotAxis = VECTX;
256 104
      mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
257 105
      mCubits  = new Cubit[mSize][mSize][mSize];
258 106

  
259
      // 3x2 bitmap = 6 squares:
260
      //
261
      // RED     GREEN   BLUE
262
      // YELLOW  WHITE   BROWN
263

  
264
      final float ze = 0.0f;
265
      final float ot = 1.0f/3.0f;
266
      final float tt = 2.0f/3.0f;
267
      final float oh = 1.0f/2.0f;
268
      final float of = 1.0f/40.0f;
269

  
270
      final Static4D mapFront = new Static4D(ze,oh, ze+ot,oh+oh);
271
      final Static4D mapBack  = new Static4D(tt,ze, tt+ot,ze+oh);
272
      final Static4D mapLeft  = new Static4D(ot,ze, ot+ot,ze+oh);
273
      final Static4D mapRight = new Static4D(ze,ze, ze+ot,ze+oh);
274
      final Static4D mapTop   = new Static4D(tt,oh, tt+ot,oh+oh);
275
      final Static4D mapBottom= new Static4D(ot,oh, ot+ot,oh+oh);
276

  
277
      final Static4D mapBlack = new Static4D(ze,ze, ze+of,ze+of);
278

  
279
      Static4D tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom;
280
      float nc = 0.5f*mSize;
281 107
      int vertices = (int)(24.0f/mSize + 2.0f);
282 108

  
283 109
      for(int x = 0; x< mSize; x++)
284 110
        for(int y = 0; y< mSize; y++)
285 111
          for(int z = 0; z< mSize; z++)
286 112
            {
287
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) // only the external walls
113
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
288 114
              {
289
              tmpLeft  = (x==       0 ? mapLeft  :mapBlack);
290
              tmpRight = (x== mSize-1 ? mapRight :mapBlack);
291
              tmpFront = (z== mSize-1 ? mapFront :mapBlack);
292
              tmpBack  = (z==       0 ? mapBack  :mapBlack);
293
              tmpTop   = (y== mSize-1 ? mapTop   :mapBlack);
294
              tmpBottom= (y==       0 ? mapBottom:mapBlack);
295

  
296
              mCubits[x][y][z] = new Cubit(new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom),
297
                                           new Static3D( TEXTURE_SIZE*(x-nc), TEXTURE_SIZE*(y-nc), TEXTURE_SIZE*(z-nc) ),
298
                                           new Static3D(x,y,z) );
299

  
115
              mCubits[x][y][z] = new Cubit( this,createMesh(vertices,x,y,z),new Static3D(x,y,z) );
300 116
              attach(mCubits[x][y][z].mNode);
301 117
              }
302 118
            }
......
359 175
     }
360 176

  
361 177
///////////////////////////////////////////////////////////////////////////////////////////////////
362
// all DistortedTextures, DistortedNodes, DistortedFramebuffers, DistortedScreens and all types of
363
// Meshes HAVE TO be markedForDeletion when they are no longer needed- otherwise we have a major
364
// memory leak.
365 178

  
366 179
   public void releaseResources()
367 180
     {
......
378 191
           }
379 192
     }
380 193

  
381
///////////////////////////////////////////////////////////////////////////////////////////////////
382

  
383
   public void createTexture()
384
     {
385
     Bitmap bitmap;
386

  
387
     final int S = 128;
388
     final int W = 3*S;
389
     final int H = 2*S;
390
     final int R = S/10;
391
     final int M = S/20;
392

  
393
     Paint paint = new Paint();
394
     bitmap = Bitmap.createBitmap(W,H, Bitmap.Config.ARGB_8888);
395
     Canvas canvas = new Canvas(bitmap);
396

  
397
     paint.setAntiAlias(true);
398
     paint.setTextAlign(Paint.Align.CENTER);
399
     paint.setStyle(Paint.Style.FILL);
400

  
401
     // 3x2 bitmap = 6 squares:
402
     //
403
     // RED     GREEN   BLUE
404
     // YELLOW  WHITE   BROWN
405

  
406
     paint.setColor(0xff000000);                                  // BLACK BACKGROUND
407
     canvas.drawRect(0, 0, W, H, paint);                          //
408

  
409
     paint.setColor(0xffff0000);                                  // RED
410
     canvas.drawRoundRect(    M,   M,   S-M,   S-M, R, R, paint); //
411
     paint.setColor(0xff00ff00);                                  // GREEN
412
     canvas.drawRoundRect(  S+M,   M, 2*S-M,   S-M, R, R, paint); //
413
     paint.setColor(0xff0000ff);                                  // BLUE
414
     canvas.drawRoundRect(2*S+M,   M, 3*S-M,   S-M, R, R, paint); //
415
     paint.setColor(0xffffff00);                                  // YELLOW
416
     canvas.drawRoundRect(    M, S+M,   S-M, 2*S-M, R, R, paint); //
417
     paint.setColor(0xffffffff);                                  // WHITE
418
     canvas.drawRoundRect(  S+M, S+M, 2*S-M, 2*S-M, R, R, paint); //
419
     paint.setColor(0xffb5651d);                                  // BROWN
420
     canvas.drawRoundRect(2*S+M, S+M, 3*S-M, 2*S-M, R, R, paint); //
421

  
422
     mTexture.setTexture(bitmap);
423
     }
424

  
425 194
///////////////////////////////////////////////////////////////////////////////////////////////////
426 195

  
427 196
   public void apply(Effect effect, int position)
......
598 367

  
599 368
      mRotationAngleStatic.set0(0);
600 369
      }
370

  
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

  
373
   public void createTexture()
374
     {
375
     Bitmap bitmap;
376

  
377
     final int S = 128;
378
     final int W = 3*S;
379
     final int H = 2*S;
380
     final int R = S/10;
381
     final int M = S/20;
382

  
383
     Paint paint = new Paint();
384
     bitmap = Bitmap.createBitmap(W,H, Bitmap.Config.ARGB_8888);
385
     Canvas canvas = new Canvas(bitmap);
386

  
387
     paint.setAntiAlias(true);
388
     paint.setTextAlign(Paint.Align.CENTER);
389
     paint.setStyle(Paint.Style.FILL);
390

  
391
     // 3x2 bitmap = 6 squares:
392
     //
393
     // RED     GREEN   BLUE
394
     // YELLOW  WHITE   BROWN
395

  
396
     paint.setColor(0xff000000);                                  // BLACK BACKGROUND
397
     canvas.drawRect(0, 0, W, H, paint);                          //
398

  
399
     paint.setColor(0xffff0000);                                  // RED
400
     canvas.drawRoundRect(    M,   M,   S-M,   S-M, R, R, paint); //
401
     paint.setColor(0xff00ff00);                                  // GREEN
402
     canvas.drawRoundRect(  S+M,   M, 2*S-M,   S-M, R, R, paint); //
403
     paint.setColor(0xff0000ff);                                  // BLUE
404
     canvas.drawRoundRect(2*S+M,   M, 3*S-M,   S-M, R, R, paint); //
405
     paint.setColor(0xffffff00);                                  // YELLOW
406
     canvas.drawRoundRect(    M, S+M,   S-M, 2*S-M, R, R, paint); //
407
     paint.setColor(0xffffffff);                                  // WHITE
408
     canvas.drawRoundRect(  S+M, S+M, 2*S-M, 2*S-M, R, R, paint); //
409
     paint.setColor(0xffb5651d);                                  // BROWN
410
     canvas.drawRoundRect(2*S+M, S+M, 3*S-M, 2*S-M, R, R, paint); //
411

  
412
     mTexture.setTexture(bitmap);
413
     }
414

  
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

  
417
   private MeshCubes createMesh(int vertices,int x, int y, int z)
418
     {
419
     Static4D tmpLeft  = (x==       0 ? mapLeft  :mapBlack);
420
     Static4D tmpRight = (x== mSize-1 ? mapRight :mapBlack);
421
     Static4D tmpFront = (z== mSize-1 ? mapFront :mapBlack);
422
     Static4D tmpBack  = (z==       0 ? mapBack  :mapBlack);
423
     Static4D tmpTop   = (y== mSize-1 ? mapTop   :mapBlack);
424
     Static4D tmpBottom= (y==       0 ? mapBottom:mapBlack);
425

  
426
     return new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom);
427
     }
601 428
}
src/main/java/org/distorted/object/RubikObject.java
35 35
import org.distorted.library.type.Static1D;
36 36
import org.distorted.library.type.Static3D;
37 37
import org.distorted.library.type.Static4D;
38
import org.distorted.magic.RubikSurfaceView;
39 38

  
40 39
///////////////////////////////////////////////////////////////////////////////////////////////////
41 40

  
......
45 44
  static final int TEXTURE_SIZE = 100;
46 45

  
47 46
  private static final int POST_ROTATION_MILLISEC = 500;
48
  private final float[] LEGAL_QUATS;
47
  final float[] LEGAL_QUATS;
49 48

  
50 49
  private Static3D mMove, mScale, mNodeMove, mNodeScale;
51 50
  private Static4D mQuatAccumulated;
......
100 99
    effects.apply(nodeMoveEffect);
101 100
    }
102 101

  
103
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
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
    }
177

  
178 102
///////////////////////////////////////////////////////////////////////////////////////////////////
179 103

  
180 104
  void resetRotationAngle(Dynamic1D rotationAngle)
......
187 111
    rotationAngle.add(mRotationAngleFinal);
188 112
    }
189 113

  
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 114
///////////////////////////////////////////////////////////////////////////////////////////////////
214 115

  
215 116
  private float getSinkStrength()

Also available in: Unified diff