Revision e8764a49
Added by Leszek Koltunski almost 5 years ago
src/main/java/org/distorted/effect/ScrambleEffect.java | ||
---|---|---|
21 | 21 |
|
22 | 22 |
import org.distorted.library.effect.Effect; |
23 | 23 |
import org.distorted.library.main.DistortedEffects; |
24 |
import org.distorted.library.main.DistortedScreen; |
|
25 | 24 |
import org.distorted.library.message.EffectListener; |
26 | 25 |
import org.distorted.magic.RubikCube; |
27 | 26 |
|
28 | 27 |
import java.lang.reflect.Method; |
28 |
import java.util.Random; |
|
29 | 29 |
|
30 | 30 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
31 | 31 |
|
... | ... | |
61 | 61 |
} |
62 | 62 |
|
63 | 63 |
private EffectListener mListener; |
64 |
private int mDuration; |
|
65 |
private int[] mEffectReturned; |
|
64 |
private int mEffectReturned; |
|
65 |
private long mCurrentBaseEffectID; |
|
66 |
private int mNumDoubleScramblesLeft, mNumScramblesLeft; |
|
67 |
private int mLastVector; |
|
68 |
private long mDurationSingleTurn; |
|
69 |
private Random mRnd; |
|
66 | 70 |
private RubikCube mCube; |
67 |
private DistortedScreen mScreen; |
|
68 | 71 |
|
69 |
static final int EFFECT_FLAVOUR_BASE = 0; |
|
70 |
static final int EFFECT_FLAVOUR_PLUGIN= 1; |
|
71 |
static final int NUM_EFFECT_FLAVOURS = 2; |
|
72 |
|
|
73 |
Effect[][] mNodeEffects; |
|
74 |
int[][] mNodeEffectPosition; |
|
75 |
Effect[][] mCubeEffects; |
|
76 |
int[][] mCubeEffectPosition; |
|
77 |
int[] mCubeEffectNumber, mNodeEffectNumber; |
|
72 |
Effect[] mNodeEffects; |
|
73 |
int[] mNodeEffectPosition; |
|
74 |
Effect[] mCubeEffects; |
|
75 |
int[] mCubeEffectPosition; |
|
76 |
int mCubeEffectNumber, mNodeEffectNumber; |
|
78 | 77 |
|
79 | 78 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
80 | 79 |
|
81 | 80 |
ScrambleEffect() |
82 | 81 |
{ |
83 |
mEffectReturned = new int[NUM_EFFECT_FLAVOURS]; |
|
84 |
mCubeEffectNumber = new int[NUM_EFFECT_FLAVOURS]; |
|
85 |
mNodeEffectNumber = new int[NUM_EFFECT_FLAVOURS]; |
|
86 |
mCubeEffectPosition = new int[NUM_EFFECT_FLAVOURS][]; |
|
87 |
mNodeEffectPosition = new int[NUM_EFFECT_FLAVOURS][]; |
|
88 |
mCubeEffects = new Effect[NUM_EFFECT_FLAVOURS][]; |
|
89 |
mNodeEffects = new Effect[NUM_EFFECT_FLAVOURS][]; |
|
82 |
mRnd = new Random( System.currentTimeMillis() ); |
|
83 |
mLastVector = -1; |
|
90 | 84 |
} |
91 | 85 |
|
92 | 86 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
123 | 117 |
abstract void effectFinishedPlugin(final long effectID); |
124 | 118 |
|
125 | 119 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
126 |
// TODO |
|
120 |
|
|
127 | 121 |
private void createBaseEffects(int duration, int numScrambles) |
128 | 122 |
{ |
129 |
mCubeEffectNumber[EFFECT_FLAVOUR_BASE] = 0; |
|
130 |
mNodeEffectNumber[EFFECT_FLAVOUR_BASE] = 0; |
|
123 |
mNumScramblesLeft = numScrambles; |
|
124 |
|
|
125 |
// compute how many out of 'numScrambles' are double turns. |
|
126 |
mNumDoubleScramblesLeft=0; |
|
127 |
|
|
128 |
for(int i=0; i<numScrambles; i++) |
|
129 |
{ |
|
130 |
if( (mRnd.nextInt() % 3) == 0 ) |
|
131 |
{ |
|
132 |
mNumDoubleScramblesLeft++; |
|
133 |
} |
|
134 |
} |
|
135 |
|
|
136 |
mDurationSingleTurn = duration/(mNumScramblesLeft+mNumDoubleScramblesLeft); |
|
137 |
|
|
138 |
addNewScramble(); |
|
131 | 139 |
} |
132 | 140 |
|
133 | 141 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
134 |
// TODO |
|
135 | 142 |
|
136 |
private void effectFinishedBase(final long effectID)
|
|
143 |
private void addNewScramble()
|
|
137 | 144 |
{ |
145 |
if( mNumScramblesLeft>0 ) |
|
146 |
{ |
|
147 |
if( mLastVector == -1 ) |
|
148 |
{ |
|
149 |
switch(mRnd.nextInt(3)) |
|
150 |
{ |
|
151 |
case 0: mLastVector = RubikCube.VECTX; break; |
|
152 |
case 1: mLastVector = RubikCube.VECTY; break; |
|
153 |
case 2: mLastVector = RubikCube.VECTZ; break; |
|
154 |
} |
|
155 |
} |
|
156 |
else |
|
157 |
{ |
|
158 |
int newVector = mRnd.nextInt(2); |
|
159 |
|
|
160 |
switch(mLastVector) |
|
161 |
{ |
|
162 |
case RubikCube.VECTX: mLastVector = (newVector==0 ? RubikCube.VECTY: RubikCube.VECTZ); break; |
|
163 |
case RubikCube.VECTY: mLastVector = (newVector==0 ? RubikCube.VECTX: RubikCube.VECTZ); break; |
|
164 |
case RubikCube.VECTZ: mLastVector = (newVector==0 ? RubikCube.VECTX: RubikCube.VECTY); break; |
|
165 |
} |
|
166 |
} |
|
167 |
|
|
168 |
int row = mRnd.nextInt(mCube.getSize()); |
|
169 |
int angle= randomizeAngle(); |
|
170 |
int absAngle = (angle<0 ? -angle : angle); |
|
171 |
long durationMillis = absAngle*mDurationSingleTurn; |
|
172 |
|
|
173 |
mNumScramblesLeft--; |
|
174 |
if( absAngle==2 ) mNumDoubleScramblesLeft--; |
|
138 | 175 |
|
176 |
mCurrentBaseEffectID = mCube.addNewRotation(mLastVector, row, angle*90, durationMillis, this ); |
|
177 |
} |
|
178 |
else |
|
179 |
{ |
|
180 |
mLastVector = -1; |
|
181 |
} |
|
182 |
} |
|
183 |
|
|
184 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
185 |
// TODO; |
|
186 |
|
|
187 |
private int randomizeAngle() |
|
188 |
{ |
|
189 |
return 1; |
|
139 | 190 |
} |
140 | 191 |
|
141 | 192 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
142 | 193 |
|
143 | 194 |
public void effectFinished(final long effectID) |
144 | 195 |
{ |
145 |
for(int flavour=0; flavour<NUM_EFFECT_FLAVOURS; flavour++) |
|
196 |
if( effectID == mCurrentBaseEffectID ) |
|
197 |
{ |
|
198 |
mCube.removeRotationNow(); |
|
199 |
addNewScramble(); |
|
200 |
return; |
|
201 |
} |
|
202 |
|
|
203 |
for(int i=0; i<mCubeEffectNumber; i++) |
|
146 | 204 |
{ |
147 |
for(int i=0; i<mCubeEffectNumber[flavour]; i++) |
|
205 |
long id = mCubeEffects[i].getID(); |
|
206 |
|
|
207 |
if( effectID == id ) |
|
148 | 208 |
{ |
149 |
long id = mCubeEffects[flavour][i].getID(); |
|
209 |
mEffectReturned++; |
|
210 |
effectFinishedPlugin(effectID); |
|
150 | 211 |
|
151 |
if( effectID == id )
|
|
212 |
if( mEffectReturned == mCubeEffectNumber+mNodeEffectNumber )
|
|
152 | 213 |
{ |
153 |
mEffectReturned[flavour]++; |
|
214 |
disassignEffects(); |
|
215 |
} |
|
154 | 216 |
|
155 |
switch(flavour) |
|
156 |
{ |
|
157 |
case EFFECT_FLAVOUR_BASE : effectFinishedBase( effectID); break; |
|
158 |
case EFFECT_FLAVOUR_PLUGIN: effectFinishedPlugin(effectID); break; |
|
159 |
} |
|
217 |
return; |
|
218 |
} |
|
219 |
} |
|
160 | 220 |
|
161 |
if( mEffectReturned[flavour] == mCubeEffectNumber[flavour]+mNodeEffectNumber[flavour] ) |
|
162 |
{ |
|
163 |
disassignEffects(flavour); |
|
164 |
} |
|
221 |
for(int i=0; i<mNodeEffectNumber; i++) |
|
222 |
{ |
|
223 |
long id = mNodeEffects[i].getID(); |
|
165 | 224 |
|
166 |
return; |
|
167 |
} |
|
168 |
} |
|
169 |
for(int i=0; i<mNodeEffectNumber[flavour]; i++) |
|
225 |
if( effectID == id ) |
|
170 | 226 |
{ |
171 |
long id = mNodeEffects[flavour][i].getID(); |
|
227 |
mEffectReturned++; |
|
228 |
effectFinishedPlugin(effectID); |
|
172 | 229 |
|
173 |
if( effectID == id )
|
|
230 |
if( mEffectReturned == mCubeEffectNumber+mNodeEffectNumber )
|
|
174 | 231 |
{ |
175 |
mEffectReturned[flavour]++; |
|
176 |
|
|
177 |
switch(flavour) |
|
178 |
{ |
|
179 |
case EFFECT_FLAVOUR_BASE : effectFinishedBase( effectID); break; |
|
180 |
case EFFECT_FLAVOUR_PLUGIN: effectFinishedPlugin(effectID); break; |
|
181 |
} |
|
182 |
|
|
183 |
if( mEffectReturned[flavour] == mCubeEffectNumber[flavour]+mNodeEffectNumber[flavour] ) |
|
184 |
{ |
|
185 |
disassignEffects(flavour); |
|
186 |
} |
|
187 |
|
|
188 |
return; |
|
232 |
disassignEffects(); |
|
189 | 233 |
} |
234 |
|
|
235 |
return; |
|
190 | 236 |
} |
191 | 237 |
} |
192 | 238 |
} |
193 | 239 |
|
194 | 240 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
195 | 241 |
|
196 |
public long start(int duration, DistortedScreen screen, RubikCube cube, int numScrambles, EffectListener listener)
|
|
242 |
public long start(int duration, RubikCube cube, int numScrambles, EffectListener listener) |
|
197 | 243 |
{ |
198 |
mScreen = screen; |
|
199 | 244 |
mCube = cube; |
200 | 245 |
mListener = listener; |
201 |
mDuration = duration; |
|
202 |
|
|
203 |
createBaseEffects(mDuration, numScrambles); |
|
204 |
assignEffects(EFFECT_FLAVOUR_BASE); |
|
205 | 246 |
|
206 |
createEffects(mDuration); |
|
247 |
createBaseEffects(duration, numScrambles); |
|
248 |
createEffects(duration); |
|
207 | 249 |
|
208 |
if( mCubeEffectNumber[EFFECT_FLAVOUR_PLUGIN]==0 && mNodeEffectNumber[EFFECT_FLAVOUR_PLUGIN]==0 )
|
|
250 |
if( mCubeEffectNumber==0 && mNodeEffectNumber==0 )
|
|
209 | 251 |
{ |
210 | 252 |
throw new RuntimeException("Cube and Node Plugin Effects not created!"); |
211 | 253 |
} |
212 | 254 |
|
213 |
assignEffects(EFFECT_FLAVOUR_PLUGIN);
|
|
255 |
assignEffects(); |
|
214 | 256 |
|
215 | 257 |
return FAKE_EFFECT_ID; |
216 | 258 |
} |
217 | 259 |
|
218 | 260 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
219 | 261 |
|
220 |
private void assignEffects(int flavour)
|
|
262 |
private void assignEffects() |
|
221 | 263 |
{ |
222 |
for(int i=0; i<mCubeEffectNumber[flavour]; i++)
|
|
264 |
for(int i=0; i<mCubeEffectNumber; i++) |
|
223 | 265 |
{ |
224 |
//android.util.Log.e("scramble", "applying cube effect "+mCubeEffects[flavour][i].getName()); |
|
225 |
|
|
226 |
mCube.apply(mCubeEffects[flavour][i],mCubeEffectPosition[flavour][i]); |
|
227 |
mCubeEffects[flavour][i].notifyWhenFinished(this); |
|
266 |
mCube.apply(mCubeEffects[i],mCubeEffectPosition[i]); |
|
267 |
mCubeEffects[i].notifyWhenFinished(this); |
|
228 | 268 |
} |
229 | 269 |
|
230 | 270 |
DistortedEffects nodeEffects = mCube.getEffects(); |
231 | 271 |
|
232 |
for(int i=0; i<mNodeEffectNumber[flavour]; i++)
|
|
272 |
for(int i=0; i<mNodeEffectNumber; i++) |
|
233 | 273 |
{ |
234 |
nodeEffects.apply(mNodeEffects[flavour][i],mNodeEffectPosition[flavour][i]);
|
|
235 |
mNodeEffects[flavour][i].notifyWhenFinished(this);
|
|
274 |
nodeEffects.apply(mNodeEffects[i],mNodeEffectPosition[i]);
|
|
275 |
mNodeEffects[i].notifyWhenFinished(this); |
|
236 | 276 |
} |
237 | 277 |
} |
238 | 278 |
|
239 | 279 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
240 | 280 |
|
241 |
private void disassignEffects(int flavour)
|
|
281 |
private void disassignEffects() |
|
242 | 282 |
{ |
243 |
for(int i=0; i<mCubeEffectNumber[flavour]; i++)
|
|
283 |
for(int i=0; i<mCubeEffectNumber; i++) |
|
244 | 284 |
{ |
245 |
//android.util.Log.e("scramble", "removing cube effect "+mCubeEffects[flavour][i].getName()); |
|
246 |
|
|
247 |
mCube.remove(mCubeEffects[flavour][i].getID()); |
|
285 |
mCube.remove(mCubeEffects[i].getID()); |
|
248 | 286 |
} |
249 | 287 |
|
250 | 288 |
DistortedEffects nodeEffects = mCube.getEffects(); |
251 | 289 |
|
252 |
for(int i=0; i<mNodeEffectNumber[flavour]; i++)
|
|
290 |
for(int i=0; i<mNodeEffectNumber; i++) |
|
253 | 291 |
{ |
254 |
nodeEffects.abortById(mNodeEffects[flavour][i].getID());
|
|
292 |
nodeEffects.abortById(mNodeEffects[i].getID()); |
|
255 | 293 |
} |
256 | 294 |
|
257 |
if( flavour==EFFECT_FLAVOUR_PLUGIN ) |
|
258 |
{ |
|
259 |
mListener.effectFinished(FAKE_EFFECT_ID); |
|
260 |
} |
|
295 |
mListener.effectFinished(FAKE_EFFECT_ID); |
|
261 | 296 |
} |
262 | 297 |
|
263 | 298 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
src/main/java/org/distorted/effect/ScrambleEffectNone.java | ||
---|---|---|
33 | 33 |
Dynamic3D d0 = new Dynamic3D(1,0.5f); |
34 | 34 |
d0.add(new Static3D(0,0,0)); |
35 | 35 |
|
36 |
mCubeEffectNumber[EFFECT_FLAVOUR_PLUGIN] = 1;
|
|
37 |
mNodeEffectNumber[EFFECT_FLAVOUR_PLUGIN] = 0;
|
|
36 |
mCubeEffectNumber = 1; |
|
37 |
mNodeEffectNumber = 0; |
|
38 | 38 |
|
39 |
mCubeEffectPosition[EFFECT_FLAVOUR_PLUGIN] = new int[] {-1};
|
|
40 |
mCubeEffects[EFFECT_FLAVOUR_PLUGIN] = new Effect[mCubeEffectPosition[EFFECT_FLAVOUR_PLUGIN].length];
|
|
41 |
mCubeEffects[EFFECT_FLAVOUR_PLUGIN][0] = new MatrixEffectMove(d0);
|
|
39 |
mCubeEffectPosition = new int[] {-1}; |
|
40 |
mCubeEffects = new Effect[mCubeEffectPosition.length];
|
|
41 |
mCubeEffects[0] = new MatrixEffectMove(d0); |
|
42 | 42 |
} |
43 | 43 |
|
44 | 44 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
src/main/java/org/distorted/effect/ScrambleEffectRotations.java | ||
---|---|---|
42 | 42 |
|
43 | 43 |
public void createEffects(int duration) |
44 | 44 |
{ |
45 |
mCubeEffectNumber[EFFECT_FLAVOUR_PLUGIN] = 2;
|
|
46 |
mNodeEffectNumber[EFFECT_FLAVOUR_PLUGIN] = 0;
|
|
47 |
mCubeEffectPosition[EFFECT_FLAVOUR_PLUGIN] = new int[] {6,7};
|
|
48 |
mCubeEffects[EFFECT_FLAVOUR_PLUGIN] = new Effect[mCubeEffectPosition[EFFECT_FLAVOUR_PLUGIN].length];
|
|
45 |
mCubeEffectNumber = 2; |
|
46 |
mNodeEffectNumber = 0; |
|
47 |
mCubeEffectPosition = new int[] {6,7}; |
|
48 |
mCubeEffects = new Effect[mCubeEffectPosition.length];
|
|
49 | 49 |
|
50 | 50 |
mRnd.setSeed(System.currentTimeMillis()); |
51 | 51 |
|
... | ... | |
57 | 57 |
dq.add(generateNewRandomPoint()); |
58 | 58 |
dq.add(new Static4D(0,0,0,1)); |
59 | 59 |
|
60 |
mCubeEffects[EFFECT_FLAVOUR_PLUGIN][0] = new MatrixEffectQuaternion(dq, new Static3D(0,0,0));
|
|
60 |
mCubeEffects[0] = new MatrixEffectQuaternion(dq, new Static3D(0,0,0)); |
|
61 | 61 |
|
62 | 62 |
float Z = TEXTURE_SIZE/3; |
63 | 63 |
|
... | ... | |
66 | 66 |
d0.add(new Static3D( 0, 0, 0)); |
67 | 67 |
d0.add(new Static3D( 0, 0,-Z)); |
68 | 68 |
d0.add(new Static3D( 0, 0, 0)); |
69 |
mCubeEffects[EFFECT_FLAVOUR_PLUGIN][1] = new MatrixEffectMove(d0);
|
|
69 |
mCubeEffects[1] = new MatrixEffectMove(d0); |
|
70 | 70 |
} |
71 | 71 |
|
72 | 72 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
src/main/java/org/distorted/magic/RubikCube.java | ||
---|---|---|
53 | 53 |
private static final Static3D VectY = new Static3D(0,1,0); |
54 | 54 |
private static final Static3D VectZ = new Static3D(0,0,1); |
55 | 55 |
|
56 |
public static final int VECTX = 0; // |
|
57 |
public static final int VECTY = 1; // don't change this |
|
58 |
public static final int VECTZ = 2; // |
|
59 |
|
|
56 | 60 |
private DistortedNode[][][] mNodes; |
57 | 61 |
private MeshCubes[][][] mCubes; |
58 | 62 |
private DistortedEffects[][][] mEffects; |
... | ... | |
89 | 93 |
mNodeMove = new Static3D(0,0,0); |
90 | 94 |
mNodeScale= new Static3D(1,1,1); |
91 | 95 |
|
92 |
mRotAxis= RubikSurfaceView.VECTX;
|
|
96 |
mRotAxis = VECTX;
|
|
93 | 97 |
mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE); |
94 | 98 |
|
95 | 99 |
mNodes = new DistortedNode[mSize][mSize][mSize]; |
... | ... | |
278 | 282 |
return mEffects[0][0][0].getNumEffects(type); |
279 | 283 |
} |
280 | 284 |
|
285 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
286 |
|
|
287 |
public long addNewRotation(int vector, int row, int angle, long durationMillis, EffectListener listener ) |
|
288 |
{ |
|
289 |
Static3D axis = VectX; |
|
290 |
long effectID=0; |
|
291 |
boolean first = true; |
|
292 |
|
|
293 |
switch(vector) |
|
294 |
{ |
|
295 |
case VECTX: axis = VectX; break; |
|
296 |
case VECTY: axis = VectY; break; |
|
297 |
case VECTZ: axis = VectZ; break; |
|
298 |
} |
|
299 |
|
|
300 |
mRotAxis = vector; |
|
301 |
mRotRow = row; |
|
302 |
|
|
303 |
mRotationAngleStatic.set1(0.0f); |
|
304 |
|
|
305 |
for(int x=0; x<mSize; x++) |
|
306 |
for(int y=0; y<mSize; y++) |
|
307 |
for(int z=0; z<mSize; z++) |
|
308 |
if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) |
|
309 |
{ |
|
310 |
if( belongsToRotation(x,y,z,vector,mRotRow) ) |
|
311 |
{ |
|
312 |
mRotationAxis[x][y][z].set(axis); |
|
313 |
mRotationAngle[x][y][z].setDuration(durationMillis); |
|
314 |
mRotationAngle[x][y][z].resetToBeginning(); |
|
315 |
mRotationAngle[x][y][z].add(new Static1D(0)); |
|
316 |
mRotationAngle[x][y][z].add(new Static1D(angle)); |
|
317 |
|
|
318 |
if( first ) |
|
319 |
{ |
|
320 |
first = false; |
|
321 |
effectID = mRotateEffect[x][y][z].getID(); |
|
322 |
mRotateEffect[x][y][z].notifyWhenFinished(listener); |
|
323 |
} |
|
324 |
} |
|
325 |
} |
|
326 |
|
|
327 |
return effectID; |
|
328 |
} |
|
329 |
|
|
330 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
331 |
|
|
332 |
public int getSize() |
|
333 |
{ |
|
334 |
return mSize; |
|
335 |
} |
|
336 |
|
|
281 | 337 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
282 | 338 |
// all DistortedTextures, DistortedNodes, DistortedFramebuffers, DistortedScreens and all types of |
283 | 339 |
// Meshes HAVE TO be markedForDeletion when they are no longer needed- otherwise we have a major |
... | ... | |
307 | 363 |
|
308 | 364 |
switch(vector) |
309 | 365 |
{ |
310 |
case RubikSurfaceView.VECTX: axis = VectX; break;
|
|
311 |
case RubikSurfaceView.VECTY: axis = VectY; break;
|
|
312 |
case RubikSurfaceView.VECTZ: axis = VectZ; break;
|
|
366 |
case VECTX: axis = VectX; break; |
|
367 |
case VECTY: axis = VectY; break; |
|
368 |
case VECTZ: axis = VectZ; break; |
|
313 | 369 |
} |
314 | 370 |
|
315 | 371 |
mRotAxis = vector; |
... | ... | |
399 | 455 |
|
400 | 456 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
401 | 457 |
|
402 |
void removeRotationNow() |
|
458 |
public void removeRotationNow()
|
|
403 | 459 |
{ |
404 |
int nearestAngleInDegrees = computeNearestAngle(mRotationAngleStatic.get1()); |
|
405 |
double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180; |
|
406 |
float sinA =-(float)Math.sin(nearestAngleInRadians*0.5); |
|
407 |
float cosA = (float)Math.cos(nearestAngleInRadians*0.5); |
|
408 |
|
|
409 |
mRotationAngleStatic.set1(0); |
|
410 |
|
|
411 | 460 |
float qx=0,qy=0,qz=0; |
461 |
boolean first = true; |
|
462 |
Static4D quat = null; |
|
412 | 463 |
|
413 | 464 |
switch(mRotAxis) |
414 | 465 |
{ |
415 |
case RubikSurfaceView.VECTX: qx=1; break;
|
|
416 |
case RubikSurfaceView.VECTY: qy=1; break;
|
|
417 |
case RubikSurfaceView.VECTZ: qz=1; break;
|
|
466 |
case VECTX: qx=1; break; |
|
467 |
case VECTY: qy=1; break; |
|
468 |
case VECTZ: qz=1; break; |
|
418 | 469 |
} |
419 | 470 |
|
420 |
Static4D quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA); |
|
421 |
|
|
422 | 471 |
for(int x=0; x<mSize; x++) |
423 | 472 |
for(int y=0; y<mSize; y++) |
424 | 473 |
for(int z=0; z<mSize; z++) |
... | ... | |
426 | 475 |
{ |
427 | 476 |
if( belongsToRotation(x,y,z,mRotAxis,mRotRow) ) |
428 | 477 |
{ |
478 |
if( first ) |
|
479 |
{ |
|
480 |
first = false; |
|
481 |
int pointNum = mRotationAngle[x][y][z].getNumPoints(); |
|
482 |
|
|
483 |
if( pointNum>=1 ) |
|
484 |
{ |
|
485 |
float startingAngle = mRotationAngle[x][y][z].getPoint(pointNum-1).get1(); |
|
486 |
int nearestAngleInDegrees = computeNearestAngle(startingAngle); |
|
487 |
double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180; |
|
488 |
float sinA =-(float)Math.sin(nearestAngleInRadians*0.5); |
|
489 |
float cosA = (float)Math.cos(nearestAngleInRadians*0.5); |
|
490 |
quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA); |
|
491 |
} |
|
492 |
else |
|
493 |
{ |
|
494 |
android.util.Log.e("cube", "ERROR removing rotation!"); |
|
495 |
return; |
|
496 |
} |
|
497 |
} |
|
498 |
|
|
429 | 499 |
mRotationAngle[x][y][z].removeAll(); |
430 | 500 |
mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z])); |
431 | 501 |
modifyCurrentPosition(x,y,z,quat); |
432 | 502 |
} |
433 | 503 |
} |
504 |
|
|
505 |
mRotationAngleStatic.set1(0); |
|
434 | 506 |
} |
435 | 507 |
|
436 | 508 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
453 | 525 |
{ |
454 | 526 |
switch(vector) |
455 | 527 |
{ |
456 |
case RubikSurfaceView.VECTX: return mCurrentPosition[x][y][z].get1()==row;
|
|
457 |
case RubikSurfaceView.VECTY: return mCurrentPosition[x][y][z].get2()==row;
|
|
458 |
case RubikSurfaceView.VECTZ: return mCurrentPosition[x][y][z].get3()==row;
|
|
528 |
case VECTX: return mCurrentPosition[x][y][z].get1()==row; |
|
529 |
case VECTY: return mCurrentPosition[x][y][z].get2()==row; |
|
530 |
case VECTZ: return mCurrentPosition[x][y][z].get3()==row; |
|
459 | 531 |
} |
460 | 532 |
|
461 | 533 |
return false; |
... | ... | |
533 | 605 |
|
534 | 606 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
535 | 607 |
|
536 |
void recomputeScaleFactor(int screenWidth, int screenHeight, float size) |
|
537 |
{ |
|
538 |
int texW = mNodeTexture.getWidth(); |
|
539 |
int texH = mNodeTexture.getHeight(); |
|
540 |
|
|
541 |
if( (float)texH/texW > (float)screenHeight/screenWidth ) |
|
542 |
{ |
|
543 |
int w = (screenHeight*texW)/texH; |
|
544 |
float factor = (float)screenHeight/texH; |
|
545 |
mNodeMove.set((screenWidth-w)*0.5f ,0, 0); |
|
546 |
mNodeScale.set(factor,factor,factor); |
|
547 |
} |
|
548 |
else |
|
549 |
{ |
|
550 |
int h = (screenWidth*texH)/texW; |
|
551 |
float factor = (float)screenWidth/texW; |
|
552 |
mNodeMove.set(0,(screenHeight-h)*0.5f,0); |
|
553 |
mNodeScale.set(factor,factor,factor); |
|
554 |
} |
|
555 |
|
|
556 |
float scaleFactor = (size/(TEXTURE_SIZE*mSize)) * (float)texW/(screenWidth>screenHeight ? screenHeight:screenWidth); |
|
557 |
|
|
558 |
mMove.set( texW*0.5f , texH*0.5f , 0.0f ); |
|
559 |
mScale.set(scaleFactor,scaleFactor,scaleFactor); |
|
560 |
} |
|
608 |
void recomputeScaleFactor(int screenWidth, int screenHeight, float size) |
|
609 |
{ |
|
610 |
int texW = mNodeTexture.getWidth(); |
|
611 |
int texH = mNodeTexture.getHeight(); |
|
561 | 612 |
|
562 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
613 |
if( (float)texH/texW > (float)screenHeight/screenWidth ) |
|
614 |
{ |
|
615 |
int w = (screenHeight*texW)/texH; |
|
616 |
float factor = (float)screenHeight/texH; |
|
617 |
mNodeMove.set((screenWidth-w)*0.5f ,0, 0); |
|
618 |
mNodeScale.set(factor,factor,factor); |
|
619 |
} |
|
620 |
else |
|
621 |
{ |
|
622 |
int h = (screenWidth*texH)/texW; |
|
623 |
float factor = (float)screenWidth/texW; |
|
624 |
mNodeMove.set(0,(screenHeight-h)*0.5f,0); |
|
625 |
mNodeScale.set(factor,factor,factor); |
|
626 |
} |
|
563 | 627 |
|
564 |
int getSize() |
|
565 |
{ |
|
566 |
return mSize; |
|
628 |
float scaleFactor = (size/(TEXTURE_SIZE*mSize)) * (float)texW/(screenWidth>screenHeight ? screenHeight:screenWidth); |
|
629 |
|
|
630 |
mMove.set( texW*0.5f , texH*0.5f , 0.0f ); |
|
631 |
mScale.set(scaleFactor,scaleFactor,scaleFactor); |
|
567 | 632 |
} |
568 | 633 |
} |
src/main/java/org/distorted/magic/RubikRenderer.java | ||
---|---|---|
210 | 210 |
|
211 | 211 |
public void effectFinished(final long effectID) |
212 | 212 |
{ |
213 |
if( effectID == mRotationFinishedID) |
|
213 |
if( effectID == mRotationFinishedID )
|
|
214 | 214 |
{ |
215 | 215 |
mRemoveRotation = true; |
216 | 216 |
} |
217 |
else if( effectID == mSizeChangeEffectID ) |
|
217 |
else if( effectID == mSizeChangeEffectID )
|
|
218 | 218 |
{ |
219 | 219 |
mCanRotate = true; |
220 | 220 |
mCanDrag = true; |
221 | 221 |
} |
222 |
else if( effectID == mUnscrambleEffectID ) |
|
222 |
else if( effectID == mUnscrambleEffectID )
|
|
223 | 223 |
{ |
224 | 224 |
mCanRotate = true; |
225 | 225 |
mCanDrag = true; |
226 | 226 |
} |
227 |
else if( effectID == mScrambleEffectID ) |
|
227 |
else if( effectID == mScrambleEffectID )
|
|
228 | 228 |
{ |
229 | 229 |
mCanRotate = true; |
230 | 230 |
mCanDrag = true; |
... | ... | |
368 | 368 |
try |
369 | 369 |
{ |
370 | 370 |
ScrambleEffect effect = ScrambleEffect.create(mScrambleType); |
371 |
mScrambleEffectID = effect.start(mScrambleDuration,mScreen,mNewCube,mScrambleCubeNum,this);
|
|
371 |
mScrambleEffectID = effect.start(mScrambleDuration,mNewCube,mScrambleCubeNum,this); |
|
372 | 372 |
} |
373 | 373 |
catch(Exception ex) |
374 | 374 |
{ |
src/main/java/org/distorted/magic/RubikSurfaceView.java | ||
---|---|---|
47 | 47 |
private final static int TOP = 4; // |
48 | 48 |
private final static int BOTTOM = 5; // |
49 | 49 |
|
50 |
static final int VECTX = 0; // |
|
51 |
static final int VECTY = 1; // don't change this |
|
52 |
static final int VECTZ = 2; // |
|
53 |
|
|
54 |
private static final int[] VECT = {VECTX,VECTY,VECTZ}; |
|
50 |
private static final int[] VECT = {RubikCube.VECTX,RubikCube.VECTY,RubikCube.VECTZ}; |
|
55 | 51 |
|
56 | 52 |
private boolean mDragging, mBeginningRotation, mContinuingRotation; |
57 | 53 |
private int mX, mY; |
... | ... | |
427 | 423 |
switch(face) |
428 | 424 |
{ |
429 | 425 |
case FRONT : |
430 |
case BACK : return VECTX; |
|
426 |
case BACK : return RubikCube.VECTX;
|
|
431 | 427 |
case LEFT : |
432 |
case RIGHT : return VECTZ; |
|
428 |
case RIGHT : return RubikCube.VECTZ;
|
|
433 | 429 |
case TOP : |
434 |
case BOTTOM: return VECTX; |
|
430 |
case BOTTOM: return RubikCube.VECTX;
|
|
435 | 431 |
} |
436 | 432 |
|
437 | 433 |
return -1; |
... | ... | |
444 | 440 |
switch(face) |
445 | 441 |
{ |
446 | 442 |
case FRONT : |
447 |
case BACK : return VECTY; |
|
443 |
case BACK : return RubikCube.VECTY;
|
|
448 | 444 |
case LEFT : |
449 |
case RIGHT : return VECTY; |
|
445 |
case RIGHT : return RubikCube.VECTY;
|
|
450 | 446 |
case TOP : |
451 |
case BOTTOM: return VECTZ; |
|
447 |
case BOTTOM: return RubikCube.VECTZ;
|
|
452 | 448 |
} |
453 | 449 |
|
454 | 450 |
return -1; |
... | ... | |
461 | 457 |
switch(face) |
462 | 458 |
{ |
463 | 459 |
case FRONT : |
464 |
case BACK : return VECTZ; |
|
460 |
case BACK : return RubikCube.VECTZ;
|
|
465 | 461 |
case LEFT : |
466 |
case RIGHT : return VECTX; |
|
462 |
case RIGHT : return RubikCube.VECTX;
|
|
467 | 463 |
case TOP : |
468 |
case BOTTOM: return VECTY; |
|
464 |
case BOTTOM: return RubikCube.VECTY;
|
|
469 | 465 |
} |
470 | 466 |
|
471 | 467 |
return -1; |
Also available in: Unified diff
RubikCube: progress with scrambling