Revision f16ff19d
Added by Leszek Koltunski about 4 years ago
src/main/java/org/distorted/object/RubikCube.java | ||
---|---|---|
52 | 52 |
private static final Static3D VectY = new Static3D(0,1,0); |
53 | 53 |
private static final Static3D VectZ = new Static3D(0,0,1); |
54 | 54 |
|
55 |
private DistortedNode[][][] mNodes; |
|
56 |
private MeshCubes[][][] mCubes; |
|
57 |
private DistortedEffects[][][] mEffects; |
|
58 |
private Static4D[][][] mQuatScramble; |
|
59 |
private Static3D[][][] mRotationAxis; |
|
60 |
private Dynamic1D[][][] mRotationAngle; |
|
61 |
private Static3D[][][] mCurrentPosition; |
|
62 |
private MatrixEffectRotate[][][] mRotateEffect; |
|
55 |
private static final Static3D matrCenter = new Static3D(0,0,0); |
|
63 | 56 |
|
64 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
65 |
// All legal rotation quats must have all four of their components equal to either |
|
66 |
// 0, 1, -1, 0.5, -0.5 or +-sqrt(2)/2. |
|
67 |
// |
|
68 |
// Because of quatMultiplication, errors can accumulate - so to avoid this, we |
|
69 |
// correct the value of the 'scramble' quat to what it should be. |
|
70 |
// |
|
71 |
// We also have to remember that the group of unit quaternions is a double-cover of rotations |
|
72 |
// in 3D ( q represents the same rotation as -q ) - so invert if needed. |
|
57 |
///////////////////////////////////////////////////////////////////////////////// |
|
73 | 58 |
|
74 |
private static final float SQ2 = 0.5f*((float)Math.sqrt(2)); |
|
75 |
private static final float[] LEGAL = { 0.0f , 0.5f , -0.5f , 1.0f , -1.0f , SQ2 , -SQ2 }; |
|
76 |
|
|
77 |
private void normalizeScrambleQuat(int i, int j, int k) |
|
59 |
private class Cubit |
|
78 | 60 |
{ |
79 |
Static4D quat = mQuatScramble[i][j][k]; |
|
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; |
|
80 | 70 |
|
81 |
float x = quat.get0(); |
|
82 |
float y = quat.get1(); |
|
83 |
float z = quat.get2(); |
|
84 |
float w = quat.get3(); |
|
85 |
float diff; |
|
71 |
MatrixEffectRotate mRotateEffect; |
|
86 | 72 |
|
87 |
for(float legal: LEGAL) |
|
73 |
///////////////////////////////////////////////////////////////////////////////// |
|
74 |
|
|
75 |
Cubit(MeshCubes mesh,Static3D vector, Static3D position) |
|
88 | 76 |
{ |
89 |
diff = x-legal; |
|
90 |
if( diff*diff<0.01f ) x = legal; |
|
91 |
diff = y-legal; |
|
92 |
if( diff*diff<0.01f ) y = legal; |
|
93 |
diff = z-legal; |
|
94 |
if( diff*diff<0.01f ) z = legal; |
|
95 |
diff = w-legal; |
|
96 |
if( diff*diff<0.01f ) w = legal; |
|
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 | 97 |
} |
98 | 98 |
|
99 |
if( w<0 ) |
|
99 |
///////////////////////////////////////////////////////////////////////////////// |
|
100 |
|
|
101 |
void savePreferences(SharedPreferences.Editor editor) |
|
100 | 102 |
{ |
101 |
w = -w; |
|
102 |
z = -z; |
|
103 |
y = -y; |
|
104 |
x = -x; |
|
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()); |
|
105 | 109 |
} |
106 |
else if( w==0 ) |
|
110 |
|
|
111 |
///////////////////////////////////////////////////////////////////////////////// |
|
112 |
|
|
113 |
void restorePreferences(SharedPreferences preferences) |
|
107 | 114 |
{ |
108 |
if( z<0 ) |
|
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 ) |
|
109 | 133 |
{ |
110 |
z = -z; |
|
111 |
y = -y; |
|
112 |
x = -x; |
|
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); |
|
113 | 140 |
} |
114 |
else if( z==0 )
|
|
141 |
else |
|
115 | 142 |
{ |
116 |
if( y<0 ) |
|
117 |
{ |
|
118 |
y = -y; |
|
119 |
x = -x; |
|
120 |
} |
|
121 |
else if( y==0 ) |
|
122 |
{ |
|
123 |
if( x<0 ) |
|
124 |
{ |
|
125 |
x = -x; |
|
126 |
} |
|
127 |
} |
|
143 |
return 0; |
|
128 | 144 |
} |
129 | 145 |
} |
130 | 146 |
|
131 |
mQuatScramble[i][j][k].set(x,y,z,w); |
|
132 |
} |
|
147 |
///////////////////////////////////////////////////////////////////////////////// |
|
133 | 148 |
|
134 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
149 |
Static4D returnRotationQuat(float qx,float qy,float qz) |
|
150 |
{ |
|
151 |
int pointNum = mRotationAngle.getNumPoints(); |
|
135 | 152 |
|
136 |
private boolean belongsToRotation(int x, int y, int z, int vector, int row) |
|
137 |
{ |
|
138 |
switch(vector) |
|
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) |
|
139 | 171 |
{ |
140 |
case VECTX: return mCurrentPosition[x][y][z].get0()==row; |
|
141 |
case VECTY: return mCurrentPosition[x][y][z].get1()==row; |
|
142 |
case VECTZ: return mCurrentPosition[x][y][z].get2()==row; |
|
172 |
mRotationAngle.removeAll(); |
|
173 |
mQuatScramble.set(RubikSurfaceView.quatMultiply(quat,mQuatScramble)); |
|
174 |
normalizeScrambleQuat( mQuatScramble ); |
|
175 |
modifyCurrentPosition( mCurrentPosition,quat); |
|
143 | 176 |
} |
144 | 177 |
|
145 |
return false; |
|
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 |
} |
|
212 |
|
|
213 |
|
|
214 |
///////////////////////////////////////////////////////////////////////////////// |
|
215 |
|
|
216 |
long setUpCallback(EffectListener listener) |
|
217 |
{ |
|
218 |
mRotateEffect.notifyWhenFinished(listener); |
|
219 |
return mRotateEffect.getID(); |
|
220 |
} |
|
146 | 221 |
} |
147 | 222 |
|
223 |
private Cubit[][][] mCubits; |
|
224 |
|
|
148 | 225 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
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. |
|
149 | 228 |
|
150 |
private void modifyCurrentPosition(int x, int y, int z, Static4D quat)
|
|
229 |
float[] getLegalQuats()
|
|
151 | 230 |
{ |
152 |
Static3D current = mCurrentPosition[x][y][z]; |
|
153 |
float diff = 0.5f*(mSize-1); |
|
154 |
float cubitCenterX = current.get0() - diff; |
|
155 |
float cubitCenterY = current.get1() - diff; |
|
156 |
float cubitCenterZ = current.get2() - diff; |
|
157 |
|
|
158 |
Static4D cubitCenter = new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0); |
|
159 |
Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat); |
|
160 |
|
|
161 |
float rotatedX = rotatedCenter.get0() + diff; |
|
162 |
float rotatedY = rotatedCenter.get1() + diff; |
|
163 |
float rotatedZ = rotatedCenter.get2() + diff; |
|
164 |
|
|
165 |
int roundedX = (int)(rotatedX+0.1f); |
|
166 |
int roundedY = (int)(rotatedY+0.1f); |
|
167 |
int roundedZ = (int)(rotatedZ+0.1f); |
|
168 |
|
|
169 |
mCurrentPosition[x][y][z].set0(roundedX); |
|
170 |
mCurrentPosition[x][y][z].set1(roundedY); |
|
171 |
mCurrentPosition[x][y][z].set2(roundedZ); |
|
231 |
final float SQ2 = 0.5f*((float)Math.sqrt(2)); |
|
232 |
return new float[] { 0.0f , 0.5f , -0.5f , 1.0f , -1.0f , SQ2 , -SQ2 }; |
|
233 |
} |
|
234 |
|
|
235 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
236 |
|
|
237 |
private boolean belongsToRotation( Static3D currentPosition, int vector, int row) |
|
238 |
{ |
|
239 |
switch(vector) |
|
240 |
{ |
|
241 |
case VECTX: return currentPosition.get0()==row; |
|
242 |
case VECTY: return currentPosition.get1()==row; |
|
243 |
case VECTZ: return currentPosition.get2()==row; |
|
244 |
} |
|
245 |
|
|
246 |
return false; |
|
172 | 247 |
} |
173 | 248 |
|
174 | 249 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
179 | 254 |
|
180 | 255 |
mRotAxis = VECTX; |
181 | 256 |
mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE); |
182 |
|
|
183 |
mNodes = new DistortedNode[mSize][mSize][mSize]; |
|
184 |
mCubes = new MeshCubes[mSize][mSize][mSize]; |
|
185 |
mEffects = new DistortedEffects[mSize][mSize][mSize]; |
|
186 |
mQuatScramble = new Static4D[mSize][mSize][mSize]; |
|
187 |
mRotationAxis = new Static3D[mSize][mSize][mSize]; |
|
188 |
mRotationAngle = new Dynamic1D[mSize][mSize][mSize]; |
|
189 |
mCurrentPosition= new Static3D[mSize][mSize][mSize]; |
|
190 |
mRotateEffect = new MatrixEffectRotate[mSize][mSize][mSize]; |
|
191 |
|
|
192 |
Static3D[][][] cubeVectors = new Static3D[mSize][mSize][mSize]; |
|
193 |
Static3D matrCenter = new Static3D(0,0,0); |
|
257 |
mCubits = new Cubit[mSize][mSize][mSize]; |
|
194 | 258 |
|
195 | 259 |
// 3x2 bitmap = 6 squares: |
196 | 260 |
// |
... | ... | |
229 | 293 |
tmpTop = (y== mSize-1 ? mapTop :mapBlack); |
230 | 294 |
tmpBottom= (y== 0 ? mapBottom:mapBlack); |
231 | 295 |
|
232 |
mCubes[x][y][z] = new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom); |
|
233 |
cubeVectors[x][y][z] = new Static3D( TEXTURE_SIZE*(x-nc), TEXTURE_SIZE*(y-nc), TEXTURE_SIZE*(z-nc) ); |
|
234 |
mQuatScramble[x][y][z] = new Static4D(0,0,0,1); |
|
235 |
mRotationAngle[x][y][z] = new Dynamic1D(); |
|
236 |
mRotationAxis[x][y][z] = new Static3D(1,0,0); |
|
237 |
mCurrentPosition[x][y][z] = new Static3D(x,y,z); |
|
238 |
mRotateEffect[x][y][z] = new MatrixEffectRotate(mRotationAngle[x][y][z], mRotationAxis[x][y][z], matrCenter); |
|
239 |
|
|
240 |
mEffects[x][y][z] = new DistortedEffects(); |
|
241 |
mEffects[x][y][z].apply(mSinkEffect); |
|
242 |
mEffects[x][y][z].apply( new MatrixEffectMove(cubeVectors[x][y][z]) ); |
|
243 |
mEffects[x][y][z].apply( new MatrixEffectQuaternion(mQuatScramble[x][y][z], matrCenter)); |
|
244 |
mEffects[x][y][z].apply(mRotateEffect[x][y][z]); |
|
245 |
mEffects[x][y][z].apply(mQuatAEffect); |
|
246 |
mEffects[x][y][z].apply(mQuatCEffect); |
|
247 |
mEffects[x][y][z].apply(mScaleEffect); |
|
248 |
mEffects[x][y][z].apply(mMoveEffect); |
|
249 |
|
|
250 |
mNodes[x][y][z] = new DistortedNode(mTexture,mEffects[x][y][z],mCubes[x][y][z]); |
|
251 |
|
|
252 |
attach(mNodes[x][y][z]); |
|
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 |
|
|
300 |
attach(mCubits[x][y][z].mNode); |
|
253 | 301 |
} |
254 | 302 |
} |
255 | 303 |
} |
... | ... | |
261 | 309 |
|
262 | 310 |
public void savePreferences(SharedPreferences.Editor editor) |
263 | 311 |
{ |
264 |
float qx,qy,qz,qw; |
|
265 |
|
|
266 | 312 |
for(int x=0; x<mSize; x++) |
267 | 313 |
for(int y=0; y<mSize; y++) |
268 | 314 |
for(int z=0; z<mSize; z++) |
269 | 315 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
270 | 316 |
{ |
271 |
qx = mQuatScramble[x][y][z].get0(); |
|
272 |
qy = mQuatScramble[x][y][z].get1(); |
|
273 |
qz = mQuatScramble[x][y][z].get2(); |
|
274 |
qw = mQuatScramble[x][y][z].get3(); |
|
275 |
|
|
276 |
editor.putFloat("qx_"+x+"_"+y+"_"+z, qx); |
|
277 |
editor.putFloat("qy_"+x+"_"+y+"_"+z, qy); |
|
278 |
editor.putFloat("qz_"+x+"_"+y+"_"+z, qz); |
|
279 |
editor.putFloat("qw_"+x+"_"+y+"_"+z, qw); |
|
317 |
mCubits[x][y][z].savePreferences(editor); |
|
280 | 318 |
} |
281 | 319 |
} |
282 | 320 |
|
... | ... | |
284 | 322 |
|
285 | 323 |
public void restorePreferences(SharedPreferences preferences) |
286 | 324 |
{ |
287 |
float qx,qy,qz,qw; |
|
288 |
|
|
289 | 325 |
for(int x=0; x<mSize; x++) |
290 | 326 |
for(int y=0; y<mSize; y++) |
291 | 327 |
for(int z=0; z<mSize; z++) |
292 | 328 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
293 | 329 |
{ |
294 |
qx = preferences.getFloat("qx_"+x+"_"+y+"_"+z, 0.0f); |
|
295 |
qy = preferences.getFloat("qy_"+x+"_"+y+"_"+z, 0.0f); |
|
296 |
qz = preferences.getFloat("qz_"+x+"_"+y+"_"+z, 0.0f); |
|
297 |
qw = preferences.getFloat("qw_"+x+"_"+y+"_"+z, 1.0f); |
|
298 |
|
|
299 |
mQuatScramble[x][y][z].set(qx,qy,qz,qw); |
|
300 |
modifyCurrentPosition(x, y, z, mQuatScramble[x][y][z]); |
|
330 |
mCubits[x][y][z].restorePreferences(preferences); |
|
301 | 331 |
} |
302 | 332 |
} |
303 | 333 |
|
... | ... | |
313 | 343 |
for(int z=0; z<mSize; z++) |
314 | 344 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
315 | 345 |
{ |
316 |
if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
|
|
346 |
if( belongsToRotation(mCubits[x][y][z].mCurrentPosition,mRotAxis,mRotRow) )
|
|
317 | 347 |
{ |
318 | 348 |
if( first ) |
319 | 349 |
{ |
320 | 350 |
first = false; |
321 |
mRotateEffect[x][y][z].notifyWhenFinished(listener); |
|
322 |
effectID = mRotateEffect[x][y][z].getID(); |
|
323 |
int pointNum = mRotationAngle[x][y][z].getNumPoints(); |
|
324 |
|
|
325 |
if( pointNum>=1 ) |
|
326 |
{ |
|
327 |
float startingAngle = mRotationAngle[x][y][z].getPoint(pointNum-1).get0(); |
|
328 |
int nearestAngleInDegrees = computeNearestAngle(startingAngle); |
|
329 |
mRotationAngleStatic.set0(startingAngle); |
|
330 |
mRotationAngleFinal.set0(nearestAngleInDegrees); |
|
331 |
mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-startingAngle)*0.2f ); |
|
332 |
} |
|
333 |
else |
|
334 |
{ |
|
335 |
android.util.Log.e("cube", "ERROR finishing rotation!"); |
|
336 |
return 0; |
|
337 |
} |
|
351 |
effectID = mCubits[x][y][z].finishRotationNow(listener); |
|
338 | 352 |
} |
339 | 353 |
|
340 |
mRotationAngle[x][y][z].setDuration(POST_ROTATION_MILLISEC); |
|
341 |
mRotationAngle[x][y][z].resetToBeginning(); |
|
342 |
mRotationAngle[x][y][z].removeAll(); |
|
343 |
mRotationAngle[x][y][z].add(mRotationAngleStatic); |
|
344 |
mRotationAngle[x][y][z].add(mRotationAngleMiddle); |
|
345 |
mRotationAngle[x][y][z].add(mRotationAngleFinal); |
|
354 |
resetRotationAngle(mCubits[x][y][z].mRotationAngle); |
|
346 | 355 |
} |
347 | 356 |
} |
348 | 357 |
|
... | ... | |
364 | 373 |
{ |
365 | 374 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
366 | 375 |
{ |
367 |
mCubes[x][y][z].markForDeletion(); |
|
368 |
mNodes[x][y][z].markForDeletion(); |
|
376 |
mCubits[x][y][z].releaseResources(); |
|
369 | 377 |
} |
370 | 378 |
} |
371 | 379 |
} |
... | ... | |
424 | 432 |
{ |
425 | 433 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
426 | 434 |
{ |
427 |
mEffects[x][y][z].apply(effect, position);
|
|
435 |
mCubits[x][y][z].mEffect.apply(effect, position);
|
|
428 | 436 |
} |
429 | 437 |
} |
430 | 438 |
} |
... | ... | |
439 | 447 |
{ |
440 | 448 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
441 | 449 |
{ |
442 |
mEffects[x][y][z].abortById(effectID);
|
|
450 |
mCubits[x][y][z].mEffect.abortById(effectID);
|
|
443 | 451 |
} |
444 | 452 |
} |
445 | 453 |
} |
... | ... | |
453 | 461 |
for(int z=0; z<mSize; z++) |
454 | 462 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
455 | 463 |
{ |
456 |
mQuatScramble[x][y][z].set(0,0,0,1); |
|
457 |
mCurrentPosition[x][y][z].set(x,y,z); |
|
464 |
mCubits[x][y][z].solve(); |
|
458 | 465 |
} |
459 | 466 |
} |
460 | 467 |
|
... | ... | |
462 | 469 |
|
463 | 470 |
public boolean isSolved() |
464 | 471 |
{ |
465 |
Static4D q = mQuatScramble[0][0][0];
|
|
472 |
Static4D q = mCubits[0][0][0].mQuatScramble;
|
|
466 | 473 |
|
467 | 474 |
float x = q.get0(); |
468 | 475 |
float y = q.get1(); |
... | ... | |
475 | 482 |
{ |
476 | 483 |
if( i==0 || i==mSize-1 || j==0 || j==mSize-1 || k==0 || k==mSize-1 ) |
477 | 484 |
{ |
478 |
q = mQuatScramble[i][j][k];
|
|
485 |
q = mCubits[i][j][k].mQuatScramble;
|
|
479 | 486 |
|
480 | 487 |
if( q.get0()!=x || q.get1()!=y || q.get2()!=z || q.get3()!=w ) |
481 | 488 |
{ |
... | ... | |
510 | 517 |
for(int z=0; z<mSize; z++) |
511 | 518 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
512 | 519 |
{ |
513 |
if( belongsToRotation(x,y,z,vector,mRotRow) )
|
|
520 |
if( belongsToRotation( mCubits[x][y][z].mCurrentPosition,vector,mRotRow) )
|
|
514 | 521 |
{ |
515 |
mRotationAxis[x][y][z].set(axis); |
|
516 |
mRotationAngle[x][y][z].add(mRotationAngleStatic); |
|
522 |
mCubits[x][y][z].beginNewRotation(axis); |
|
517 | 523 |
} |
518 | 524 |
} |
519 | 525 |
} |
... | ... | |
543 | 549 |
for(int z=0; z<mSize; z++) |
544 | 550 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
545 | 551 |
{ |
546 |
if( belongsToRotation(x,y,z,vector,mRotRow) )
|
|
552 |
if( belongsToRotation(mCubits[x][y][z].mCurrentPosition,vector,mRotRow) )
|
|
547 | 553 |
{ |
548 |
mRotationAxis[x][y][z].set(axis); |
|
549 |
mRotationAngle[x][y][z].setDuration(durationMillis); |
|
550 |
mRotationAngle[x][y][z].resetToBeginning(); |
|
551 |
mRotationAngle[x][y][z].add(new Static1D(0)); |
|
552 |
mRotationAngle[x][y][z].add(new Static1D(angle)); |
|
554 |
mCubits[x][y][z].addNewRotation(axis,durationMillis,angle); |
|
553 | 555 |
|
554 | 556 |
if( first ) |
555 | 557 |
{ |
556 | 558 |
first = false; |
557 |
effectID = mRotateEffect[x][y][z].getID(); |
|
558 |
mRotateEffect[x][y][z].notifyWhenFinished(listener); |
|
559 |
effectID = mCubits[x][y][z].setUpCallback(listener); |
|
559 | 560 |
} |
560 | 561 |
} |
561 | 562 |
} |
... | ... | |
583 | 584 |
for(int z=0; z<mSize; z++) |
584 | 585 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
585 | 586 |
{ |
586 |
if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
|
|
587 |
if( belongsToRotation(mCubits[x][y][z].mCurrentPosition,mRotAxis,mRotRow) )
|
|
587 | 588 |
{ |
588 | 589 |
if( first ) |
589 | 590 |
{ |
590 | 591 |
first = false; |
591 |
int pointNum = mRotationAngle[x][y][z].getNumPoints(); |
|
592 |
|
|
593 |
if( pointNum>=1 ) |
|
594 |
{ |
|
595 |
float startingAngle = mRotationAngle[x][y][z].getPoint(pointNum-1).get0(); |
|
596 |
int nearestAngleInDegrees = computeNearestAngle(startingAngle); |
|
597 |
double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180; |
|
598 |
float sinA =-(float)Math.sin(nearestAngleInRadians*0.5); |
|
599 |
float cosA = (float)Math.cos(nearestAngleInRadians*0.5); |
|
600 |
quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA); |
|
601 |
} |
|
602 |
else |
|
603 |
{ |
|
604 |
android.util.Log.e("cube", "ERROR removing rotation!"); |
|
605 |
return; |
|
606 |
} |
|
592 |
quat = mCubits[x][y][z].returnRotationQuat(qx,qy,qz); |
|
607 | 593 |
} |
608 | 594 |
|
609 |
mRotationAngle[x][y][z].removeAll(); |
|
610 |
mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z])); |
|
611 |
normalizeScrambleQuat(x,y,z); |
|
612 |
modifyCurrentPosition(x,y,z,quat); |
|
595 |
mCubits[x][y][z].removeRotationNow(quat); |
|
613 | 596 |
} |
614 | 597 |
} |
615 | 598 |
|
Also available in: Unified diff
Separate RubikCubit inner class.