Revision 7c111294
Added by Leszek Koltunski over 2 years ago
src/main/java/org/distorted/objectlib/helpers/BlockController.java | ||
---|---|---|
27 | 27 |
|
28 | 28 |
import org.distorted.library.message.EffectMessageSender; |
29 | 29 |
import org.distorted.objectlib.BuildConfig; |
30 |
import org.distorted.objectlib.main.ObjectPreRender; |
|
30 | 31 |
|
31 | 32 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
32 | 33 |
|
... | ... | |
140 | 141 |
|
141 | 142 |
if( act!=null ) |
142 | 143 |
{ |
143 |
TwistyPreRender pre = act.getTwistyPreRender();
|
|
144 |
ObjectPreRender pre = act.getPreRender();
|
|
144 | 145 |
if( pre!=null ) |
145 | 146 |
{ |
146 | 147 |
reallyBlocked = pre.isTouchBlocked(); |
... | ... | |
171 | 172 |
|
172 | 173 |
if( act!=null ) |
173 | 174 |
{ |
174 |
TwistyPreRender pre = act.getTwistyPreRender();
|
|
175 |
ObjectPreRender pre = act.getPreRender();
|
|
175 | 176 |
if( pre!=null ) |
176 | 177 |
{ |
177 | 178 |
reallyBlocked = !pre.isUINotBlocked(); |
src/main/java/org/distorted/objectlib/helpers/ObjectSurfaceView.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2021 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.objectlib.helpers; |
|
21 |
|
|
22 |
import org.distorted.library.main.DistortedScreen; |
|
23 |
import org.distorted.library.type.Static4D; |
|
24 |
import org.distorted.objectlib.main.Movement; |
|
25 |
|
|
26 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
27 |
|
|
28 |
public interface ObjectSurfaceView |
|
29 |
{ |
|
30 |
TwistyActivity getActivity(); |
|
31 |
void setMovement(Movement move); |
|
32 |
Static4D getQuat(); |
|
33 |
void setQuat(); |
|
34 |
DistortedScreen getScreen(); |
|
35 |
} |
src/main/java/org/distorted/objectlib/helpers/TwistyActivity.java | ||
---|---|---|
21 | 21 |
|
22 | 22 |
import androidx.appcompat.app.AppCompatActivity; |
23 | 23 |
|
24 |
import org.distorted.objectlib.main.ObjectPreRender; |
|
25 |
|
|
24 | 26 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
25 | 27 |
|
26 | 28 |
abstract public class TwistyActivity extends AppCompatActivity |
... | ... | |
29 | 31 |
|
30 | 32 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
31 | 33 |
|
32 |
public abstract TwistyPreRender getTwistyPreRender();
|
|
34 |
public abstract ObjectPreRender getPreRender();
|
|
33 | 35 |
|
34 | 36 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
35 | 37 |
|
src/main/java/org/distorted/objectlib/helpers/TwistyPreRender.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2021 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.objectlib.helpers; |
|
21 |
|
|
22 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
23 |
|
|
24 |
import org.distorted.objectlib.helpers.MovesFinished; |
|
25 |
|
|
26 |
public interface TwistyPreRender |
|
27 |
{ |
|
28 |
boolean isTouchBlocked(); |
|
29 |
boolean isUINotBlocked(); |
|
30 |
void blockTouch(int place); |
|
31 |
void unblockTouch(); |
|
32 |
void blockEverything(int place); |
|
33 |
void unblockEverything(); |
|
34 |
void unblockUI(); |
|
35 |
void addRotation(MovesFinished listener, int axis, int rowBitmap, int angle, long duration); |
|
36 |
void solveObject(); |
|
37 |
} |
src/main/java/org/distorted/objectlib/main/ObjectPreRender.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2020 Leszek Koltunski // |
|
3 |
// // |
|
4 |
// This file is part of Magic Cube. // |
|
5 |
// // |
|
6 |
// Magic Cube is free software: you can redistribute it and/or modify // |
|
7 |
// it under the terms of the GNU General Public License as published by // |
|
8 |
// the Free Software Foundation, either version 2 of the License, or // |
|
9 |
// (at your option) any later version. // |
|
10 |
// // |
|
11 |
// Magic Cube is distributed in the hope that it will be useful, // |
|
12 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of // |
|
13 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // |
|
14 |
// GNU General Public License for more details. // |
|
15 |
// // |
|
16 |
// You should have received a copy of the GNU General Public License // |
|
17 |
// along with Magic Cube. If not, see <http://www.gnu.org/licenses/>. // |
|
18 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
19 |
|
|
20 |
package org.distorted.objectlib.main; |
|
21 |
|
|
22 |
import android.content.SharedPreferences; |
|
23 |
import android.content.res.Resources; |
|
24 |
|
|
25 |
import org.distorted.objectlib.helpers.ObjectStateActioner; |
|
26 |
import org.distorted.objectlib.helpers.ObjectSurfaceView; |
|
27 |
import org.distorted.objectlib.effects.BaseEffect; |
|
28 |
import org.distorted.objectlib.effects.EffectController; |
|
29 |
import org.distorted.objectlib.effects.scramble.ScrambleEffect; |
|
30 |
import org.distorted.objectlib.helpers.BlockController; |
|
31 |
import org.distorted.objectlib.helpers.MovesFinished; |
|
32 |
|
|
33 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
34 |
|
|
35 |
public class ObjectPreRender implements EffectController |
|
36 |
{ |
|
37 |
private final ObjectSurfaceView mView; |
|
38 |
private ObjectType mNextObject; |
|
39 |
private TwistyObject mOldObject, mNewObject; |
|
40 |
private SharedPreferences mPreferences; |
|
41 |
private MovesFinished mAddActionListener; |
|
42 |
private final BlockController mBlockController; |
|
43 |
private final ObjectStateActioner mActioner; |
|
44 |
private String mDebug; |
|
45 |
|
|
46 |
private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation, |
|
47 |
mSetQuat, mChangeObject, mSetupObject, mSolveObject, mScrambleObject, |
|
48 |
mInitializeObject, mSetTextureMap, mResetAllTextureMaps, mSolve; |
|
49 |
private boolean mUIBlocked, mTouchBlocked, mIsSolved; |
|
50 |
private long mRotationFinishedID; |
|
51 |
private final long[] mEffectID; |
|
52 |
private int mScreenWidth; |
|
53 |
private int[][] mNextMoves; |
|
54 |
private int mScrambleObjectNum; |
|
55 |
private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle; |
|
56 |
private long mAddRotationDuration; |
|
57 |
private long mAddRotationID, mRemoveRotationID; |
|
58 |
private int mCubit, mFace, mNewColor; |
|
59 |
private int mNearestAngle; |
|
60 |
private long mDebugStartTime; |
|
61 |
|
|
62 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
63 |
|
|
64 |
public ObjectPreRender(ObjectSurfaceView view, ObjectStateActioner actioner) |
|
65 |
{ |
|
66 |
mView = view; |
|
67 |
mActioner = actioner; |
|
68 |
|
|
69 |
mFinishRotation = false; |
|
70 |
mRemoveRotation = false; |
|
71 |
mRemovePatternRotation= false; |
|
72 |
mAddRotation = false; |
|
73 |
mSetQuat = false; |
|
74 |
mChangeObject = false; |
|
75 |
mSetupObject = false; |
|
76 |
mSolveObject = false; |
|
77 |
mSolve = false; |
|
78 |
mScrambleObject = false; |
|
79 |
|
|
80 |
mOldObject = null; |
|
81 |
mNewObject = null; |
|
82 |
|
|
83 |
mDebug = ""; |
|
84 |
|
|
85 |
mScreenWidth = 0; |
|
86 |
mScrambleObjectNum = 0; |
|
87 |
|
|
88 |
mEffectID = new long[BaseEffect.Type.LENGTH]; |
|
89 |
|
|
90 |
mBlockController = new BlockController(mView.getActivity()); |
|
91 |
unblockEverything(); |
|
92 |
} |
|
93 |
|
|
94 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
95 |
|
|
96 |
private void createObjectNow(ObjectType object, int[][] moves) |
|
97 |
{ |
|
98 |
boolean firstTime = (mNewObject==null); |
|
99 |
|
|
100 |
if( mOldObject!=null ) mOldObject.releaseResources(); |
|
101 |
mOldObject = mNewObject; |
|
102 |
Resources res = mView.getActivity().getResources(); |
|
103 |
|
|
104 |
mNewObject = object.create(mView.getQuat(), moves, res, mScreenWidth); |
|
105 |
|
|
106 |
if( mNewObject!=null ) |
|
107 |
{ |
|
108 |
mView.setMovement(mNewObject.getMovement()); |
|
109 |
if( firstTime ) mNewObject.restorePreferences(mPreferences); |
|
110 |
mIsSolved = mNewObject.isSolved(); |
|
111 |
} |
|
112 |
} |
|
113 |
|
|
114 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
115 |
// do all 'adjustable' effects (SizeChange, Solve, Scramble) |
|
116 |
|
|
117 |
private void doEffectNow(BaseEffect.Type type) |
|
118 |
{ |
|
119 |
try |
|
120 |
{ |
|
121 |
int index = type.ordinal(); |
|
122 |
mEffectID[index] = type.startEffect(mView.getScreen(),this); |
|
123 |
} |
|
124 |
catch( Exception ex ) |
|
125 |
{ |
|
126 |
android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage()); |
|
127 |
unblockEverything(); |
|
128 |
} |
|
129 |
} |
|
130 |
|
|
131 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
132 |
|
|
133 |
private void removeRotationNow() |
|
134 |
{ |
|
135 |
mRemoveRotation=false; |
|
136 |
mNewObject.removeRotationNow(); |
|
137 |
|
|
138 |
boolean solved = mNewObject.isSolved(); |
|
139 |
|
|
140 |
if( solved && !mIsSolved ) |
|
141 |
{ |
|
142 |
mActioner.onSolved(); |
|
143 |
unblockEverything(); |
|
144 |
doEffectNow( BaseEffect.Type.WIN ); |
|
145 |
} |
|
146 |
else |
|
147 |
{ |
|
148 |
unblockEverything(); |
|
149 |
} |
|
150 |
|
|
151 |
mIsSolved = solved; |
|
152 |
} |
|
153 |
|
|
154 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
155 |
|
|
156 |
private void removeRotation() |
|
157 |
{ |
|
158 |
mRemoveRotation = true; |
|
159 |
} |
|
160 |
|
|
161 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
162 |
|
|
163 |
private void removePatternRotation() |
|
164 |
{ |
|
165 |
mRemovePatternRotation = true; |
|
166 |
} |
|
167 |
|
|
168 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
169 |
|
|
170 |
private void removePatternRotationNow() |
|
171 |
{ |
|
172 |
mRemovePatternRotation=false; |
|
173 |
mNewObject.removeRotationNow(); |
|
174 |
mAddActionListener.onActionFinished(mRemoveRotationID); |
|
175 |
} |
|
176 |
|
|
177 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
178 |
|
|
179 |
private void addRotationNow() |
|
180 |
{ |
|
181 |
mAddRotation = false; |
|
182 |
mAddRotationID = mNewObject.addNewRotation( mAddRotationAxis, mAddRotationRowBitmap, |
|
183 |
mAddRotationAngle, mAddRotationDuration, this); |
|
184 |
|
|
185 |
if( mAddRotationID==0 ) // failed to add effect - should never happen |
|
186 |
{ |
|
187 |
unblockEverything(); |
|
188 |
} |
|
189 |
} |
|
190 |
|
|
191 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
192 |
|
|
193 |
private void finishRotationNow() |
|
194 |
{ |
|
195 |
mFinishRotation = false; |
|
196 |
blockEverything(BlockController.RUBIK_PLACE_0); |
|
197 |
mRotationFinishedID = mNewObject.finishRotationNow(this, mNearestAngle); |
|
198 |
|
|
199 |
if( mRotationFinishedID==0 ) // failed to add effect - should never happen |
|
200 |
{ |
|
201 |
unblockEverything(); |
|
202 |
} |
|
203 |
} |
|
204 |
|
|
205 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
206 |
|
|
207 |
private void changeObjectNow() |
|
208 |
{ |
|
209 |
mChangeObject = false; |
|
210 |
|
|
211 |
if ( mNewObject==null || mNewObject.getObjectType()!=mNextObject ) |
|
212 |
{ |
|
213 |
blockEverything(BlockController.RUBIK_PLACE_1); |
|
214 |
createObjectNow(mNextObject, null); |
|
215 |
doEffectNow( BaseEffect.Type.SIZECHANGE ); |
|
216 |
} |
|
217 |
} |
|
218 |
|
|
219 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
220 |
|
|
221 |
private void setupObjectNow() |
|
222 |
{ |
|
223 |
mSetupObject = false; |
|
224 |
|
|
225 |
if ( mNewObject==null || mNewObject.getObjectType()!=mNextObject) |
|
226 |
{ |
|
227 |
blockEverything(BlockController.RUBIK_PLACE_2); |
|
228 |
createObjectNow(mNextObject, mNextMoves); |
|
229 |
doEffectNow( BaseEffect.Type.SIZECHANGE ); |
|
230 |
} |
|
231 |
else |
|
232 |
{ |
|
233 |
mNewObject.initializeObject(mNextMoves); |
|
234 |
} |
|
235 |
} |
|
236 |
|
|
237 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
238 |
|
|
239 |
private void scrambleObjectNow() |
|
240 |
{ |
|
241 |
mScrambleObject = false; |
|
242 |
mIsSolved = false; |
|
243 |
blockEverything(BlockController.RUBIK_PLACE_3); |
|
244 |
doEffectNow( BaseEffect.Type.SCRAMBLE ); |
|
245 |
} |
|
246 |
|
|
247 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
248 |
|
|
249 |
private void solveObjectNow() |
|
250 |
{ |
|
251 |
mSolveObject = false; |
|
252 |
blockEverything(BlockController.RUBIK_PLACE_4); |
|
253 |
doEffectNow( BaseEffect.Type.SOLVE ); |
|
254 |
} |
|
255 |
|
|
256 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
257 |
|
|
258 |
private void solveNow() |
|
259 |
{ |
|
260 |
mSolve = false; |
|
261 |
mNewObject.solve(); |
|
262 |
} |
|
263 |
|
|
264 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
265 |
|
|
266 |
private void initializeObjectNow() |
|
267 |
{ |
|
268 |
mInitializeObject = false; |
|
269 |
mNewObject.initializeObject(mNextMoves); |
|
270 |
} |
|
271 |
|
|
272 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
273 |
|
|
274 |
private void setTextureMapNow() |
|
275 |
{ |
|
276 |
mSetTextureMap = false; |
|
277 |
|
|
278 |
if( mNewObject!=null ) mNewObject.setTextureMap(mCubit,mFace,mNewColor); |
|
279 |
} |
|
280 |
|
|
281 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
282 |
|
|
283 |
private void resetAllTextureMapsNow() |
|
284 |
{ |
|
285 |
mResetAllTextureMaps = false; |
|
286 |
if( mNewObject!=null ) mNewObject.resetAllTextureMaps(); |
|
287 |
} |
|
288 |
|
|
289 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
290 |
|
|
291 |
private void setQuatNow() |
|
292 |
{ |
|
293 |
mSetQuat = false; |
|
294 |
mView.setQuat(); |
|
295 |
} |
|
296 |
|
|
297 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
298 |
// PUBLIC API |
|
299 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
300 |
|
|
301 |
public void rememberMove(int axis, int row, int angle) |
|
302 |
{ |
|
303 |
mDebug += (" (m "+axis+" "+(1<<row)+" "+angle+" "+(System.currentTimeMillis()-mDebugStartTime)+")"); |
|
304 |
} |
|
305 |
|
|
306 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
307 |
|
|
308 |
public void setScreenSize(int width) |
|
309 |
{ |
|
310 |
if( mNewObject!=null ) |
|
311 |
{ |
|
312 |
mNewObject.createTexture(); |
|
313 |
mNewObject.recomputeScaleFactor(width); |
|
314 |
} |
|
315 |
mScreenWidth = width; |
|
316 |
} |
|
317 |
|
|
318 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
319 |
|
|
320 |
public void savePreferences(SharedPreferences.Editor editor) |
|
321 |
{ |
|
322 |
if( mNewObject!=null ) |
|
323 |
{ |
|
324 |
mNewObject.savePreferences(editor); |
|
325 |
} |
|
326 |
} |
|
327 |
|
|
328 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
329 |
|
|
330 |
public void restorePreferences(SharedPreferences preferences) |
|
331 |
{ |
|
332 |
mPreferences = preferences; |
|
333 |
} |
|
334 |
|
|
335 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
336 |
|
|
337 |
public void finishRotation(int nearestAngle) |
|
338 |
{ |
|
339 |
mNearestAngle = nearestAngle; |
|
340 |
mFinishRotation = true; |
|
341 |
} |
|
342 |
|
|
343 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
344 |
|
|
345 |
public void changeObject(ObjectType object) |
|
346 |
{ |
|
347 |
mChangeObject = true; |
|
348 |
mNextObject = object; |
|
349 |
} |
|
350 |
|
|
351 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
352 |
|
|
353 |
public void setupObject(ObjectType object, int[][] moves) |
|
354 |
{ |
|
355 |
mSetupObject= true; |
|
356 |
mNextObject = object; |
|
357 |
mNextMoves = moves; |
|
358 |
} |
|
359 |
|
|
360 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
361 |
|
|
362 |
public void setTextureMap(int cubit, int face, int newColor) |
|
363 |
{ |
|
364 |
mSetTextureMap = true; |
|
365 |
|
|
366 |
mCubit = cubit; |
|
367 |
mFace = face; |
|
368 |
mNewColor = newColor; |
|
369 |
} |
|
370 |
|
|
371 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
372 |
|
|
373 |
public boolean isTouchBlocked() |
|
374 |
{ |
|
375 |
return mTouchBlocked; |
|
376 |
} |
|
377 |
|
|
378 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
379 |
|
|
380 |
public boolean isUINotBlocked() |
|
381 |
{ |
|
382 |
return !mUIBlocked; |
|
383 |
} |
|
384 |
|
|
385 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
386 |
|
|
387 |
public void blockEverything(int place) |
|
388 |
{ |
|
389 |
mUIBlocked = true; |
|
390 |
mTouchBlocked= true; |
|
391 |
mBlockController.touchBlocked(place); |
|
392 |
mBlockController.uiBlocked(place); |
|
393 |
} |
|
394 |
|
|
395 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
396 |
|
|
397 |
public void blockTouch(int place) |
|
398 |
{ |
|
399 |
mTouchBlocked= true; |
|
400 |
mBlockController.touchBlocked(place); |
|
401 |
} |
|
402 |
|
|
403 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
404 |
|
|
405 |
public void unblockEverything() |
|
406 |
{ |
|
407 |
mUIBlocked = false; |
|
408 |
mTouchBlocked= false; |
|
409 |
mBlockController.touchUnblocked(); |
|
410 |
mBlockController.uiUnblocked(); |
|
411 |
} |
|
412 |
|
|
413 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
414 |
|
|
415 |
public void unblockTouch() |
|
416 |
{ |
|
417 |
mTouchBlocked= false; |
|
418 |
mBlockController.touchUnblocked(); |
|
419 |
} |
|
420 |
|
|
421 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
422 |
|
|
423 |
public void unblockUI() |
|
424 |
{ |
|
425 |
mUIBlocked= false; |
|
426 |
mBlockController.uiUnblocked(); |
|
427 |
} |
|
428 |
|
|
429 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
430 |
|
|
431 |
public void setQuatOnNextRender() |
|
432 |
{ |
|
433 |
mSetQuat = true; |
|
434 |
} |
|
435 |
|
|
436 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
437 |
|
|
438 |
public void preRender() |
|
439 |
{ |
|
440 |
if( mSolve ) solveNow(); |
|
441 |
if( mSetQuat ) setQuatNow(); |
|
442 |
if( mFinishRotation ) finishRotationNow(); |
|
443 |
if( mRemoveRotation ) removeRotationNow(); |
|
444 |
if( mRemovePatternRotation ) removePatternRotationNow(); |
|
445 |
if( mChangeObject ) changeObjectNow(); |
|
446 |
if( mSetupObject ) setupObjectNow(); |
|
447 |
if( mSolveObject ) solveObjectNow(); |
|
448 |
if( mScrambleObject ) scrambleObjectNow(); |
|
449 |
if( mAddRotation ) addRotationNow(); |
|
450 |
if( mInitializeObject ) initializeObjectNow(); |
|
451 |
if( mResetAllTextureMaps ) resetAllTextureMapsNow(); |
|
452 |
if( mSetTextureMap ) setTextureMapNow(); |
|
453 |
} |
|
454 |
|
|
455 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
456 |
|
|
457 |
public void addRotation(MovesFinished listener, int axis, int rowBitmap, int angle, long duration) |
|
458 |
{ |
|
459 |
mAddRotation = true; |
|
460 |
|
|
461 |
mAddActionListener = listener; |
|
462 |
mAddRotationAxis = axis; |
|
463 |
mAddRotationRowBitmap = rowBitmap; |
|
464 |
mAddRotationAngle = angle; |
|
465 |
mAddRotationDuration = duration; |
|
466 |
|
|
467 |
if( listener instanceof ScrambleEffect ) |
|
468 |
{ |
|
469 |
mDebug += (" (a "+axis+" "+rowBitmap+" "+angle+" "+(System.currentTimeMillis()-mDebugStartTime)+")"); |
|
470 |
} |
|
471 |
} |
|
472 |
|
|
473 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
474 |
|
|
475 |
public void initializeObject(int[][] moves) |
|
476 |
{ |
|
477 |
mInitializeObject = true; |
|
478 |
mNextMoves = moves; |
|
479 |
} |
|
480 |
|
|
481 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
482 |
|
|
483 |
public void scrambleObject(int num) |
|
484 |
{ |
|
485 |
if( !mUIBlocked ) |
|
486 |
{ |
|
487 |
mScrambleObject = true; |
|
488 |
mScrambleObjectNum = num; |
|
489 |
mDebug = ""; |
|
490 |
mDebugStartTime = System.currentTimeMillis(); |
|
491 |
} |
|
492 |
} |
|
493 |
|
|
494 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
495 |
// this starts the Solve Effect |
|
496 |
|
|
497 |
public void solveObject() |
|
498 |
{ |
|
499 |
if( !mUIBlocked ) |
|
500 |
{ |
|
501 |
mSolveObject = true; |
|
502 |
} |
|
503 |
} |
|
504 |
|
|
505 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
506 |
// this only sets the cubits state to solved |
|
507 |
|
|
508 |
public void solve() |
|
509 |
{ |
|
510 |
mSolve = true; |
|
511 |
} |
|
512 |
|
|
513 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
514 |
|
|
515 |
public void resetAllTextureMaps() |
|
516 |
{ |
|
517 |
mResetAllTextureMaps = true; |
|
518 |
} |
|
519 |
|
|
520 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
521 |
|
|
522 |
public TwistyObject getObject() |
|
523 |
{ |
|
524 |
return mNewObject; |
|
525 |
} |
|
526 |
|
|
527 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
528 |
|
|
529 |
public TwistyObject getOldObject() |
|
530 |
{ |
|
531 |
return mOldObject; |
|
532 |
} |
|
533 |
|
|
534 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
535 |
|
|
536 |
public int getNumScrambles() |
|
537 |
{ |
|
538 |
return mScrambleObjectNum; |
|
539 |
} |
|
540 |
|
|
541 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
542 |
|
|
543 |
public void effectFinished(final long effectID) |
|
544 |
{ |
|
545 |
if( effectID == mRotationFinishedID ) |
|
546 |
{ |
|
547 |
mRotationFinishedID = 0; |
|
548 |
removeRotation(); |
|
549 |
} |
|
550 |
else if( effectID == mAddRotationID ) |
|
551 |
{ |
|
552 |
mAddRotationID = 0; |
|
553 |
mRemoveRotationID = effectID; |
|
554 |
removePatternRotation(); |
|
555 |
} |
|
556 |
else |
|
557 |
{ |
|
558 |
for(int i=0; i<BaseEffect.Type.LENGTH; i++) |
|
559 |
{ |
|
560 |
if( effectID == mEffectID[i] ) |
|
561 |
{ |
|
562 |
if( i!=BaseEffect.Type.WIN.ordinal() ) unblockEverything(); |
|
563 |
if( i==BaseEffect.Type.SCRAMBLE.ordinal() ) mActioner.onScrambleEffectFinished(mView.getActivity()); |
|
564 |
if( i==BaseEffect.Type.WIN.ordinal() ) mActioner.onWinEffectFinished(mView.getActivity(),mDebug,mScrambleObjectNum); |
|
565 |
break; |
|
566 |
} |
|
567 |
} |
|
568 |
} |
|
569 |
} |
|
570 |
} |
src/main/java/org/distorted/objectlib/main/TwistyObject.java | ||
---|---|---|
891 | 891 |
} |
892 | 892 |
|
893 | 893 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
894 |
// PUBLIC API
|
|
894 |
// INTERNAL API
|
|
895 | 895 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
896 | 896 |
|
897 |
public boolean isSolved()
|
|
897 |
public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
|
|
898 | 898 |
{ |
899 |
if( mSolvedFunctionIndex==0 ) return isSolved0(); |
|
900 |
if( mSolvedFunctionIndex==1 ) return isSolved1(); |
|
901 |
if( mSolvedFunctionIndex==2 ) return isSolved2(); |
|
902 |
if( mSolvedFunctionIndex==3 ) return isSolved3(); |
|
903 |
|
|
904 |
return false; |
|
899 |
mScrambler.randomizeNewScramble(scramble,rnd,curr,total); |
|
905 | 900 |
} |
906 | 901 |
|
907 | 902 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
908 |
// the getFaceColors + final black in a grid (so that we do not exceed the maximum texture size) |
|
909 | 903 |
|
910 |
public void createTexture()
|
|
904 |
public int getNodeSize()
|
|
911 | 905 |
{ |
912 |
Bitmap bitmap; |
|
906 |
return mNodeSize; |
|
907 |
} |
|
913 | 908 |
|
914 |
Paint paint = new Paint(); |
|
915 |
bitmap = Bitmap.createBitmap( mNumTexCols*TEXTURE_HEIGHT, mNumTexRows*TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888); |
|
916 |
Canvas canvas = new Canvas(bitmap); |
|
909 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
917 | 910 |
|
918 |
paint.setAntiAlias(true); |
|
919 |
paint.setTextAlign(Paint.Align.CENTER); |
|
920 |
paint.setStyle(Paint.Style.FILL); |
|
911 |
public void initializeObject(int[][] moves) |
|
912 |
{ |
|
913 |
solve(); |
|
914 |
setupPosition(moves); |
|
915 |
} |
|
921 | 916 |
|
922 |
paint.setColor(COLOR_BLACK); |
|
923 |
canvas.drawRect(0, 0, mNumTexCols*TEXTURE_HEIGHT, mNumTexRows*TEXTURE_HEIGHT, paint); |
|
917 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
924 | 918 |
|
925 |
int face = 0; |
|
926 |
FactorySticker factory = FactorySticker.getInstance(); |
|
919 |
public synchronized void removeRotationNow() |
|
920 |
{ |
|
921 |
float angle = getAngle(); |
|
922 |
double nearestAngleInRadians = angle*Math.PI/180; |
|
923 |
float sinA =-(float)Math.sin(nearestAngleInRadians*0.5); |
|
924 |
float cosA = (float)Math.cos(nearestAngleInRadians*0.5); |
|
925 |
float axisX = mAxis[mRotAxis].get0(); |
|
926 |
float axisY = mAxis[mRotAxis].get1(); |
|
927 |
float axisZ = mAxis[mRotAxis].get2(); |
|
928 |
Static4D quat = new Static4D( axisX*sinA, axisY*sinA, axisZ*sinA, cosA); |
|
927 | 929 |
|
928 |
for(int row=0; row<mNumTexRows; row++) |
|
929 |
for(int col=0; col<mNumTexCols; col++) |
|
930 |
mRotationAngle.removeAll(); |
|
931 |
mRotationAngleStatic.set0(0); |
|
932 |
|
|
933 |
for(int i=0; i<NUM_CUBITS; i++) |
|
934 |
if( belongsToRotation(i,mRotAxis,mRotRowBitmap) ) |
|
930 | 935 |
{ |
931 |
if( face>=NUM_TEXTURES ) break; |
|
932 |
ObjectSticker sticker = retSticker(face); |
|
933 |
factory.drawRoundedPolygon(canvas, paint, col*TEXTURE_HEIGHT, row*TEXTURE_HEIGHT, getColor(face%NUM_FACE_COLORS), sticker); |
|
934 |
face++; |
|
936 |
int index = CUBITS[i].removeRotationNow(quat); |
|
937 |
mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),index); |
|
935 | 938 |
} |
936 |
|
|
937 |
if( !mTexture.setTexture(bitmap) ) |
|
938 |
{ |
|
939 |
int max = DistortedLibrary.getMaxTextureSize(); |
|
940 |
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); |
|
941 |
crashlytics.log("failed to set texture of size "+bitmap.getWidth()+"x"+bitmap.getHeight()+" max is "+max); |
|
942 |
} |
|
943 | 939 |
} |
944 | 940 |
|
945 | 941 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
946 | 942 |
|
947 |
public void setObjectRatio(float sizeChange)
|
|
943 |
public long finishRotationNow(EffectListener listener, int nearestAngleInDegrees)
|
|
948 | 944 |
{ |
949 |
mObjectScreenRatio *= (1.0f+sizeChange)/2; |
|
950 |
|
|
951 |
if( mObjectScreenRatio>MAX_SIZE_CHANGE) mObjectScreenRatio = MAX_SIZE_CHANGE; |
|
952 |
if( mObjectScreenRatio<MIN_SIZE_CHANGE) mObjectScreenRatio = MIN_SIZE_CHANGE; |
|
945 |
if( wasRotateApplied() ) |
|
946 |
{ |
|
947 |
float angle = getAngle(); |
|
948 |
mRotationAngleStatic.set0(angle); |
|
949 |
mRotationAngleFinal.set0(nearestAngleInDegrees); |
|
950 |
mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-angle)*0.2f ); |
|
953 | 951 |
|
954 |
float scale = mObjectScreenRatio*mInitScreenRatio*mNodeSize/mRealSize; |
|
955 |
mObjectScale.set(scale,scale,scale); |
|
956 |
} |
|
952 |
mRotationAngle.setDuration(POST_ROTATION_MILLISEC); |
|
953 |
mRotationAngle.resetToBeginning(); |
|
954 |
mRotationAngle.removeAll(); |
|
955 |
mRotationAngle.add(mRotationAngleStatic); |
|
956 |
mRotationAngle.add(mRotationAngleMiddle); |
|
957 |
mRotationAngle.add(mRotationAngleFinal); |
|
958 |
mRotateEffect.notifyWhenFinished(listener); |
|
957 | 959 |
|
958 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
960 |
return mRotateEffect.getID(); |
|
961 |
} |
|
959 | 962 |
|
960 |
public float getObjectRatio() |
|
961 |
{ |
|
962 |
return mObjectScreenRatio*mInitScreenRatio; |
|
963 |
return 0; |
|
963 | 964 |
} |
964 | 965 |
|
965 | 966 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
966 | 967 |
|
967 |
public int getCubitFaceColorIndex(int cubit, int face)
|
|
968 |
public synchronized long addNewRotation( int axis, int rowBitmap, int angle, long durationMillis, EffectListener listener )
|
|
968 | 969 |
{ |
969 |
Static4D texMap = mMesh.getTextureMap(NUM_FACE_COLORS*cubit + face); |
|
970 |
if( wasRotateApplied() ) |
|
971 |
{ |
|
972 |
mRotAxis = axis; |
|
973 |
mRotRowBitmap= computeBitmapFromRow( rowBitmap,axis ); |
|
970 | 974 |
|
971 |
int x = (int)(texMap.get0()/texMap.get2()); |
|
972 |
int y = (int)(texMap.get1()/texMap.get3()); |
|
975 |
mRotationAngleStatic.set0(0.0f); |
|
976 |
mRotationAxis.set( mAxis[axis] ); |
|
977 |
mRotationAngle.setDuration(durationMillis); |
|
978 |
mRotationAngle.resetToBeginning(); |
|
979 |
mRotationAngle.add(new Static1D(0)); |
|
980 |
mRotationAngle.add(new Static1D(angle)); |
|
981 |
mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis*ObjectType.MAX_OBJECT_SIZE) , -1); |
|
982 |
mRotateEffect.notifyWhenFinished(listener); |
|
973 | 983 |
|
974 |
return (mNumTexRows-1-y)*NUM_STICKERS_IN_ROW + x; |
|
984 |
return mRotateEffect.getID(); |
|
985 |
} |
|
986 |
|
|
987 |
return 0; |
|
975 | 988 |
} |
976 | 989 |
|
977 | 990 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
978 | 991 |
|
979 |
public int getNumLayers()
|
|
992 |
public void setTextureMap(int cubit, int face, int newColor)
|
|
980 | 993 |
{ |
981 |
return mNumLayers; |
|
994 |
final float ratioW = 1.0f/mNumTexCols; |
|
995 |
final float ratioH = 1.0f/mNumTexRows; |
|
996 |
final Static4D[] maps = new Static4D[mNumCubitFaces]; |
|
997 |
int row = (mNumTexRows-1) - newColor/mNumTexCols; |
|
998 |
int col = newColor%mNumTexCols; |
|
999 |
|
|
1000 |
maps[face] = new Static4D( col*ratioW, row*ratioH, ratioW, ratioH); |
|
1001 |
mMesh.setTextureMap(maps,mNumCubitFaces*cubit); |
|
982 | 1002 |
} |
983 | 1003 |
|
984 | 1004 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
985 | 1005 |
|
986 |
public void continueRotation(float angleInDegrees)
|
|
1006 |
public void resetAllTextureMaps()
|
|
987 | 1007 |
{ |
988 |
mRotationAngleStatic.set0(angleInDegrees); |
|
989 |
} |
|
990 |
|
|
991 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1008 |
final float ratioW = 1.0f/mNumTexCols; |
|
1009 |
final float ratioH = 1.0f/mNumTexRows; |
|
1010 |
int color, row, col; |
|
992 | 1011 |
|
993 |
public Static4D getRotationQuat()
|
|
1012 |
for(int cubit=0; cubit<NUM_CUBITS; cubit++)
|
|
994 | 1013 |
{ |
995 |
return mQuat; |
|
996 |
} |
|
1014 |
final Static4D[] maps = new Static4D[mNumCubitFaces]; |
|
997 | 1015 |
|
998 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1016 |
for(int cubitface=0; cubitface<mNumCubitFaces; cubitface++) |
|
1017 |
{ |
|
1018 |
color = getFaceColor(cubit,cubitface,mNumLayers); |
|
1019 |
row = (mNumTexRows-1) - color/mNumTexCols; |
|
1020 |
col = color%mNumTexCols; |
|
1021 |
maps[cubitface] = new Static4D( col*ratioW, row*ratioH, ratioW, ratioH); |
|
1022 |
} |
|
999 | 1023 |
|
1000 |
public void recomputeScaleFactor(int scrWidth) |
|
1001 |
{ |
|
1002 |
mNodeScale.set(scrWidth,NODE_RATIO*scrWidth,scrWidth); |
|
1024 |
mMesh.setTextureMap(maps,mNumCubitFaces*cubit); |
|
1025 |
} |
|
1003 | 1026 |
} |
1004 | 1027 |
|
1005 | 1028 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1006 | 1029 |
|
1007 |
public void savePreferences(SharedPreferences.Editor editor)
|
|
1030 |
public void releaseResources()
|
|
1008 | 1031 |
{ |
1009 |
for(int i=0; i<NUM_CUBITS; i++) CUBITS[i].savePreferences(editor); |
|
1032 |
mTexture.markForDeletion(); |
|
1033 |
mMesh.markForDeletion(); |
|
1034 |
mEffects.markForDeletion(); |
|
1035 |
|
|
1036 |
for(int j=0; j<NUM_CUBITS; j++) |
|
1037 |
{ |
|
1038 |
CUBITS[j].releaseResources(); |
|
1039 |
} |
|
1010 | 1040 |
} |
1011 | 1041 |
|
1012 | 1042 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
1043 | 1073 |
|
1044 | 1074 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1045 | 1075 |
|
1046 |
public void releaseResources() |
|
1047 |
{ |
|
1048 |
mTexture.markForDeletion(); |
|
1049 |
mMesh.markForDeletion(); |
|
1050 |
mEffects.markForDeletion(); |
|
1051 |
|
|
1052 |
for(int j=0; j<NUM_CUBITS; j++) |
|
1053 |
{ |
|
1054 |
CUBITS[j].releaseResources(); |
|
1055 |
} |
|
1056 |
} |
|
1057 |
|
|
1058 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1059 |
|
|
1060 |
public void apply(Effect effect, int position) |
|
1076 |
public void savePreferences(SharedPreferences.Editor editor) |
|
1061 | 1077 |
{ |
1062 |
mEffects.apply(effect, position);
|
|
1078 |
for(int i=0; i<NUM_CUBITS; i++) CUBITS[i].savePreferences(editor);
|
|
1063 | 1079 |
} |
1064 | 1080 |
|
1065 | 1081 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1066 | 1082 |
|
1067 |
public void remove(long effectID)
|
|
1083 |
public void recomputeScaleFactor(int scrWidth)
|
|
1068 | 1084 |
{ |
1069 |
mEffects.abortById(effectID);
|
|
1085 |
mNodeScale.set(scrWidth,NODE_RATIO*scrWidth,scrWidth);
|
|
1070 | 1086 |
} |
1071 | 1087 |
|
1072 | 1088 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1073 | 1089 |
|
1074 |
public synchronized void solve() |
|
1075 |
{ |
|
1076 |
for(int i=0; i<NUM_CUBITS; i++) |
|
1090 |
public Static4D getRotationQuat() |
|
1077 | 1091 |
{ |
1078 |
CUBITS[i].solve(); |
|
1079 |
mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0); |
|
1092 |
return mQuat; |
|
1080 | 1093 |
} |
1081 |
} |
|
1082 | 1094 |
|
1083 | 1095 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1096 |
// the getFaceColors + final black in a grid (so that we do not exceed the maximum texture size) |
|
1084 | 1097 |
|
1085 |
public void resetAllTextureMaps()
|
|
1098 |
public void createTexture()
|
|
1086 | 1099 |
{ |
1087 |
final float ratioW = 1.0f/mNumTexCols; |
|
1088 |
final float ratioH = 1.0f/mNumTexRows; |
|
1089 |
int color, row, col; |
|
1100 |
Bitmap bitmap; |
|
1090 | 1101 |
|
1091 |
for(int cubit=0; cubit<NUM_CUBITS; cubit++)
|
|
1092 |
{
|
|
1093 |
final Static4D[] maps = new Static4D[mNumCubitFaces];
|
|
1102 |
Paint paint = new Paint();
|
|
1103 |
bitmap = Bitmap.createBitmap( mNumTexCols*TEXTURE_HEIGHT, mNumTexRows*TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
|
|
1104 |
Canvas canvas = new Canvas(bitmap);
|
|
1094 | 1105 |
|
1095 |
for(int cubitface=0; cubitface<mNumCubitFaces; cubitface++) |
|
1106 |
paint.setAntiAlias(true); |
|
1107 |
paint.setTextAlign(Paint.Align.CENTER); |
|
1108 |
paint.setStyle(Paint.Style.FILL); |
|
1109 |
|
|
1110 |
paint.setColor(COLOR_BLACK); |
|
1111 |
canvas.drawRect(0, 0, mNumTexCols*TEXTURE_HEIGHT, mNumTexRows*TEXTURE_HEIGHT, paint); |
|
1112 |
|
|
1113 |
int face = 0; |
|
1114 |
FactorySticker factory = FactorySticker.getInstance(); |
|
1115 |
|
|
1116 |
for(int row=0; row<mNumTexRows; row++) |
|
1117 |
for(int col=0; col<mNumTexCols; col++) |
|
1096 | 1118 |
{ |
1097 |
color = getFaceColor(cubit,cubitface,mNumLayers);
|
|
1098 |
row = (mNumTexRows-1) - color/mNumTexCols;
|
|
1099 |
col = color%mNumTexCols;
|
|
1100 |
maps[cubitface] = new Static4D( col*ratioW, row*ratioH, ratioW, ratioH);
|
|
1119 |
if( face>=NUM_TEXTURES ) break;
|
|
1120 |
ObjectSticker sticker = retSticker(face);
|
|
1121 |
factory.drawRoundedPolygon(canvas, paint, col*TEXTURE_HEIGHT, row*TEXTURE_HEIGHT, getColor(face%NUM_FACE_COLORS), sticker);
|
|
1122 |
face++;
|
|
1101 | 1123 |
} |
1102 | 1124 |
|
1103 |
mMesh.setTextureMap(maps,mNumCubitFaces*cubit); |
|
1125 |
if( !mTexture.setTexture(bitmap) ) |
|
1126 |
{ |
|
1127 |
int max = DistortedLibrary.getMaxTextureSize(); |
|
1128 |
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); |
|
1129 |
crashlytics.log("failed to set texture of size "+bitmap.getWidth()+"x"+bitmap.getHeight()+" max is "+max); |
|
1104 | 1130 |
} |
1105 | 1131 |
} |
1106 | 1132 |
|
1133 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1134 |
// PUBLIC API |
|
1107 | 1135 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1108 | 1136 |
|
1109 |
public void setTextureMap(int cubit, int face, int newColor)
|
|
1137 |
public boolean isSolved()
|
|
1110 | 1138 |
{ |
1111 |
final float ratioW = 1.0f/mNumTexCols; |
|
1112 |
final float ratioH = 1.0f/mNumTexRows; |
|
1113 |
final Static4D[] maps = new Static4D[mNumCubitFaces]; |
|
1114 |
int row = (mNumTexRows-1) - newColor/mNumTexCols; |
|
1115 |
int col = newColor%mNumTexCols; |
|
1139 |
if( mSolvedFunctionIndex==0 ) return isSolved0(); |
|
1140 |
if( mSolvedFunctionIndex==1 ) return isSolved1(); |
|
1141 |
if( mSolvedFunctionIndex==2 ) return isSolved2(); |
|
1142 |
if( mSolvedFunctionIndex==3 ) return isSolved3(); |
|
1116 | 1143 |
|
1117 |
maps[face] = new Static4D( col*ratioW, row*ratioH, ratioW, ratioH); |
|
1118 |
mMesh.setTextureMap(maps,mNumCubitFaces*cubit); |
|
1144 |
return false; |
|
1119 | 1145 |
} |
1120 | 1146 |
|
1121 | 1147 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1122 | 1148 |
|
1123 |
public synchronized void beginNewRotation(int axis, int row )
|
|
1149 |
public void setObjectRatio(float sizeChange)
|
|
1124 | 1150 |
{ |
1125 |
if( axis<0 || axis>=NUM_AXIS ) |
|
1126 |
{ |
|
1127 |
android.util.Log.e("object", "invalid rotation axis: "+axis); |
|
1128 |
return; |
|
1129 |
} |
|
1130 |
if( row<0 || row>=mNumLayers ) |
|
1131 |
{ |
|
1132 |
android.util.Log.e("object", "invalid rotation row: "+row); |
|
1133 |
return; |
|
1134 |
} |
|
1151 |
mObjectScreenRatio *= (1.0f+sizeChange)/2; |
|
1135 | 1152 |
|
1136 |
mRotAxis = axis; |
|
1137 |
mRotRowBitmap= computeBitmapFromRow( (1<<row),axis ); |
|
1138 |
mRotationAngleStatic.set0(0.0f); |
|
1139 |
mRotationAxis.set( mAxis[axis] ); |
|
1140 |
mRotationAngle.add(mRotationAngleStatic); |
|
1141 |
mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis*ObjectType.MAX_OBJECT_SIZE) , -1); |
|
1153 |
if( mObjectScreenRatio>MAX_SIZE_CHANGE) mObjectScreenRatio = MAX_SIZE_CHANGE; |
|
1154 |
if( mObjectScreenRatio<MIN_SIZE_CHANGE) mObjectScreenRatio = MIN_SIZE_CHANGE; |
|
1155 |
|
|
1156 |
float scale = mObjectScreenRatio*mInitScreenRatio*mNodeSize/mRealSize; |
|
1157 |
mObjectScale.set(scale,scale,scale); |
|
1142 | 1158 |
} |
1143 | 1159 |
|
1144 | 1160 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1145 | 1161 |
|
1146 |
public synchronized long addNewRotation( int axis, int rowBitmap, int angle, long durationMillis, EffectListener listener )
|
|
1162 |
public float getObjectRatio()
|
|
1147 | 1163 |
{ |
1148 |
if( wasRotateApplied() ) |
|
1149 |
{ |
|
1150 |
mRotAxis = axis; |
|
1151 |
mRotRowBitmap= computeBitmapFromRow( rowBitmap,axis ); |
|
1164 |
return mObjectScreenRatio*mInitScreenRatio; |
|
1165 |
} |
|
1152 | 1166 |
|
1153 |
mRotationAngleStatic.set0(0.0f); |
|
1154 |
mRotationAxis.set( mAxis[axis] ); |
|
1155 |
mRotationAngle.setDuration(durationMillis); |
|
1156 |
mRotationAngle.resetToBeginning(); |
|
1157 |
mRotationAngle.add(new Static1D(0)); |
|
1158 |
mRotationAngle.add(new Static1D(angle)); |
|
1159 |
mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis*ObjectType.MAX_OBJECT_SIZE) , -1); |
|
1160 |
mRotateEffect.notifyWhenFinished(listener); |
|
1167 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1161 | 1168 |
|
1162 |
return mRotateEffect.getID(); |
|
1163 |
} |
|
1169 |
public int getCubitFaceColorIndex(int cubit, int face) |
|
1170 |
{ |
|
1171 |
Static4D texMap = mMesh.getTextureMap(NUM_FACE_COLORS*cubit + face); |
|
1164 | 1172 |
|
1165 |
return 0; |
|
1173 |
int x = (int)(texMap.get0()/texMap.get2()); |
|
1174 |
int y = (int)(texMap.get1()/texMap.get3()); |
|
1175 |
|
|
1176 |
return (mNumTexRows-1-y)*NUM_STICKERS_IN_ROW + x; |
|
1166 | 1177 |
} |
1167 | 1178 |
|
1168 | 1179 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1169 | 1180 |
|
1170 |
public long finishRotationNow(EffectListener listener, int nearestAngleInDegrees)
|
|
1181 |
public int getNumLayers()
|
|
1171 | 1182 |
{ |
1172 |
if( wasRotateApplied() ) |
|
1173 |
{ |
|
1174 |
float angle = getAngle(); |
|
1175 |
mRotationAngleStatic.set0(angle); |
|
1176 |
mRotationAngleFinal.set0(nearestAngleInDegrees); |
|
1177 |
mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-angle)*0.2f ); |
|
1183 |
return mNumLayers; |
|
1184 |
} |
|
1178 | 1185 |
|
1179 |
mRotationAngle.setDuration(POST_ROTATION_MILLISEC); |
|
1180 |
mRotationAngle.resetToBeginning(); |
|
1181 |
mRotationAngle.removeAll(); |
|
1182 |
mRotationAngle.add(mRotationAngleStatic); |
|
1183 |
mRotationAngle.add(mRotationAngleMiddle); |
|
1184 |
mRotationAngle.add(mRotationAngleFinal); |
|
1185 |
mRotateEffect.notifyWhenFinished(listener); |
|
1186 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1186 | 1187 |
|
1187 |
return mRotateEffect.getID(); |
|
1188 |
} |
|
1188 |
public void continueRotation(float angleInDegrees) |
|
1189 |
{ |
|
1190 |
mRotationAngleStatic.set0(angleInDegrees); |
|
1191 |
} |
|
1189 | 1192 |
|
1190 |
return 0; |
|
1193 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1194 |
|
|
1195 |
public void apply(Effect effect, int position) |
|
1196 |
{ |
|
1197 |
mEffects.apply(effect, position); |
|
1191 | 1198 |
} |
1192 | 1199 |
|
1193 | 1200 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1194 | 1201 |
|
1195 |
public synchronized void removeRotationNow()
|
|
1202 |
public void remove(long effectID)
|
|
1196 | 1203 |
{ |
1197 |
float angle = getAngle(); |
|
1198 |
double nearestAngleInRadians = angle*Math.PI/180; |
|
1199 |
float sinA =-(float)Math.sin(nearestAngleInRadians*0.5); |
|
1200 |
float cosA = (float)Math.cos(nearestAngleInRadians*0.5); |
|
1201 |
float axisX = mAxis[mRotAxis].get0(); |
|
1202 |
float axisY = mAxis[mRotAxis].get1(); |
|
1203 |
float axisZ = mAxis[mRotAxis].get2(); |
|
1204 |
Static4D quat = new Static4D( axisX*sinA, axisY*sinA, axisZ*sinA, cosA); |
|
1204 |
mEffects.abortById(effectID); |
|
1205 |
} |
|
1205 | 1206 |
|
1206 |
mRotationAngle.removeAll(); |
|
1207 |
mRotationAngleStatic.set0(0); |
|
1207 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1208 | 1208 |
|
1209 |
public synchronized void solve() |
|
1210 |
{ |
|
1209 | 1211 |
for(int i=0; i<NUM_CUBITS; i++) |
1210 |
if( belongsToRotation(i,mRotAxis,mRotRowBitmap) ) |
|
1211 |
{ |
|
1212 |
int index = CUBITS[i].removeRotationNow(quat); |
|
1213 |
mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),index); |
|
1214 |
} |
|
1212 |
{ |
|
1213 |
CUBITS[i].solve(); |
|
1214 |
mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0); |
|
1215 |
} |
|
1215 | 1216 |
} |
1216 | 1217 |
|
1217 | 1218 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1218 | 1219 |
|
1219 |
public void initializeObject(int[][] moves)
|
|
1220 |
public synchronized void beginNewRotation(int axis, int row )
|
|
1220 | 1221 |
{ |
1221 |
solve(); |
|
1222 |
setupPosition(moves); |
|
1222 |
if( axis<0 || axis>=NUM_AXIS ) |
|
1223 |
{ |
|
1224 |
android.util.Log.e("object", "invalid rotation axis: "+axis); |
|
1225 |
return; |
|
1226 |
} |
|
1227 |
if( row<0 || row>=mNumLayers ) |
|
1228 |
{ |
|
1229 |
android.util.Log.e("object", "invalid rotation row: "+row); |
|
1230 |
return; |
|
1231 |
} |
|
1232 |
|
|
1233 |
mRotAxis = axis; |
|
1234 |
mRotRowBitmap= computeBitmapFromRow( (1<<row),axis ); |
|
1235 |
mRotationAngleStatic.set0(0.0f); |
|
1236 |
mRotationAxis.set( mAxis[axis] ); |
|
1237 |
mRotationAngle.add(mRotationAngleStatic); |
|
1238 |
mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis*ObjectType.MAX_OBJECT_SIZE) , -1); |
|
1223 | 1239 |
} |
1224 | 1240 |
|
1225 | 1241 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
1270 | 1286 |
return mCameraDist; |
1271 | 1287 |
} |
1272 | 1288 |
|
1273 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1274 |
|
|
1275 |
public int getNodeSize() |
|
1276 |
{ |
|
1277 |
return mNodeSize; |
|
1278 |
} |
|
1279 |
|
|
1280 | 1289 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1281 | 1290 |
|
1282 | 1291 |
public ObjectType getObjectType() |
... | ... | |
1284 | 1293 |
return intGetObjectType(mNumLayers); |
1285 | 1294 |
} |
1286 | 1295 |
|
1287 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1288 |
|
|
1289 |
public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total) |
|
1290 |
{ |
|
1291 |
mScrambler.randomizeNewScramble(scramble,rnd,curr,total); |
|
1292 |
} |
|
1293 |
|
|
1294 | 1296 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1295 | 1297 |
|
1296 | 1298 |
protected abstract int getFOV(); |
... | ... | |
1314 | 1316 |
protected abstract int getFaceColor(int cubit, int cubitface, int numLayers); |
1315 | 1317 |
protected abstract int getResource(int mNumLayers); |
1316 | 1318 |
protected abstract ObjectType intGetObjectType(int numLayers); |
1319 |
protected abstract Movement getMovement(); |
|
1317 | 1320 |
|
1318 |
public abstract Movement getMovement(); |
|
1319 | 1321 |
public abstract Static3D[] getRotationAxis(); |
1320 | 1322 |
public abstract int[] getBasicAngle(); |
1321 | 1323 |
public abstract int getObjectName(int numLayers); |
Also available in: Unified diff
Move PreRender to objectlib.
This code is now shared betweeen the Rubik and Tutorial activities.