Revision 4a014840
Added by Leszek Koltunski over 1 year ago
src/main/java/org/distorted/objectlib/main/ObjectControl.java | ||
---|---|---|
332 | 332 |
mRotationFactor = mTouchControl.returnRotationFactor(mCurrentAxis,mCurrentRow); |
333 | 333 |
if( mRotAxisType != ROT_AXIS_NOT_NORMAL ) mNormalRotAngle = computeNormalRotAngle(mNormalTouchPoint[0]-x,mNormalTouchPoint[1]-y); |
334 | 334 |
|
335 |
if( object.beginNewRotation( mCurrentAxis, mCurrentRow ) )
|
|
335 |
if( object.beginRotation( mCurrentAxis, mCurrentRow ) ) |
|
336 | 336 |
{ |
337 | 337 |
mInterface.onBeginRotation(); |
338 | 338 |
addSpeedProbe(0); |
... | ... | |
823 | 823 |
return mPreRender.getObject(); |
824 | 824 |
} |
825 | 825 |
|
826 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
827 |
|
|
828 |
public OperatingSystemInterface getOS() |
|
829 |
{ |
|
830 |
return mOS; |
|
831 |
} |
|
832 |
|
|
833 | 826 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
834 | 827 |
|
835 | 828 |
public void savePreferences() |
src/main/java/org/distorted/objectlib/main/ObjectPreRender.java | ||
---|---|---|
42 | 42 |
private float mMoveX, mMoveY; |
43 | 43 |
private float mScale; |
44 | 44 |
|
45 |
private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
|
|
45 |
private boolean mFinishRotation, mRemoveManualRotation, mRemoveProgramaticRotation, mAddRotation,
|
|
46 | 46 |
mSetQuat, mChangeObject, mSolveObject, mScrambleObject, mFastScrambleObject, |
47 | 47 |
mPresentObject,mInitializeObject, mSetTextureMap, mResetAllTextureMaps, mSolve, |
48 | 48 |
mApplyScrambles, mResetTextureEffect; |
... | ... | |
54 | 54 |
private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle; |
55 | 55 |
private long mAddRotationDuration; |
56 | 56 |
private int mPresentDuration, mRestickerDuration; |
57 |
private long mAddRotationID, mRemoveRotationID; |
|
57 |
private long mAddRotationID, mRemoveProgramaticRotationID;
|
|
58 | 58 |
private int mCubit, mFace, mNewColor; |
59 | 59 |
private int mFinishAxis, mFinishRow; |
60 | 60 |
private float mFinishAngle, mAvgSpeed; |
... | ... | |
72 | 72 |
mController = controller; |
73 | 73 |
|
74 | 74 |
mFinishRotation = false; |
75 |
mRemoveRotation = false;
|
|
76 |
mRemovePatternRotation= false;
|
|
75 |
mRemoveManualRotation = false;
|
|
76 |
mRemoveProgramaticRotation = false;
|
|
77 | 77 |
mAddRotation = false; |
78 | 78 |
mSetQuat = false; |
79 | 79 |
mChangeObject = false; |
... | ... | |
175 | 175 |
|
176 | 176 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
177 | 177 |
|
178 |
private void removeRotationNow() |
|
178 |
private void removeManualRotationNow()
|
|
179 | 179 |
{ |
180 |
mRemoveRotation=false;
|
|
181 |
float angle = mNewObject.removeRotationNow();
|
|
180 |
mRemoveManualRotation =false;
|
|
181 |
float angle = mNewObject.removeRotation(); |
|
182 | 182 |
|
183 | 183 |
boolean solved = mNewObject.isSolved(); |
184 | 184 |
|
... | ... | |
209 | 209 |
|
210 | 210 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
211 | 211 |
|
212 |
private void removeRotation() |
|
212 |
private void removeManualRotation()
|
|
213 | 213 |
{ |
214 |
mRemoveRotation = true; |
|
214 |
mRemoveManualRotation = true;
|
|
215 | 215 |
} |
216 | 216 |
|
217 | 217 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
218 | 218 |
|
219 |
private void removePatternRotation()
|
|
219 |
private void removeProgramaticRotation()
|
|
220 | 220 |
{ |
221 |
mRemovePatternRotation = true;
|
|
221 |
mRemoveProgramaticRotation = true;
|
|
222 | 222 |
} |
223 | 223 |
|
224 | 224 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
225 | 225 |
|
226 |
private void removePatternRotationNow()
|
|
226 |
private void removeProgramaticRotationNow()
|
|
227 | 227 |
{ |
228 |
mRemovePatternRotation=false;
|
|
229 |
mNewObject.removeRotationNow();
|
|
230 |
mAddActionListener.onActionFinished(mRemoveRotationID); |
|
228 |
mRemoveProgramaticRotation =false;
|
|
229 |
mNewObject.removeRotation(); |
|
230 |
mAddActionListener.onActionFinished(mRemoveProgramaticRotationID);
|
|
231 | 231 |
} |
232 | 232 |
|
233 | 233 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
238 | 238 |
|
239 | 239 |
if( mNewObject.getNumAxis() > mAddRotationAxis ) |
240 | 240 |
{ |
241 |
mAddRotationID = mNewObject.addNewRotation( this, mAddRotationAxis, mAddRotationRowBitmap,
|
|
242 |
mAddRotationAngle, mAddRotationDuration);
|
|
241 |
mAddRotationID = mNewObject.addRotation( this, mAddRotationAxis, mAddRotationRowBitmap, |
|
242 |
mAddRotationAngle, mAddRotationDuration); |
|
243 | 243 |
|
244 | 244 |
// failed to add effect (previous rotation hasn't been removed yet) |
245 | 245 |
if( mAddRotationID==0 ) |
... | ... | |
276 | 276 |
{ |
277 | 277 |
mFinishRotation = false; |
278 | 278 |
blockEverything(BlockController.PLACE_0); |
279 |
mRotationFinishedID = mNewObject.finishRotationNow(this,mFinishAxis,mFinishRow,mFinishAngle,mAvgSpeed);
|
|
279 |
mRotationFinishedID = mNewObject.finishRotation(this,mFinishAxis,mFinishRow,mFinishAngle,mAvgSpeed); |
|
280 | 280 |
|
281 | 281 |
if( mRotationFinishedID==0 ) // failed to add effect - should never happen |
282 | 282 |
{ |
... | ... | |
608 | 608 |
|
609 | 609 |
public void preRender() |
610 | 610 |
{ |
611 |
if( mSolve ) solveNow(); |
|
612 |
if( mSetQuat ) setQuatNow(); |
|
613 |
if( mFinishRotation ) finishRotationNow(); |
|
614 |
if( mRemoveRotation ) removeRotationNow();
|
|
615 |
if( mRemovePatternRotation ) removePatternRotationNow();
|
|
616 |
if( mChangeObject ) changeObjectNow(); |
|
617 |
if( mSolveObject ) solveObjectNow(); |
|
618 |
if( mScrambleObject ) scrambleObjectNow(); |
|
619 |
if( mFastScrambleObject ) fastScrambleObjectNow(); |
|
620 |
if( mPresentObject ) presentObjectNow(); |
|
621 |
if( mAddRotation ) addRotationNow(); |
|
622 |
if( mInitializeObject ) initializeObjectNow(); |
|
623 |
if( mApplyScrambles ) applyScramblesNow(); |
|
624 |
if( mResetAllTextureMaps ) resetAllTextureMapsNow(); |
|
625 |
if( mSetTextureMap ) setTextureMapNow(); |
|
626 |
if( mResetTextureEffect ) resetTextureNow(); |
|
611 |
if( mSolve ) solveNow();
|
|
612 |
if( mSetQuat ) setQuatNow();
|
|
613 |
if( mFinishRotation ) finishRotationNow();
|
|
614 |
if( mRemoveManualRotation ) removeManualRotationNow();
|
|
615 |
if( mRemoveProgramaticRotation) removeProgramaticRotationNow();
|
|
616 |
if( mChangeObject ) changeObjectNow();
|
|
617 |
if( mSolveObject ) solveObjectNow();
|
|
618 |
if( mScrambleObject ) scrambleObjectNow();
|
|
619 |
if( mFastScrambleObject ) fastScrambleObjectNow();
|
|
620 |
if( mPresentObject ) presentObjectNow();
|
|
621 |
if( mAddRotation ) addRotationNow();
|
|
622 |
if( mInitializeObject ) initializeObjectNow();
|
|
623 |
if( mApplyScrambles ) applyScramblesNow();
|
|
624 |
if( mResetAllTextureMaps ) resetAllTextureMapsNow();
|
|
625 |
if( mSetTextureMap ) setTextureMapNow();
|
|
626 |
if( mResetTextureEffect ) resetTextureNow();
|
|
627 | 627 |
} |
628 | 628 |
|
629 | 629 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
631 | 631 |
public void addRotation(MovesFinished listener, int axis, int rowBitmap, int bareAngle, int millPreDegree) |
632 | 632 |
{ |
633 | 633 |
int[][] basicAngles = mNewObject==null ? null : mNewObject.getBasicAngles(); |
634 |
int length = basicAngles==null ? 0 : basicAngles.length; |
|
635 | 634 |
|
636 |
if( axis<length )
|
|
635 |
if( basicAngles!=null && axis<basicAngles.length )
|
|
637 | 636 |
{ |
638 | 637 |
int row = computeRowFromBitmap(rowBitmap); |
639 | 638 |
|
... | ... | |
771 | 770 |
if( effectID == mRotationFinishedID ) |
772 | 771 |
{ |
773 | 772 |
mRotationFinishedID = 0; |
774 |
removeRotation(); |
|
773 |
removeManualRotation();
|
|
775 | 774 |
} |
776 | 775 |
else if( effectID == mAddRotationID ) |
777 | 776 |
{ |
778 | 777 |
mAddRotationID = 0; |
779 |
mRemoveRotationID = effectID; |
|
780 |
removePatternRotation();
|
|
778 |
mRemoveProgramaticRotationID = effectID;
|
|
779 |
removeProgramaticRotation();
|
|
781 | 780 |
} |
782 | 781 |
else |
783 | 782 |
{ |
src/main/java/org/distorted/objectlib/main/TwistyLayerRotations.java | ||
---|---|---|
10 | 10 |
package org.distorted.objectlib.main; |
11 | 11 |
|
12 | 12 |
import org.distorted.library.effect.VertexEffectRotate; |
13 |
import org.distorted.library.main.DistortedEffects; |
|
13 | 14 |
import org.distorted.library.message.EffectListener; |
14 | 15 |
import org.distorted.library.type.Dynamic1D; |
15 | 16 |
import org.distorted.library.type.Static1D; |
... | ... | |
30 | 31 |
private int mCurrentRotAxis; |
31 | 32 |
|
32 | 33 |
private final int mMaxNumLayers; |
33 |
private final int mGhostAngle; |
|
34 | 34 |
private final Static3D mRotationAxis; |
35 | 35 |
private final VertexEffectRotate mRotateEffect; |
36 | 36 |
private final Dynamic1D mRotationAngle; |
37 | 37 |
private final Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal; |
38 | 38 |
private final TwistyObject mParent; |
39 | 39 |
|
40 |
// ghost angle |
|
41 |
private final float mGhostAngle; |
|
42 |
private final int mNumLayer0; |
|
43 |
private final boolean[] mGhostIsUp; |
|
44 |
private int mUpLeft, mUpRight; |
|
45 |
private final int mNumLeft, mNumRight; |
|
46 |
private VertexEffectRotate mGhostEffect1; |
|
47 |
private Static1D mGhostAngleN; |
|
48 |
private int mGhostN; |
|
49 |
|
|
40 | 50 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
41 | 51 |
|
42 |
TwistyLayerRotations(TwistyObject parent, int maxLayers, int ghostAngle)
|
|
52 |
TwistyLayerRotations(TwistyObject parent, Static3D ax, int[] numLayers, int ghostAngle, DistortedEffects effect)
|
|
43 | 53 |
{ |
44 | 54 |
mParent = parent; |
55 |
mGhostAngle = (float)(Math.PI*ghostAngle/180); |
|
56 |
|
|
57 |
int maxLayers = -1; |
|
58 |
for(int numLayer : numLayers) if(maxLayers<numLayer) maxLayers = numLayer; |
|
45 | 59 |
mMaxNumLayers = maxLayers; |
46 |
mGhostAngle = ghostAngle; |
|
60 |
mNumLayer0 = numLayers[0]; |
|
61 |
mGhostIsUp = (mGhostAngle==0) ? null : new boolean[mNumLayer0]; |
|
62 |
mUpLeft = mUpRight = 0; |
|
63 |
mNumLeft = mNumLayer0/2; |
|
64 |
mNumRight= mNumLayer0-mNumLeft; |
|
47 | 65 |
|
48 | 66 |
mRotationState = STATE_NOTHING; |
49 | 67 |
|
... | ... | |
54 | 72 |
mRotationAngle= new Dynamic1D(); |
55 | 73 |
mRotationAxis = new Static3D(1,0,0); |
56 | 74 |
mRotateEffect = new VertexEffectRotate(mRotationAngle, mRotationAxis, CENTER); |
75 |
|
|
76 |
effect.apply(mRotateEffect); |
|
77 |
|
|
78 |
if( mGhostAngle!=0 ) |
|
79 |
{ |
|
80 |
mGhostN = 0; |
|
81 |
Static1D ghostAngle1= new Static1D( (float)(Math.PI*mGhostAngle/180) ); |
|
82 |
mGhostAngleN= new Static1D(0); |
|
83 |
VertexEffectRotate ghostEffectN = new VertexEffectRotate(mGhostAngleN, ax, CENTER); |
|
84 |
mGhostEffect1 = new VertexEffectRotate( ghostAngle1, ax, CENTER); |
|
85 |
effect.apply(ghostEffectN); |
|
86 |
effect.apply(mGhostEffect1); |
|
87 |
} |
|
57 | 88 |
} |
58 | 89 |
|
90 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
91 |
// GHOST |
|
59 | 92 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
60 | 93 |
|
61 |
private int computeNearestAngle(int basicAngle, float angle, float speed)
|
|
94 |
private boolean angleIsGhost(int angle, int basicAngle)
|
|
62 | 95 |
{ |
63 |
int nearestAngle = 360/basicAngle; |
|
64 |
int tmp = (int)((angle+nearestAngle/2)/nearestAngle); |
|
65 |
if( angle< -(nearestAngle*0.5) ) tmp-=1; |
|
96 |
return angle%(360/basicAngle)!=0; |
|
97 |
} |
|
66 | 98 |
|
67 |
if( tmp!=0 ) return nearestAngle*tmp;
|
|
99 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
68 | 100 |
|
69 |
return speed> 1.2f ? nearestAngle*(angle>0 ? 1:-1) : 0; |
|
101 |
private int computeGhostAngle(int row, int basicAngle, float angle, float speed) |
|
102 |
{ |
|
103 |
boolean left = row<mNumLayer0/2; |
|
104 |
|
|
105 |
if( left ) |
|
106 |
{ |
|
107 |
if( angle<0 ) // if we are looking at the 0th axis (x axis) from the front, this is 'up' rot |
|
108 |
{ |
|
109 |
if( mUpRight==mNumRight && !mGhostIsUp[row] ) |
|
110 |
{ |
|
111 |
int a = computeGhostAngle(basicAngle,angle,speed); |
|
112 |
if( angleIsGhost(a,basicAngle) ) |
|
113 |
{ |
|
114 |
changeRow(row,true); |
|
115 |
if( mUpLeft==0 ) enableGhostAxis(false); |
|
116 |
mUpLeft++; |
|
117 |
|
|
118 |
if( mUpLeft==mNumLeft ) |
|
119 |
{ |
|
120 |
for( int i=0; i<mNumLayer0; i++ ) changeRow(i,false); |
|
121 |
mUpLeft = 0; |
|
122 |
mUpRight= 0; |
|
123 |
changeTotalGhostAngle(1); |
|
124 |
} |
|
125 |
} |
|
126 |
return a; |
|
127 |
} |
|
128 |
else return computeNearestAngle(basicAngle,angle,speed); |
|
129 |
} |
|
130 |
else |
|
131 |
{ |
|
132 |
if( mGhostIsUp[row] ) |
|
133 |
{ |
|
134 |
int a = computeGhostAngle(basicAngle,angle,speed); |
|
135 |
if( angleIsGhost(a,basicAngle) ) |
|
136 |
{ |
|
137 |
changeRow(row,false); |
|
138 |
if( mUpLeft==1 ) enableGhostAxis(true); |
|
139 |
mUpLeft--; |
|
140 |
} |
|
141 |
return a; |
|
142 |
} |
|
143 |
else if( mUpLeft==0 && mUpRight==0 ) |
|
144 |
{ |
|
145 |
int a = computeGhostAngle(basicAngle,angle,speed); |
|
146 |
if( angleIsGhost(a,basicAngle) ) |
|
147 |
{ |
|
148 |
mUpLeft = mNumLeft-1; |
|
149 |
mUpRight= mNumRight; |
|
150 |
for( int i=0; i<mNumLayer0; i++ ) |
|
151 |
if( i!=row) changeRow(i,true); |
|
152 |
if( mNumLeft==1 ) enableGhostAxis(true); |
|
153 |
changeTotalGhostAngle(-1); |
|
154 |
} |
|
155 |
return a; |
|
156 |
} |
|
157 |
else return computeNearestAngle(basicAngle,angle,speed); |
|
158 |
} |
|
159 |
} |
|
160 |
else |
|
161 |
{ |
|
162 |
if( angle<0 ) |
|
163 |
{ |
|
164 |
if( !mGhostIsUp[row] ) |
|
165 |
{ |
|
166 |
int a = computeGhostAngle(basicAngle,angle,speed); |
|
167 |
if( angleIsGhost(a,basicAngle) ) |
|
168 |
{ |
|
169 |
changeRow(row,true); |
|
170 |
mUpRight++; |
|
171 |
if( mUpRight==mNumRight ) enableGhostAxis(true); |
|
172 |
} |
|
173 |
return a; |
|
174 |
} |
|
175 |
else return computeNearestAngle(basicAngle,angle,speed); |
|
176 |
} |
|
177 |
else |
|
178 |
{ |
|
179 |
if( mGhostIsUp[row] ) |
|
180 |
{ |
|
181 |
int a = computeGhostAngle(basicAngle,angle,speed); |
|
182 |
if( angleIsGhost(a,basicAngle) ) |
|
183 |
{ |
|
184 |
changeRow(row,false); |
|
185 |
mUpRight--; |
|
186 |
if( mNumRight==1 ) enableGhostAxis(false); |
|
187 |
} |
|
188 |
return a; |
|
189 |
} |
|
190 |
else return computeNearestAngle(basicAngle,angle,speed); |
|
191 |
} |
|
192 |
} |
|
70 | 193 |
} |
71 | 194 |
|
72 | 195 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
73 | 196 |
|
74 |
private float getAngle()
|
|
197 |
private int computeRowBitmap(boolean[] up)
|
|
75 | 198 |
{ |
76 |
int pointNum = mRotationAngle.getNumPoints(); |
|
77 |
return pointNum>=1 ? mRotationAngle.getPoint(pointNum-1).get0() : 0; |
|
199 |
int ret = 0; |
|
200 |
int tmp = 1; |
|
201 |
|
|
202 |
for(int l=0; l<mNumLayer0; l++) |
|
203 |
{ |
|
204 |
if( up[l] ) ret += tmp; |
|
205 |
tmp *= 2; |
|
206 |
} |
|
207 |
|
|
208 |
return ret; |
|
209 |
} |
|
210 |
|
|
211 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
212 |
|
|
213 |
private void enableGhostAxis(boolean enable) |
|
214 |
{ |
|
215 |
mParent.enableGhostAxis(enable); |
|
216 |
} |
|
217 |
|
|
218 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
219 |
|
|
220 |
private void changeTotalGhostAngle(int diff) |
|
221 |
{ |
|
222 |
mGhostN += diff; |
|
223 |
mGhostN %= 360; |
|
224 |
mGhostAngleN.set0(mGhostN*mGhostAngle); |
|
225 |
} |
|
226 |
|
|
227 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
228 |
|
|
229 |
private void changeRow(int row, boolean up) |
|
230 |
{ |
|
231 |
mGhostIsUp[row] = up; |
|
232 |
int rowBitmap = computeRowBitmap(mGhostIsUp); |
|
233 |
mGhostEffect1.setMeshAssociation( rowBitmap , -1); |
|
234 |
} |
|
235 |
|
|
236 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
237 |
// TODO |
|
238 |
|
|
239 |
private int computeGhostAngle(int basicAngle, float angle, float speed) |
|
240 |
{ |
|
241 |
int basicDeg = 360/basicAngle; |
|
242 |
int numRot = (int)(angle/basicDeg + 0.5f); |
|
243 |
if( angle< -(basicDeg*0.5) ) numRot-=1; |
|
244 |
if( numRot==0 && speed>1.1f ) numRot = (angle>0 ? 1:-1); |
|
245 |
return basicDeg*numRot; |
|
246 |
} |
|
247 |
|
|
248 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
249 |
// END GHOST |
|
250 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
251 |
|
|
252 |
private int computeNearestAngle(int basicAngle, float angle, float speed) |
|
253 |
{ |
|
254 |
int basicDeg = 360/basicAngle; |
|
255 |
int numRot = (int)(angle/basicDeg + 0.5f); |
|
256 |
if( angle< -(basicDeg*0.5) ) numRot-=1; |
|
257 |
if( numRot==0 && speed>1.1f ) numRot = (angle>0 ? 1:-1); |
|
258 |
return basicDeg*numRot; |
|
259 |
} |
|
260 |
|
|
261 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
262 |
|
|
263 |
private int computeNearestAngle(int axisIndex, int row, int basicAngle, float angle, float speed) |
|
264 |
{ |
|
265 |
if( mGhostAngle==0 || axisIndex!=0 ) return computeNearestAngle(basicAngle,angle,speed); |
|
266 |
else return computeGhostAngle(row,basicAngle,angle,speed); |
|
78 | 267 |
} |
79 | 268 |
|
80 | 269 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
81 | 270 |
|
82 |
VertexEffectRotate getEffect()
|
|
271 |
private float getAngle()
|
|
83 | 272 |
{ |
84 |
return mRotateEffect; |
|
273 |
int pointNum = mRotationAngle.getNumPoints(); |
|
274 |
return pointNum>=1 ? mRotationAngle.getPoint(pointNum-1).get0() : 0; |
|
85 | 275 |
} |
86 | 276 |
|
87 | 277 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
88 | 278 |
// API |
89 | 279 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
280 |
// the rotation has fully finished (everything including the last mini 'come back'). Delete it. |
|
90 | 281 |
|
91 |
synchronized float removeRotationNow()
|
|
282 |
synchronized float removeRotation() |
|
92 | 283 |
{ |
93 | 284 |
float angle = getAngle(); |
94 | 285 |
|
... | ... | |
101 | 292 |
} |
102 | 293 |
|
103 | 294 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
295 |
// we have just lifted the finger |
|
104 | 296 |
|
105 |
long finishRotationNow(EffectListener listener, int basicAngle, float finishAngle, float avgSpeed)
|
|
297 |
long finishRotation(EffectListener listener, int axisIndex, int row, int basicAngle, float finishAngle, float avgSpeed)
|
|
106 | 298 |
{ |
107 |
int nearestAngleInDegrees = computeNearestAngle(basicAngle,finishAngle,avgSpeed); |
|
299 |
int nearestAngleInDegrees = computeNearestAngle(axisIndex,row,basicAngle,finishAngle,avgSpeed);
|
|
108 | 300 |
|
109 | 301 |
mRotationState = STATE_FINISH; |
110 | 302 |
float angle = getAngle(); |
... | ... | |
124 | 316 |
} |
125 | 317 |
|
126 | 318 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
319 |
// rotation has begun and we have just moved the finger a bit |
|
127 | 320 |
|
128 | 321 |
void continueRotation(float angleInDegrees) |
129 | 322 |
{ |
... | ... | |
131 | 324 |
} |
132 | 325 |
|
133 | 326 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
327 |
// this is 'programmatic' rotation - i.e. for example the one induced by the 'backMove' button. |
|
134 | 328 |
|
135 |
synchronized long addNewRotation(EffectListener listener, Static3D axis, int axisIndex, int rowBitmap, int angle, long durationMillis )
|
|
329 |
synchronized long addRotation(EffectListener listener, Static3D axis, int axisIndex, int rowBitmap, int angle, long durationMillis ) |
|
136 | 330 |
{ |
137 | 331 |
int mult = 1; |
138 | 332 |
|
139 | 333 |
if( mRotationState==STATE_ROTATE ) return 0; |
140 |
if( mRotationState==STATE_FINISH ) { removeRotationNow(); mult = -1; }
|
|
334 |
if( mRotationState==STATE_FINISH ) { removeRotation(); mult = -1; } |
|
141 | 335 |
|
142 | 336 |
mRotationState = STATE_ROTATE; |
143 |
mCurrentRotAxis = axisIndex;
|
|
144 |
mRotRowBitmap= mParent.computeBandagedBitmap(rowBitmap,axisIndex); |
|
337 |
mCurrentRotAxis= axisIndex; |
|
338 |
mRotRowBitmap = mParent.computeBandagedBitmap(rowBitmap,axisIndex);
|
|
145 | 339 |
mRotationAngleStatic.set0(0.0f); |
146 | 340 |
mRotationAxis.set(axis); |
147 | 341 |
mRotationAngle.setDuration(durationMillis); |
... | ... | |
155 | 349 |
} |
156 | 350 |
|
157 | 351 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
352 |
// i.e. we just touched the screen, moved it a little bit and the TouchControl has figured out |
|
353 |
// along which axis we are going to rotate. |
|
158 | 354 |
|
159 |
synchronized boolean beginNewRotation(Static3D axis, int axisIndex, int row )
|
|
355 |
synchronized boolean beginRotation(Static3D axis, int axisIndex, int row ) |
|
160 | 356 |
{ |
161 | 357 |
if( mRotationState==STATE_ROTATE ) return false; |
162 |
if( mRotationState==STATE_FINISH ) removeRotationNow();
|
|
358 |
if( mRotationState==STATE_FINISH ) removeRotation(); |
|
163 | 359 |
|
164 | 360 |
mRotationState = STATE_ROTATE; |
165 |
mCurrentRotAxis = axisIndex;
|
|
166 |
mRotRowBitmap= mParent.computeBandagedBitmap( (1<<row),axisIndex ); |
|
361 |
mCurrentRotAxis= axisIndex; |
|
362 |
mRotRowBitmap = mParent.computeBandagedBitmap( (1<<row),axisIndex );
|
|
167 | 363 |
mRotationAngleStatic.set0(0.0f); |
168 | 364 |
mRotationAxis.set(axis); |
169 | 365 |
mRotationAngle.add(mRotationAngleStatic); |
src/main/java/org/distorted/objectlib/main/TwistyObject.java | ||
---|---|---|
229 | 229 |
mNumFaceColors = getNumFaceColors(); |
230 | 230 |
mBelongs = new boolean[mNumCubits]; |
231 | 231 |
|
232 |
mRotation = new TwistyLayerRotations(this,mMaxNumLayers,getGhostAngle()); |
|
233 |
|
|
234 | 232 |
int scramblingType = getScrambleType(); |
235 | 233 |
int[][] edges = getScrambleEdges(); |
236 | 234 |
int[][] algorithms = getScrambleAlgorithms(); |
... | ... | |
258 | 256 |
mEffects = new DistortedEffects(); |
259 | 257 |
createQuaternionEffects(); |
260 | 258 |
|
261 |
VertexEffectRotate rotateEffect = mRotation.getEffect(); |
|
259 |
mRotation = new TwistyLayerRotations(this,mAxis[0],mNumLayers,getGhostAngle(),mEffects); |
|
260 |
|
|
262 | 261 |
MatrixEffectScale scaleEffect = new MatrixEffectScale(mObjectScale); |
263 | 262 |
MatrixEffectQuaternion quatEffect = new MatrixEffectQuaternion(mQuat, CENTER); |
264 | 263 |
MatrixEffectMove moveEffect = new MatrixEffectMove(move); |
... | ... | |
273 | 272 |
mSolved = new TwistyObjectSolved(this,mOrigPos,index); |
274 | 273 |
mSolved.setupSolvedQuats(getSolvedQuats()); |
275 | 274 |
|
276 |
mEffects.apply(rotateEffect); |
|
277 | 275 |
mEffects.apply(quatEffect); |
278 | 276 |
mEffects.apply(scaleEffect); |
279 | 277 |
mEffects.apply(moveEffect); |
... | ... | |
1103 | 1101 |
|
1104 | 1102 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1105 | 1103 |
|
1106 |
synchronized float removeRotationNow()
|
|
1104 |
synchronized float removeRotation() |
|
1107 | 1105 |
{ |
1108 |
return mRotation.removeRotationNow();
|
|
1106 |
return mRotation.removeRotation(); |
|
1109 | 1107 |
} |
1110 | 1108 |
|
1111 | 1109 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1112 | 1110 |
|
1113 |
long finishRotationNow(EffectListener listener, int finishAx, int finishRow, float finishAngle, float avgSpeed)
|
|
1111 |
long finishRotation(EffectListener listener, int finishAx, int finishRow, float finishAngle, float avgSpeed) |
|
1114 | 1112 |
{ |
1115 | 1113 |
int basicAngle = mBasicAngles[finishAx][finishRow]; |
1116 |
return mRotation.finishRotationNow(listener,basicAngle,finishAngle,avgSpeed);
|
|
1114 |
return mRotation.finishRotation(listener,finishAx,finishRow,basicAngle,finishAngle,avgSpeed);
|
|
1117 | 1115 |
} |
1118 | 1116 |
|
1119 | 1117 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
1125 | 1123 |
|
1126 | 1124 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1127 | 1125 |
|
1128 |
synchronized long addNewRotation(EffectListener listener, int axis, int rowBitmap, int angle, long durationMillis ) |
|
1126 |
synchronized long addRotation(EffectListener listener, int axis, int rowBitmap, int angle, long durationMillis ) |
|
1127 |
{ |
|
1128 |
return mRotation.addRotation(listener,mAxis[axis],axis,rowBitmap,angle,durationMillis); |
|
1129 |
} |
|
1130 |
|
|
1131 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1132 |
|
|
1133 |
void enableGhostAxis(boolean enable) |
|
1129 | 1134 |
{ |
1130 |
return mRotation.addNewRotation(listener,mAxis[axis],axis,rowBitmap,angle,durationMillis);
|
|
1135 |
mTouchControl.enableGhostAxis(enable);
|
|
1131 | 1136 |
} |
1132 | 1137 |
|
1133 | 1138 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
1134 | 1139 |
|
1135 |
synchronized boolean beginNewRotation(int axis, int row )
|
|
1140 |
synchronized boolean beginRotation(int axis, int row ) |
|
1136 | 1141 |
{ |
1137 | 1142 |
if( axis<0 || axis>=mNumAxis ) |
1138 | 1143 |
{ |
... | ... | |
1145 | 1150 |
return false; |
1146 | 1151 |
} |
1147 | 1152 |
|
1148 |
return mRotation.beginNewRotation(mAxis[axis],axis,row);
|
|
1153 |
return mRotation.beginRotation(mAxis[axis],axis,row); |
|
1149 | 1154 |
} |
1150 | 1155 |
|
1151 | 1156 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
src/main/java/org/distorted/objectlib/touchcontrol/TouchControl.java | ||
---|---|---|
150 | 150 |
public abstract int getTouchedCubitFace(); |
151 | 151 |
public abstract int getTouchedCubit(); |
152 | 152 |
public abstract float[] getTouchedPuzzleCenter(); |
153 |
public abstract void enableGhostAxis(boolean enable); |
|
153 | 154 |
} |
src/main/java/org/distorted/objectlib/touchcontrol/TouchControlBall.java | ||
---|---|---|
31 | 31 |
private final float[] mMove2D; |
32 | 32 |
private final float[][] mCastedRotAxis; |
33 | 33 |
private float[][] mTouchBorders; |
34 |
private boolean mGhostAxisEnabled; |
|
34 | 35 |
|
35 | 36 |
private float mLongitude, mLatitude; |
36 | 37 |
private float mX, mY, mZ; |
... | ... | |
81 | 82 |
mEnabledRotAxis = new int[numRotAxis+1]; |
82 | 83 |
mCastedRotAxis = new float[numRotAxis][2]; |
83 | 84 |
|
85 |
mGhostAxisEnabled = true; |
|
86 |
|
|
84 | 87 |
computeBorders(cuts,rotatable,size); |
85 | 88 |
} |
86 | 89 |
|
... | ... | |
212 | 215 |
|
213 | 216 |
private void computeEnabledAxis() |
214 | 217 |
{ |
215 |
int face = returnTouchedFace(); |
|
216 |
int part = returnTouchedPart(); |
|
217 |
int num = mEnabled[face][0].length; |
|
218 |
mEnabledRotAxis[0] = num; |
|
219 |
System.arraycopy(mEnabled[face][part], 0, mEnabledRotAxis, 1, num); |
|
218 |
if( mGhostAxisEnabled ) |
|
219 |
{ |
|
220 |
int face = returnTouchedFace(); |
|
221 |
int part = returnTouchedPart(); |
|
222 |
int num = mEnabled[face][0].length; |
|
223 |
mEnabledRotAxis[0] = num; |
|
224 |
System.arraycopy(mEnabled[face][part], 0, mEnabledRotAxis, 1, num); |
|
225 |
} |
|
226 |
else |
|
227 |
{ |
|
228 |
mEnabledRotAxis[0] = 1; // if in 'ghost' mode, only the 0th axis is enabled. |
|
229 |
mEnabledRotAxis[1] = 0; |
|
230 |
} |
|
220 | 231 |
} |
221 | 232 |
|
222 | 233 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
350 | 361 |
{ |
351 | 362 |
return false; |
352 | 363 |
} |
364 |
|
|
365 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
366 |
|
|
367 |
public void enableGhostAxis(boolean enable) |
|
368 |
{ |
|
369 |
mGhostAxisEnabled = enable; |
|
370 |
} |
|
353 | 371 |
} |
src/main/java/org/distorted/objectlib/touchcontrol/TouchControlMirror.java | ||
---|---|---|
148 | 148 |
float dy = mPoint[1] - rotatedTouchPoint.get1()/mObjectRatio; |
149 | 149 |
float dz = mPoint[2] - rotatedTouchPoint.get2()/mObjectRatio; |
150 | 150 |
|
151 |
int disabledAxis = computeDisabledAxis(); |
|
152 |
int rotIndex = computeRotationIndex(disabledAxis,dx,dy,dz); |
|
153 |
int row = computeRow(mTouchedCubit,rotIndex); |
|
154 |
|
|
155 |
output[0] = rotIndex; |
|
156 |
output[1] = row; |
|
151 |
if( mGhostAxisEnabled ) |
|
152 |
{ |
|
153 |
int disabledAxis = computeDisabledAxis(); |
|
154 |
int rotIndex = computeRotationIndex(disabledAxis,dx,dy,dz); |
|
155 |
int row = computeRow(mTouchedCubit,rotIndex); |
|
156 |
output[0] = rotIndex; |
|
157 |
output[1] = row; |
|
158 |
} |
|
159 |
else |
|
160 |
{ |
|
161 |
output[0] = 0; |
|
162 |
output[1] = computeRow(mTouchedCubit,0); |
|
163 |
} |
|
157 | 164 |
} |
158 | 165 |
} |
src/main/java/org/distorted/objectlib/touchcontrol/TouchControlShapeChanging.java | ||
---|---|---|
95 | 95 |
int mTouchedCubit, mTouchedFace, mNumAxis; |
96 | 96 |
FaceInfo[][] mInfos; |
97 | 97 |
float[][] mQuats; |
98 |
boolean mGhostAxisEnabled; |
|
98 | 99 |
|
99 | 100 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
100 | 101 |
|
... | ... | |
615 | 616 |
{ |
616 | 617 |
return mTouchedCubit; |
617 | 618 |
} |
619 |
|
|
620 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
621 |
|
|
622 |
public void enableGhostAxis(boolean enable) |
|
623 |
{ |
|
624 |
mGhostAxisEnabled = enable; |
|
625 |
} |
|
618 | 626 |
} |
src/main/java/org/distorted/objectlib/touchcontrol/TouchControlShapeConstant.java | ||
---|---|---|
35 | 35 |
|
36 | 36 |
private final int mSplit; |
37 | 37 |
private final int[][][] mEnabled; |
38 |
private boolean mGhostAxisEnabled; |
|
38 | 39 |
|
39 | 40 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
40 | 41 |
|
... | ... | |
69 | 70 |
|
70 | 71 |
mDistanceCenterFace3D = distance3D; // distance from the center of the object to each of its faces |
71 | 72 |
|
73 |
mGhostAxisEnabled = true; |
|
74 |
|
|
72 | 75 |
computeCastedAxis(mRotAxis); |
73 | 76 |
computeBorders(cuts,rotatable,size); |
74 | 77 |
computeLinear(mRotAxis,faceAxis); |
... | ... | |
318 | 321 |
|
319 | 322 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
320 | 323 |
|
321 |
void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
|
|
324 |
void computeEnabledAxis(int face, float[] touchPoint) |
|
322 | 325 |
{ |
323 |
int part = returnPart(mSplit,face,touchPoint); |
|
326 |
if( mGhostAxisEnabled ) |
|
327 |
{ |
|
328 |
int part = returnPart(mSplit, face, touchPoint); |
|
324 | 329 |
|
325 |
int num = mEnabled[face][0].length; |
|
326 |
enabled[0] = num; |
|
327 |
System.arraycopy(mEnabled[face][part], 0, enabled, 1, num); |
|
330 |
int num = mEnabled[face][0].length; |
|
331 |
mEnabledRotAxis[0] = num; |
|
332 |
System.arraycopy(mEnabled[face][part], 0, mEnabledRotAxis, 1, num); |
|
333 |
} |
|
334 |
else |
|
335 |
{ |
|
336 |
mEnabledRotAxis[0] = 1; // if in 'ghost' mode, only the 0th axis is enabled. |
|
337 |
mEnabledRotAxis[1] = 0; |
|
338 |
} |
|
328 | 339 |
} |
329 | 340 |
|
330 | 341 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
378 | 389 |
mMove2D[0] -= mPoint2D[0]; |
379 | 390 |
mMove2D[1] -= mPoint2D[1]; |
380 | 391 |
|
381 |
computeEnabledAxis(mLastTouchedFace, mPoint2D, mEnabledRotAxis);
|
|
392 |
computeEnabledAxis(mLastTouchedFace, mPoint2D); |
|
382 | 393 |
int rotIndex = computeRotationIndex( mCastedRotAxis[mLastTouchedFace], mMove2D, mEnabledRotAxis); |
383 | 394 |
float offset = computeOffset(mPoint2D, mCastedRotAxis[mLastTouchedFace][rotIndex]); |
384 | 395 |
int row = computeRowFromOffset(mLastTouchedFace,rotIndex,offset); |
... | ... | |
452 | 463 |
{ |
453 | 464 |
return 0; |
454 | 465 |
} |
466 |
|
|
467 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
468 |
|
|
469 |
public void enableGhostAxis(boolean enable) |
|
470 |
{ |
|
471 |
mGhostAxisEnabled = enable; |
|
472 |
} |
|
455 | 473 |
} |
src/main/java/org/distorted/objectlib/touchcontrol/TouchControlShapemod.java | ||
---|---|---|
94 | 94 |
float dy = mPoint[1] - rotatedTouchPoint.get1()/mObjectRatio; |
95 | 95 |
float dz = mPoint[2] - rotatedTouchPoint.get2()/mObjectRatio; |
96 | 96 |
|
97 |
int disabledAxis = computeDisabledAxis(quat); |
|
98 |
int rotIndex = computeRotationIndex(disabledAxis,dx,dy,dz); |
|
99 |
int row = computeRow(mTouchedCubit,rotIndex); |
|
100 |
|
|
101 |
output[0] = rotIndex; |
|
102 |
output[1] = row; |
|
97 |
if( mGhostAxisEnabled ) |
|
98 |
{ |
|
99 |
int disabledAxis = computeDisabledAxis(quat); |
|
100 |
int rotIndex = computeRotationIndex(disabledAxis,dx,dy,dz); |
|
101 |
int row = computeRow(mTouchedCubit,rotIndex); |
|
102 |
output[0] = rotIndex; |
|
103 |
output[1] = row; |
|
104 |
} |
|
105 |
else |
|
106 |
{ |
|
107 |
output[0] = 0; |
|
108 |
output[1] = computeRow(mTouchedCubit,0); |
|
109 |
} |
|
103 | 110 |
} |
104 | 111 |
} |
Also available in: Unified diff
progress with Ghost rotations.