Revision 880beeea
Added by Leszek Koltunski over 2 years ago
src/main/java/org/distorted/objectlib/helpers/ObjectStateActioner.java | ||
---|---|---|
21 | 21 |
|
22 | 22 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
23 | 23 |
|
24 |
import org.distorted.objectlib.main.ObjectType; |
|
25 |
|
|
24 | 26 |
public interface ObjectStateActioner |
25 | 27 |
{ |
26 | 28 |
void onWinEffectFinished(TwistyActivity act, String debug, int scrambleNum); |
27 | 29 |
void onScrambleEffectFinished(TwistyActivity act); |
30 |
void onBeginRotation(TwistyActivity act); |
|
31 |
void onFinishRotation(TwistyActivity act, int axis, int row, int angle); |
|
32 |
void failedToDrag(TwistyActivity act); |
|
33 |
int getCurrentColor(); |
|
34 |
int cubitIsLocked(ObjectType type, int cubit); |
|
28 | 35 |
void onSolved(); |
29 | 36 |
} |
src/main/java/org/distorted/objectlib/helpers/TwistyActivity.java | ||
---|---|---|
32 | 32 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
33 | 33 |
|
34 | 34 |
public abstract ObjectPreRender getPreRender(); |
35 |
public abstract boolean isLocked(); |
|
35 | 36 |
|
36 | 37 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
37 | 38 |
|
src/main/java/org/distorted/objectlib/main/ObjectControl.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2019 Leszek Koltunski // |
|
3 |
// // |
|
4 |
// This file is part of Magic Cube. // |
|
5 |
// // |
|
6 |
// Magic Cube is free software: you can redistribute it and/or modify // |
|
7 |
// it under the terms of the GNU General Public License as published by // |
|
8 |
// the Free Software Foundation, either version 2 of the License, or // |
|
9 |
// (at your option) any later version. // |
|
10 |
// // |
|
11 |
// Magic Cube is distributed in the hope that it will be useful, // |
|
12 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of // |
|
13 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // |
|
14 |
// GNU General Public License for more details. // |
|
15 |
// // |
|
16 |
// You should have received a copy of the GNU General Public License // |
|
17 |
// along with Magic Cube. If not, see <http://www.gnu.org/licenses/>. // |
|
18 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
19 |
|
|
20 |
package org.distorted.objectlib.main; |
|
21 |
|
|
22 |
import java.lang.ref.WeakReference; |
|
23 |
|
|
24 |
import android.util.DisplayMetrics; |
|
25 |
import android.view.MotionEvent; |
|
26 |
|
|
27 |
import org.distorted.library.main.QuatHelper; |
|
28 |
import org.distorted.library.type.Static2D; |
|
29 |
import org.distorted.library.type.Static4D; |
|
30 |
|
|
31 |
import org.distorted.objectlib.helpers.ObjectStateActioner; |
|
32 |
import org.distorted.objectlib.helpers.ObjectSurfaceView; |
|
33 |
import org.distorted.objectlib.helpers.TwistyActivity; |
|
34 |
|
|
35 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
36 |
|
|
37 |
public class ObjectControl |
|
38 |
{ |
|
39 |
public static final int NUM_SPEED_PROBES = 10; |
|
40 |
public static final int INVALID_POINTER_ID = -1; |
|
41 |
|
|
42 |
public static final int MODE_ROTATE = 0; |
|
43 |
public static final int MODE_DRAG = 1; |
|
44 |
public static final int MODE_REPLACE = 2; |
|
45 |
|
|
46 |
// Moving the finger from the middle of the vertical screen to the right edge will rotate a |
|
47 |
// given face by SWIPING_SENSITIVITY/2 degrees. |
|
48 |
public final static int SWIPING_SENSITIVITY = 240; |
|
49 |
// Moving the finger by 0.3 of an inch will start a Rotation. |
|
50 |
public final static float ROTATION_SENSITIVITY = 0.3f; |
|
51 |
|
|
52 |
private final Static4D CAMERA_POINT = new Static4D(0, 0, 0, 0); |
|
53 |
|
|
54 |
private final WeakReference<TwistyActivity> mAct; |
|
55 |
private final ObjectStateActioner mActioner; |
|
56 |
private final ObjectPreRender mPreRender; |
|
57 |
private Movement mMovement; |
|
58 |
private boolean mDragging, mBeginningRotation, mContinuingRotation; |
|
59 |
private int mScreenWidth, mScreenHeight, mScreenMin; |
|
60 |
|
|
61 |
private float mRotAngle, mInitDistance; |
|
62 |
private float mStartRotX, mStartRotY; |
|
63 |
private float mAxisX, mAxisY; |
|
64 |
private float mRotationFactor; |
|
65 |
private int mLastCubitColor, mLastCubitFace, mLastCubit; |
|
66 |
private int mCurrentAxis, mCurrentRow; |
|
67 |
private float mCurrentAngle, mCurrRotSpeed; |
|
68 |
private final float[] mLastX; |
|
69 |
private final float[] mLastY; |
|
70 |
private final long[] mLastT; |
|
71 |
private int mFirstIndex, mLastIndex; |
|
72 |
private final int mDensity; |
|
73 |
|
|
74 |
private int mPointer1, mPointer2; |
|
75 |
private float mX1, mY1, mX2, mY2, mX, mY; |
|
76 |
private boolean mIsAutomatic; |
|
77 |
|
|
78 |
private static final Static4D mQuat= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f); |
|
79 |
private static final Static4D mTemp= new Static4D(0,0,0,1); |
|
80 |
|
|
81 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
82 |
// cast the 3D axis we are currently rotating along (which is already casted to the surface of the |
|
83 |
// currently touched face AND converted into a 4D vector - fourth 0) to a 2D in-screen-surface axis |
|
84 |
|
|
85 |
private void computeCurrentAxis(Static4D axis) |
|
86 |
{ |
|
87 |
Static4D result = QuatHelper.rotateVectorByQuat(axis, mQuat); |
|
88 |
|
|
89 |
mAxisX =result.get0(); |
|
90 |
mAxisY =result.get1(); |
|
91 |
|
|
92 |
float len = (float)Math.sqrt(mAxisX*mAxisX + mAxisY*mAxisY); |
|
93 |
mAxisX /= len; |
|
94 |
mAxisY /= len; |
|
95 |
} |
|
96 |
|
|
97 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
98 |
|
|
99 |
private void addSpeedProbe(float x, float y) |
|
100 |
{ |
|
101 |
long currTime = System.currentTimeMillis(); |
|
102 |
boolean theSame = mLastIndex==mFirstIndex; |
|
103 |
|
|
104 |
mLastIndex++; |
|
105 |
if( mLastIndex>=NUM_SPEED_PROBES ) mLastIndex=0; |
|
106 |
|
|
107 |
mLastT[mLastIndex] = currTime; |
|
108 |
mLastX[mLastIndex] = x; |
|
109 |
mLastY[mLastIndex] = y; |
|
110 |
|
|
111 |
if( mLastIndex==mFirstIndex) |
|
112 |
{ |
|
113 |
mFirstIndex++; |
|
114 |
if( mFirstIndex>=NUM_SPEED_PROBES ) mFirstIndex=0; |
|
115 |
} |
|
116 |
|
|
117 |
if( theSame ) |
|
118 |
{ |
|
119 |
mLastT[mFirstIndex] = currTime; |
|
120 |
mLastX[mFirstIndex] = x; |
|
121 |
mLastY[mFirstIndex] = y; |
|
122 |
} |
|
123 |
} |
|
124 |
|
|
125 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
126 |
|
|
127 |
private void computeCurrentSpeedInInchesPerSecond() |
|
128 |
{ |
|
129 |
long firstTime = mLastT[mFirstIndex]; |
|
130 |
long lastTime = mLastT[mLastIndex]; |
|
131 |
float fX = mLastX[mFirstIndex]; |
|
132 |
float fY = mLastY[mFirstIndex]; |
|
133 |
float lX = mLastX[mLastIndex]; |
|
134 |
float lY = mLastY[mLastIndex]; |
|
135 |
|
|
136 |
long timeDiff = lastTime-firstTime; |
|
137 |
|
|
138 |
mLastIndex = 0; |
|
139 |
mFirstIndex= 0; |
|
140 |
|
|
141 |
mCurrRotSpeed = timeDiff>0 ? 1000*retFingerDragDistanceInInches(fX,fY,lX,lY)/timeDiff : 0; |
|
142 |
} |
|
143 |
|
|
144 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
145 |
|
|
146 |
private float retFingerDragDistanceInInches(float xFrom, float yFrom, float xTo, float yTo) |
|
147 |
{ |
|
148 |
float xDist = mScreenWidth*(xFrom-xTo); |
|
149 |
float yDist = mScreenHeight*(yFrom-yTo); |
|
150 |
float distInPixels = (float)Math.sqrt(xDist*xDist + yDist*yDist); |
|
151 |
|
|
152 |
return distInPixels/mDensity; |
|
153 |
} |
|
154 |
|
|
155 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
156 |
|
|
157 |
private void setUpDragOrRotate(boolean down, float x, float y, int mode) |
|
158 |
{ |
|
159 |
if( mode==MODE_DRAG ) |
|
160 |
{ |
|
161 |
mDragging = true; |
|
162 |
mBeginningRotation = false; |
|
163 |
mContinuingRotation = false; |
|
164 |
} |
|
165 |
else |
|
166 |
{ |
|
167 |
TwistyObject object = mPreRender.getObject(); |
|
168 |
CAMERA_POINT.set2( object==null ? 1.21f : object.getCameraDist() ); |
|
169 |
|
|
170 |
Static4D touchPoint = new Static4D(x, y, 0, 0); |
|
171 |
Static4D rotatedTouchPoint= QuatHelper.rotateVectorByInvertedQuat(touchPoint, mQuat); |
|
172 |
Static4D rotatedCamera= QuatHelper.rotateVectorByInvertedQuat(CAMERA_POINT, mQuat); |
|
173 |
|
|
174 |
if( object!=null && mMovement!=null && mMovement.faceTouched(rotatedTouchPoint,rotatedCamera,object.getObjectRatio() ) ) |
|
175 |
{ |
|
176 |
mDragging = false; |
|
177 |
mContinuingRotation = false; |
|
178 |
|
|
179 |
if( mode==MODE_ROTATE ) |
|
180 |
{ |
|
181 |
mBeginningRotation= !mPreRender.isTouchBlocked(); |
|
182 |
} |
|
183 |
else if( mode==MODE_REPLACE ) |
|
184 |
{ |
|
185 |
mBeginningRotation= false; |
|
186 |
|
|
187 |
if( down ) |
|
188 |
{ |
|
189 |
int color = mActioner.getCurrentColor(); |
|
190 |
mLastCubitFace = mMovement.getTouchedFace(); |
|
191 |
float[] point = mMovement.getTouchedPoint3D(); |
|
192 |
mLastCubit = object.getCubit(point); |
|
193 |
mPreRender.setTextureMap( mLastCubit, mLastCubitFace, color ); |
|
194 |
mLastCubitColor = mActioner.cubitIsLocked(object.getObjectType(),mLastCubit); |
|
195 |
} |
|
196 |
} |
|
197 |
} |
|
198 |
else |
|
199 |
{ |
|
200 |
final TwistyActivity act = mAct.get(); |
|
201 |
final boolean locked= act.isLocked(); |
|
202 |
mDragging = (!locked || mIsAutomatic); |
|
203 |
mBeginningRotation = false; |
|
204 |
mContinuingRotation = false; |
|
205 |
if( !mDragging ) mActioner.failedToDrag(act); |
|
206 |
} |
|
207 |
} |
|
208 |
} |
|
209 |
|
|
210 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
211 |
|
|
212 |
private void drag(float x, float y) |
|
213 |
{ |
|
214 |
if( mPointer1!=INVALID_POINTER_ID && mPointer2!=INVALID_POINTER_ID) |
|
215 |
{ |
|
216 |
float x2 = (mX2 - mScreenWidth*0.5f)/mScreenMin; |
|
217 |
float y2 = (mScreenHeight*0.5f - mY2)/mScreenMin; |
|
218 |
|
|
219 |
float angleNow = getAngle(x,y,x2,y2); |
|
220 |
float angleDiff = angleNow-mRotAngle; |
|
221 |
float sinA =-(float)Math.sin(angleDiff); |
|
222 |
float cosA = (float)Math.cos(angleDiff); |
|
223 |
|
|
224 |
Static4D dragQuat = QuatHelper.quatMultiply(new Static4D(0,0,sinA,cosA), mQuat); |
|
225 |
mTemp.set(dragQuat); |
|
226 |
|
|
227 |
mRotAngle = angleNow; |
|
228 |
|
|
229 |
float distNow = (float)Math.sqrt( (x-x2)*(x-x2) + (y-y2)*(y-y2) ); |
|
230 |
float distQuot = mInitDistance<0 ? 1.0f : distNow/ mInitDistance; |
|
231 |
mInitDistance = distNow; |
|
232 |
TwistyObject object = mPreRender.getObject(); |
|
233 |
if( object!=null ) object.setObjectRatio(distQuot); |
|
234 |
} |
|
235 |
else |
|
236 |
{ |
|
237 |
Static4D dragQuat = QuatHelper.quatMultiply(QuatHelper.quatFromDrag(mX-x,y-mY), mQuat); |
|
238 |
mTemp.set(dragQuat); |
|
239 |
} |
|
240 |
|
|
241 |
mPreRender.setQuatOnNextRender(); |
|
242 |
mX = x; |
|
243 |
mY = y; |
|
244 |
} |
|
245 |
|
|
246 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
247 |
|
|
248 |
private void finishRotation() |
|
249 |
{ |
|
250 |
computeCurrentSpeedInInchesPerSecond(); |
|
251 |
int angle = mPreRender.getObject().computeNearestAngle(mCurrentAxis,mCurrentAngle, mCurrRotSpeed); |
|
252 |
mPreRender.finishRotation(angle); |
|
253 |
mPreRender.rememberMove(mCurrentAxis,mCurrentRow,angle); |
|
254 |
|
|
255 |
if( angle!=0 ) |
|
256 |
{ |
|
257 |
TwistyActivity act = mAct.get(); |
|
258 |
mActioner.onFinishRotation(act,mCurrentAxis,mCurrentRow,angle); |
|
259 |
} |
|
260 |
|
|
261 |
mContinuingRotation = false; |
|
262 |
mBeginningRotation = false; |
|
263 |
mDragging = true; |
|
264 |
} |
|
265 |
|
|
266 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
267 |
|
|
268 |
private void continueRotation(float x, float y) |
|
269 |
{ |
|
270 |
float dx = x-mStartRotX; |
|
271 |
float dy = y-mStartRotY; |
|
272 |
float alpha = dx*mAxisX + dy*mAxisY; |
|
273 |
float x2 = dx - alpha*mAxisX; |
|
274 |
float y2 = dy - alpha*mAxisY; |
|
275 |
|
|
276 |
float len = (float)Math.sqrt(x2*x2 + y2*y2); |
|
277 |
|
|
278 |
// we have the length of 1D vector 'angle', now the direction: |
|
279 |
float tmp = mAxisY==0 ? -mAxisX*y2 : mAxisY*x2; |
|
280 |
|
|
281 |
float angle = (tmp>0 ? 1:-1)*len*mRotationFactor; |
|
282 |
mCurrentAngle = SWIPING_SENSITIVITY*angle; |
|
283 |
mPreRender.getObject().continueRotation(mCurrentAngle); |
|
284 |
|
|
285 |
addSpeedProbe(x2,y2); |
|
286 |
} |
|
287 |
|
|
288 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
289 |
|
|
290 |
private void beginRotation(float x, float y) |
|
291 |
{ |
|
292 |
mStartRotX = x; |
|
293 |
mStartRotY = y; |
|
294 |
|
|
295 |
TwistyObject object = mPreRender.getObject(); |
|
296 |
int numLayers = object.getNumLayers(); |
|
297 |
|
|
298 |
Static4D touchPoint2 = new Static4D(x, y, 0, 0); |
|
299 |
Static4D rotatedTouchPoint2= QuatHelper.rotateVectorByInvertedQuat(touchPoint2, mQuat); |
|
300 |
Static2D res = mMovement.newRotation(rotatedTouchPoint2,object.getObjectRatio()); |
|
301 |
|
|
302 |
mCurrentAxis = (int)res.get0(); |
|
303 |
mCurrentRow = (int)res.get1(); |
|
304 |
|
|
305 |
computeCurrentAxis( mMovement.getCastedRotAxis(mCurrentAxis) ); |
|
306 |
mRotationFactor = mMovement.returnRotationFactor(numLayers,mCurrentRow); |
|
307 |
|
|
308 |
object.beginNewRotation( mCurrentAxis, mCurrentRow ); |
|
309 |
|
|
310 |
TwistyActivity act = mAct.get(); |
|
311 |
mActioner.onBeginRotation(act); |
|
312 |
|
|
313 |
addSpeedProbe(x,y); |
|
314 |
|
|
315 |
mBeginningRotation = false; |
|
316 |
mContinuingRotation= true; |
|
317 |
} |
|
318 |
|
|
319 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
320 |
|
|
321 |
private float getAngle(float x1, float y1, float x2, float y2) |
|
322 |
{ |
|
323 |
return (float) Math.atan2(y1-y2, x1-x2); |
|
324 |
} |
|
325 |
|
|
326 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
327 |
|
|
328 |
private void prepareDown(MotionEvent event) |
|
329 |
{ |
|
330 |
mPointer1 = event.getPointerId(0); |
|
331 |
mX1 = event.getX(); |
|
332 |
mY1 = event.getY(); |
|
333 |
mPointer2 = INVALID_POINTER_ID; |
|
334 |
} |
|
335 |
|
|
336 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
337 |
|
|
338 |
private void prepareMove(MotionEvent event) |
|
339 |
{ |
|
340 |
int index1 = event.findPointerIndex(mPointer1); |
|
341 |
|
|
342 |
if( index1>=0 ) |
|
343 |
{ |
|
344 |
mX1 = event.getX(index1); |
|
345 |
mY1 = event.getY(index1); |
|
346 |
} |
|
347 |
|
|
348 |
int index2 = event.findPointerIndex(mPointer2); |
|
349 |
|
|
350 |
if( index2>=0 ) |
|
351 |
{ |
|
352 |
mX2 = event.getX(index2); |
|
353 |
mY2 = event.getY(index2); |
|
354 |
} |
|
355 |
} |
|
356 |
|
|
357 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
358 |
|
|
359 |
private void prepareUp(MotionEvent event) |
|
360 |
{ |
|
361 |
mPointer1 = INVALID_POINTER_ID; |
|
362 |
mPointer2 = INVALID_POINTER_ID; |
|
363 |
} |
|
364 |
|
|
365 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
366 |
|
|
367 |
private void prepareDown2(MotionEvent event) |
|
368 |
{ |
|
369 |
int index = event.getActionIndex(); |
|
370 |
|
|
371 |
if( mPointer1==INVALID_POINTER_ID ) |
|
372 |
{ |
|
373 |
mPointer1 = event.getPointerId(index); |
|
374 |
mX1 = event.getX(index); |
|
375 |
mY1 = event.getY(index); |
|
376 |
} |
|
377 |
else if( mPointer2==INVALID_POINTER_ID ) |
|
378 |
{ |
|
379 |
mPointer2 = event.getPointerId(index); |
|
380 |
mX2 = event.getX(index); |
|
381 |
mY2 = event.getY(index); |
|
382 |
} |
|
383 |
} |
|
384 |
|
|
385 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
386 |
|
|
387 |
private void prepareUp2(MotionEvent event) |
|
388 |
{ |
|
389 |
int index = event.getActionIndex(); |
|
390 |
|
|
391 |
if( index==event.findPointerIndex(mPointer1) ) mPointer1 = INVALID_POINTER_ID; |
|
392 |
else if( index==event.findPointerIndex(mPointer2) ) mPointer2 = INVALID_POINTER_ID; |
|
393 |
} |
|
394 |
|
|
395 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
396 |
|
|
397 |
private void actionMove(float x1, float y1, float x2, float y2, int mode) |
|
398 |
{ |
|
399 |
float pX = mPointer1 != INVALID_POINTER_ID ? x1 : x2; |
|
400 |
float pY = mPointer1 != INVALID_POINTER_ID ? y1 : y2; |
|
401 |
|
|
402 |
float x = (pX - mScreenWidth*0.5f)/mScreenMin; |
|
403 |
float y = (mScreenHeight*0.5f -pY)/mScreenMin; |
|
404 |
|
|
405 |
if( mBeginningRotation ) |
|
406 |
{ |
|
407 |
if( retFingerDragDistanceInInches(mX,mY,x,y) > ROTATION_SENSITIVITY ) |
|
408 |
{ |
|
409 |
beginRotation(x,y); |
|
410 |
} |
|
411 |
} |
|
412 |
else if( mContinuingRotation ) |
|
413 |
{ |
|
414 |
continueRotation(x,y); |
|
415 |
} |
|
416 |
else if( mDragging ) |
|
417 |
{ |
|
418 |
drag(x,y); |
|
419 |
} |
|
420 |
else |
|
421 |
{ |
|
422 |
setUpDragOrRotate(false,x,y,mode); |
|
423 |
} |
|
424 |
} |
|
425 |
|
|
426 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
427 |
|
|
428 |
private void actionDown(float x, float y, int mode) |
|
429 |
{ |
|
430 |
mX = (x - mScreenWidth*0.5f)/mScreenMin; |
|
431 |
mY = (mScreenHeight*0.5f - y)/mScreenMin; |
|
432 |
|
|
433 |
setUpDragOrRotate(true,mX,mY,mode); |
|
434 |
} |
|
435 |
|
|
436 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
437 |
|
|
438 |
private void actionUp() |
|
439 |
{ |
|
440 |
if( mContinuingRotation ) |
|
441 |
{ |
|
442 |
finishRotation(); |
|
443 |
} |
|
444 |
|
|
445 |
if( mLastCubitColor>=0 ) |
|
446 |
{ |
|
447 |
mPreRender.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor ); |
|
448 |
mLastCubitColor = -1; |
|
449 |
} |
|
450 |
} |
|
451 |
|
|
452 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
453 |
|
|
454 |
private void actionDown2(float x1, float y1, float x2, float y2) |
|
455 |
{ |
|
456 |
mRotAngle = getAngle(x1,-y1, x2,-y2); |
|
457 |
mInitDistance = -1; |
|
458 |
|
|
459 |
mX = (x1 - mScreenWidth*0.5f )/mScreenMin; |
|
460 |
mY = (mScreenHeight*0.5f - y1)/mScreenMin; |
|
461 |
|
|
462 |
if( mBeginningRotation ) |
|
463 |
{ |
|
464 |
mContinuingRotation = false; |
|
465 |
mBeginningRotation = false; |
|
466 |
mDragging = true; |
|
467 |
} |
|
468 |
else if( mContinuingRotation ) |
|
469 |
{ |
|
470 |
finishRotation(); |
|
471 |
} |
|
472 |
} |
|
473 |
|
|
474 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
475 |
|
|
476 |
private void actionUp2(boolean p1isUp, float x1, float y1, boolean p2isUp, float x2, float y2) |
|
477 |
{ |
|
478 |
if( p1isUp ) |
|
479 |
{ |
|
480 |
mX = (x2 - mScreenWidth*0.5f)/mScreenMin; |
|
481 |
mY = (mScreenHeight*0.5f - y2)/mScreenMin; |
|
482 |
} |
|
483 |
if( p2isUp ) |
|
484 |
{ |
|
485 |
mX = (x1 - mScreenWidth*0.5f)/mScreenMin; |
|
486 |
mY = (mScreenHeight*0.5f - y1)/mScreenMin; |
|
487 |
} |
|
488 |
} |
|
489 |
|
|
490 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
491 |
// PUBLIC API |
|
492 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
493 |
|
|
494 |
public ObjectControl(TwistyActivity act, ObjectSurfaceView view, ObjectStateActioner actioner) |
|
495 |
{ |
|
496 |
mIsAutomatic = false; |
|
497 |
|
|
498 |
mLastCubitColor = -1; |
|
499 |
mCurrRotSpeed = 0.0f; |
|
500 |
|
|
501 |
mLastX = new float[NUM_SPEED_PROBES]; |
|
502 |
mLastY = new float[NUM_SPEED_PROBES]; |
|
503 |
mLastT = new long[NUM_SPEED_PROBES]; |
|
504 |
mFirstIndex =0; |
|
505 |
mLastIndex =0; |
|
506 |
|
|
507 |
DisplayMetrics dm = new DisplayMetrics(); |
|
508 |
act.getWindowManager().getDefaultDisplay().getMetrics(dm); |
|
509 |
|
|
510 |
mDensity = dm.densityDpi; |
|
511 |
|
|
512 |
mPreRender = new ObjectPreRender(view,actioner); |
|
513 |
mAct = new WeakReference<>(act); |
|
514 |
mActioner = actioner; |
|
515 |
} |
|
516 |
|
|
517 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
518 |
|
|
519 |
public void setScreenSize(int width, int height) |
|
520 |
{ |
|
521 |
mScreenWidth = width; |
|
522 |
mScreenHeight= height; |
|
523 |
|
|
524 |
mScreenMin = Math.min(width, height); |
|
525 |
} |
|
526 |
|
|
527 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
528 |
|
|
529 |
public void initialize() |
|
530 |
{ |
|
531 |
mPointer1 = INVALID_POINTER_ID; |
|
532 |
mPointer2 = INVALID_POINTER_ID; |
|
533 |
} |
|
534 |
|
|
535 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
536 |
|
|
537 |
public void setQuat() |
|
538 |
{ |
|
539 |
mQuat.set(mTemp); |
|
540 |
} |
|
541 |
|
|
542 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
543 |
|
|
544 |
public Static4D getQuat() |
|
545 |
{ |
|
546 |
return mQuat; |
|
547 |
} |
|
548 |
|
|
549 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
550 |
|
|
551 |
public void setMovement(Movement movement) |
|
552 |
{ |
|
553 |
mMovement = movement; |
|
554 |
} |
|
555 |
|
|
556 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
557 |
|
|
558 |
public ObjectPreRender getPreRender() |
|
559 |
{ |
|
560 |
return mPreRender; |
|
561 |
} |
|
562 |
|
|
563 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
564 |
|
|
565 |
public void prepareDown() |
|
566 |
{ |
|
567 |
mIsAutomatic = true; |
|
568 |
mPointer1 = 0; |
|
569 |
mPointer2 = INVALID_POINTER_ID; |
|
570 |
} |
|
571 |
|
|
572 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
573 |
|
|
574 |
public void prepareDown2() |
|
575 |
{ |
|
576 |
mPointer2 = 0; |
|
577 |
} |
|
578 |
|
|
579 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
580 |
|
|
581 |
public void prepareUp() |
|
582 |
{ |
|
583 |
mIsAutomatic = false; |
|
584 |
mPointer1 = INVALID_POINTER_ID; |
|
585 |
mPointer2 = INVALID_POINTER_ID; |
|
586 |
} |
|
587 |
|
|
588 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
589 |
|
|
590 |
public void prepareMove(float x1, float y1, float x2, float y2) |
|
591 |
{ |
|
592 |
mX1 = x1; |
|
593 |
mY1 = y1; |
|
594 |
mX2 = x2; |
|
595 |
mY2 = y2; |
|
596 |
} |
|
597 |
|
|
598 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
599 |
|
|
600 |
public boolean onTouchEvent(MotionEvent event, int mode) |
|
601 |
{ |
|
602 |
int action = event.getActionMasked(); |
|
603 |
|
|
604 |
switch(action) |
|
605 |
{ |
|
606 |
case MotionEvent.ACTION_DOWN : prepareDown(event); |
|
607 |
actionDown(mX1, mY1, mode); |
|
608 |
break; |
|
609 |
case MotionEvent.ACTION_MOVE : prepareMove(event); |
|
610 |
actionMove(mX1, mY1, mX2, mY2, mode); |
|
611 |
break; |
|
612 |
case MotionEvent.ACTION_UP : prepareUp(event); |
|
613 |
actionUp(); |
|
614 |
break; |
|
615 |
case MotionEvent.ACTION_POINTER_DOWN: prepareDown2(event); |
|
616 |
actionDown2(mX1, mY1, mX2, mY2); |
|
617 |
break; |
|
618 |
case MotionEvent.ACTION_POINTER_UP : prepareUp2(event); |
|
619 |
boolean p1isUp = mPointer1==INVALID_POINTER_ID; |
|
620 |
boolean p2isUp = mPointer2==INVALID_POINTER_ID; |
|
621 |
actionUp2(p1isUp, mX1, mY1, p2isUp, mX2, mY2); |
|
622 |
break; |
|
623 |
} |
|
624 |
|
|
625 |
return true; |
|
626 |
} |
|
627 |
} |
|
628 |
|
src/main/java/org/distorted/objectlib/main/TwistyObject.java | ||
---|---|---|
890 | 890 |
} |
891 | 891 |
} |
892 | 892 |
|
893 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
894 |
// INTERNAL API |
|
895 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
896 |
|
|
897 |
public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total) |
|
898 |
{ |
|
899 |
mScrambler.randomizeNewScramble(scramble,rnd,curr,total); |
|
900 |
} |
|
901 |
|
|
902 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
903 |
|
|
904 |
public int getNodeSize() |
|
905 |
{ |
|
906 |
return mNodeSize; |
|
907 |
} |
|
908 |
|
|
909 | 893 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
910 | 894 |
|
911 |
public void initializeObject(int[][] moves)
|
|
895 |
void initializeObject(int[][] moves) |
|
912 | 896 |
{ |
913 | 897 |
solve(); |
914 | 898 |
setupPosition(moves); |
... | ... | |
916 | 900 |
|
917 | 901 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
918 | 902 |
|
919 |
public synchronized void removeRotationNow()
|
|
903 |
synchronized void removeRotationNow() |
|
920 | 904 |
{ |
921 | 905 |
float angle = getAngle(); |
922 | 906 |
double nearestAngleInRadians = angle*Math.PI/180; |
... | ... | |
940 | 924 |
|
941 | 925 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
942 | 926 |
|
943 |
public long finishRotationNow(EffectListener listener, int nearestAngleInDegrees)
|
|
927 |
long finishRotationNow(EffectListener listener, int nearestAngleInDegrees) |
|
944 | 928 |
{ |
945 | 929 |
if( wasRotateApplied() ) |
946 | 930 |
{ |
... | ... | |
965 | 949 |
|
966 | 950 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
967 | 951 |
|
968 |
public synchronized long addNewRotation( int axis, int rowBitmap, int angle, long durationMillis, EffectListener listener )
|
|
952 |
synchronized long addNewRotation( int axis, int rowBitmap, int angle, long durationMillis, EffectListener listener ) |
|
969 | 953 |
{ |
970 | 954 |
if( wasRotateApplied() ) |
971 | 955 |
{ |
... | ... | |
989 | 973 |
|
990 | 974 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
991 | 975 |
|
992 |
public void setTextureMap(int cubit, int face, int newColor) |
|
976 |
void continueRotation(float angleInDegrees) |
|
977 |
{ |
|
978 |
mRotationAngleStatic.set0(angleInDegrees); |
|
979 |
} |
|
980 |
|
|
981 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
982 |
|
|
983 |
synchronized void beginNewRotation(int axis, int row ) |
|
984 |
{ |
|
985 |
if( axis<0 || axis>=NUM_AXIS ) |
|
986 |
{ |
|
987 |
android.util.Log.e("object", "invalid rotation axis: "+axis); |
|
988 |
return; |
|
989 |
} |
|
990 |
if( row<0 || row>=mNumLayers ) |
|
991 |
{ |
|
992 |
android.util.Log.e("object", "invalid rotation row: "+row); |
|
993 |
return; |
|
994 |
} |
|
995 |
|
|
996 |
mRotAxis = axis; |
|
997 |
mRotRowBitmap= computeBitmapFromRow( (1<<row),axis ); |
|
998 |
mRotationAngleStatic.set0(0.0f); |
|
999 |
mRotationAxis.set( mAxis[axis] ); |
|
1000 |
mRotationAngle.add(mRotationAngleStatic); |
|
1001 |
mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis*ObjectType.MAX_OBJECT_SIZE) , -1); |
|
1002 |
} |
|
1003 |
|
|
1004 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1005 |
|
|
1006 |
void setTextureMap(int cubit, int face, int newColor) |
|
993 | 1007 |
{ |
994 | 1008 |
final float ratioW = 1.0f/mNumTexCols; |
995 | 1009 |
final float ratioH = 1.0f/mNumTexRows; |
... | ... | |
1003 | 1017 |
|
1004 | 1018 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1005 | 1019 |
|
1006 |
public void resetAllTextureMaps()
|
|
1020 |
void resetAllTextureMaps() |
|
1007 | 1021 |
{ |
1008 | 1022 |
final float ratioW = 1.0f/mNumTexCols; |
1009 | 1023 |
final float ratioH = 1.0f/mNumTexRows; |
... | ... | |
1027 | 1041 |
|
1028 | 1042 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1029 | 1043 |
|
1030 |
public void releaseResources()
|
|
1044 |
void releaseResources() |
|
1031 | 1045 |
{ |
1032 | 1046 |
mTexture.markForDeletion(); |
1033 | 1047 |
mMesh.markForDeletion(); |
... | ... | |
1041 | 1055 |
|
1042 | 1056 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1043 | 1057 |
|
1044 |
public synchronized void restorePreferences(SharedPreferences preferences)
|
|
1058 |
synchronized void restorePreferences(SharedPreferences preferences) |
|
1045 | 1059 |
{ |
1046 | 1060 |
boolean error = false; |
1047 | 1061 |
|
... | ... | |
1073 | 1087 |
|
1074 | 1088 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1075 | 1089 |
|
1076 |
public void savePreferences(SharedPreferences.Editor editor)
|
|
1090 |
void savePreferences(SharedPreferences.Editor editor) |
|
1077 | 1091 |
{ |
1078 | 1092 |
for(int i=0; i<NUM_CUBITS; i++) CUBITS[i].savePreferences(editor); |
1079 | 1093 |
} |
1080 | 1094 |
|
1081 | 1095 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1082 | 1096 |
|
1083 |
public void recomputeScaleFactor(int scrWidth)
|
|
1097 |
void recomputeScaleFactor(int scrWidth) |
|
1084 | 1098 |
{ |
1085 | 1099 |
mNodeScale.set(scrWidth,NODE_RATIO*scrWidth,scrWidth); |
1086 | 1100 |
} |
1087 | 1101 |
|
1088 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1089 |
|
|
1090 |
public Static4D getRotationQuat() |
|
1091 |
{ |
|
1092 |
return mQuat; |
|
1093 |
} |
|
1094 |
|
|
1095 | 1102 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1096 | 1103 |
// the getFaceColors + final black in a grid (so that we do not exceed the maximum texture size) |
1097 | 1104 |
|
1098 |
public void createTexture()
|
|
1105 |
void createTexture() |
|
1099 | 1106 |
{ |
1100 | 1107 |
Bitmap bitmap; |
1101 | 1108 |
|
... | ... | |
1130 | 1137 |
} |
1131 | 1138 |
} |
1132 | 1139 |
|
1133 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1134 |
// PUBLIC API |
|
1135 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1136 |
|
|
1137 |
public boolean isSolved() |
|
1138 |
{ |
|
1139 |
if( mSolvedFunctionIndex==0 ) return isSolved0(); |
|
1140 |
if( mSolvedFunctionIndex==1 ) return isSolved1(); |
|
1141 |
if( mSolvedFunctionIndex==2 ) return isSolved2(); |
|
1142 |
if( mSolvedFunctionIndex==3 ) return isSolved3(); |
|
1143 |
|
|
1144 |
return false; |
|
1145 |
} |
|
1146 |
|
|
1147 | 1140 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1148 | 1141 |
|
1149 |
public void setObjectRatio(float sizeChange)
|
|
1142 |
void setObjectRatio(float sizeChange) |
|
1150 | 1143 |
{ |
1151 | 1144 |
mObjectScreenRatio *= (1.0f+sizeChange)/2; |
1152 | 1145 |
|
... | ... | |
1159 | 1152 |
|
1160 | 1153 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1161 | 1154 |
|
1162 |
public float getObjectRatio()
|
|
1155 |
float getObjectRatio() |
|
1163 | 1156 |
{ |
1164 | 1157 |
return mObjectScreenRatio*mInitScreenRatio; |
1165 | 1158 |
} |
1166 | 1159 |
|
1167 | 1160 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1168 | 1161 |
|
1169 |
public int getCubitFaceColorIndex(int cubit, int face)
|
|
1162 |
boolean isSolved()
|
|
1170 | 1163 |
{ |
1171 |
Static4D texMap = mMesh.getTextureMap(NUM_FACE_COLORS*cubit + face);
|
|
1172 |
|
|
1173 |
int x = (int)(texMap.get0()/texMap.get2());
|
|
1174 |
int y = (int)(texMap.get1()/texMap.get3());
|
|
1164 |
if( mSolvedFunctionIndex==0 ) return isSolved0();
|
|
1165 |
if( mSolvedFunctionIndex==1 ) return isSolved1(); |
|
1166 |
if( mSolvedFunctionIndex==2 ) return isSolved2();
|
|
1167 |
if( mSolvedFunctionIndex==3 ) return isSolved3();
|
|
1175 | 1168 |
|
1176 |
return (mNumTexRows-1-y)*NUM_STICKERS_IN_ROW + x;
|
|
1169 |
return false;
|
|
1177 | 1170 |
} |
1178 | 1171 |
|
1179 | 1172 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1180 | 1173 |
|
1181 |
public int getNumLayers()
|
|
1174 |
int getCubit(float[] point3D)
|
|
1182 | 1175 |
{ |
1183 |
return mNumLayers; |
|
1176 |
float dist, minDist = Float.MAX_VALUE; |
|
1177 |
int currentBest=-1; |
|
1178 |
float multiplier = returnMultiplier(); |
|
1179 |
|
|
1180 |
point3D[0] *= multiplier; |
|
1181 |
point3D[1] *= multiplier; |
|
1182 |
point3D[2] *= multiplier; |
|
1183 |
|
|
1184 |
for(int i=0; i<NUM_CUBITS; i++) |
|
1185 |
{ |
|
1186 |
dist = CUBITS[i].getDistSquared(point3D); |
|
1187 |
if( dist<minDist ) |
|
1188 |
{ |
|
1189 |
minDist = dist; |
|
1190 |
currentBest = i; |
|
1191 |
} |
|
1192 |
} |
|
1193 |
|
|
1194 |
return currentBest; |
|
1184 | 1195 |
} |
1185 | 1196 |
|
1186 | 1197 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1187 | 1198 |
|
1188 |
public void continueRotation(float angleInDegrees)
|
|
1199 |
int computeNearestAngle(int axis, float angle, float speed)
|
|
1189 | 1200 |
{ |
1190 |
mRotationAngleStatic.set0(angleInDegrees); |
|
1201 |
int[] basicArray = getBasicAngle(); |
|
1202 |
int basicAngle = basicArray[axis>=basicArray.length ? 0 : axis]; |
|
1203 |
int nearestAngle = 360/basicAngle; |
|
1204 |
|
|
1205 |
int tmp = (int)((angle+nearestAngle/2)/nearestAngle); |
|
1206 |
if( angle< -(nearestAngle*0.5) ) tmp-=1; |
|
1207 |
|
|
1208 |
if( tmp!=0 ) return nearestAngle*tmp; |
|
1209 |
|
|
1210 |
return speed> 1.2f ? nearestAngle*(angle>0 ? 1:-1) : 0; |
|
1191 | 1211 |
} |
1192 | 1212 |
|
1193 | 1213 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1194 | 1214 |
|
1195 |
public void apply(Effect effect, int position)
|
|
1215 |
float getCameraDist()
|
|
1196 | 1216 |
{ |
1197 |
mEffects.apply(effect, position);
|
|
1217 |
return mCameraDist;
|
|
1198 | 1218 |
} |
1199 | 1219 |
|
1220 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1221 |
// INTERNAL API - those are called from 'effects' package |
|
1200 | 1222 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1201 | 1223 |
|
1202 |
public void remove(long effectID)
|
|
1224 |
public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
|
|
1203 | 1225 |
{ |
1204 |
mEffects.abortById(effectID);
|
|
1226 |
mScrambler.randomizeNewScramble(scramble,rnd,curr,total);
|
|
1205 | 1227 |
} |
1206 | 1228 |
|
1207 | 1229 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1208 | 1230 |
|
1209 |
public synchronized void solve()
|
|
1231 |
public int getNodeSize()
|
|
1210 | 1232 |
{ |
1211 |
for(int i=0; i<NUM_CUBITS; i++) |
|
1212 |
{ |
|
1213 |
CUBITS[i].solve(); |
|
1214 |
mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0); |
|
1215 |
} |
|
1233 |
return mNodeSize; |
|
1216 | 1234 |
} |
1217 | 1235 |
|
1218 | 1236 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1219 | 1237 |
|
1220 |
public synchronized void beginNewRotation(int axis, int row ) |
|
1221 |
{ |
|
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 ) |
|
1238 |
public Static4D getRotationQuat() |
|
1228 | 1239 |
{ |
1229 |
android.util.Log.e("object", "invalid rotation row: "+row); |
|
1230 |
return; |
|
1240 |
return mQuat; |
|
1231 | 1241 |
} |
1232 | 1242 |
|
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); |
|
1239 |
} |
|
1240 |
|
|
1243 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1244 |
// PUBLIC API |
|
1241 | 1245 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1242 | 1246 |
|
1243 |
public int getCubit(float[] point3D)
|
|
1247 |
public int getCubitFaceColorIndex(int cubit, int face)
|
|
1244 | 1248 |
{ |
1245 |
float dist, minDist = Float.MAX_VALUE; |
|
1246 |
int currentBest=-1; |
|
1247 |
float multiplier = returnMultiplier(); |
|
1248 |
|
|
1249 |
point3D[0] *= multiplier; |
|
1250 |
point3D[1] *= multiplier; |
|
1251 |
point3D[2] *= multiplier; |
|
1249 |
Static4D texMap = mMesh.getTextureMap(NUM_FACE_COLORS*cubit + face); |
|
1252 | 1250 |
|
1253 |
for(int i=0; i<NUM_CUBITS; i++) |
|
1254 |
{ |
|
1255 |
dist = CUBITS[i].getDistSquared(point3D); |
|
1256 |
if( dist<minDist ) |
|
1257 |
{ |
|
1258 |
minDist = dist; |
|
1259 |
currentBest = i; |
|
1260 |
} |
|
1261 |
} |
|
1251 |
int x = (int)(texMap.get0()/texMap.get2()); |
|
1252 |
int y = (int)(texMap.get1()/texMap.get3()); |
|
1262 | 1253 |
|
1263 |
return currentBest;
|
|
1254 |
return (mNumTexRows-1-y)*NUM_STICKERS_IN_ROW + x;
|
|
1264 | 1255 |
} |
1265 | 1256 |
|
1266 | 1257 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1267 | 1258 |
|
1268 |
public int computeNearestAngle(int axis, float angle, float speed)
|
|
1259 |
public int getNumLayers()
|
|
1269 | 1260 |
{ |
1270 |
int[] basicArray = getBasicAngle(); |
|
1271 |
int basicAngle = basicArray[axis>=basicArray.length ? 0 : axis]; |
|
1272 |
int nearestAngle = 360/basicAngle; |
|
1261 |
return mNumLayers; |
|
1262 |
} |
|
1273 | 1263 |
|
1274 |
int tmp = (int)((angle+nearestAngle/2)/nearestAngle); |
|
1275 |
if( angle< -(nearestAngle*0.5) ) tmp-=1; |
|
1264 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1276 | 1265 |
|
1277 |
if( tmp!=0 ) return nearestAngle*tmp; |
|
1266 |
public void apply(Effect effect, int position) |
|
1267 |
{ |
|
1268 |
mEffects.apply(effect, position); |
|
1269 |
} |
|
1278 | 1270 |
|
1279 |
return speed> 1.2f ? nearestAngle*(angle>0 ? 1:-1) : 0; |
|
1271 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1272 |
|
|
1273 |
public void remove(long effectID) |
|
1274 |
{ |
|
1275 |
mEffects.abortById(effectID); |
|
1280 | 1276 |
} |
1281 | 1277 |
|
1282 | 1278 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1283 | 1279 |
|
1284 |
public float getCameraDist()
|
|
1280 |
public synchronized void solve()
|
|
1285 | 1281 |
{ |
1286 |
return mCameraDist; |
|
1282 |
for(int i=0; i<NUM_CUBITS; i++) |
|
1283 |
{ |
|
1284 |
CUBITS[i].solve(); |
|
1285 |
mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0); |
|
1286 |
} |
|
1287 | 1287 |
} |
1288 | 1288 |
|
1289 | 1289 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Move ObjectControl, the next big chunk of code, to objectlib.