Revision bfdb9aa5
Added by Leszek Koltunski over 1 year ago
src/main/java/org/distorted/objectlib/touchcontrol/TouchControlBall.java | ||
---|---|---|
19 | 19 |
|
20 | 20 |
public class TouchControlBall extends TouchControl |
21 | 21 |
{ |
22 |
private static final float MIN_LEN = 0.35f; |
|
23 |
private static final float[] mTmp = new float[4]; |
|
24 |
|
|
22 | 25 |
private final Static3D[] mRotAxis; |
23 |
private final float[] mPoint, mCamera; |
|
24 |
private float mLongitude, mLatitude; |
|
26 |
private final float[] mPoint, mCamera, mTouch; |
|
25 | 27 |
private final int[] mEnabledRotAxis; |
26 | 28 |
private final int[][][] mEnabled; |
29 |
private final float[] mMove2D; |
|
30 |
private final float[][] mCastedRotAxis; |
|
31 |
private float[][] mTouchBorders; |
|
32 |
|
|
33 |
private float mLongitude, mLatitude; |
|
34 |
private float mX, mY, mZ; |
|
27 | 35 |
|
28 | 36 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
29 | 37 |
|
... | ... | |
31 | 39 |
{ |
32 | 40 |
super(object.getObjectRatio()); |
33 | 41 |
|
42 |
int[] numLayers = object.getNumLayers(); |
|
43 |
float[][] cuts = object.getCuts(numLayers); |
|
44 |
boolean[][] rotatable = object.getLayerRotatable(numLayers); |
|
45 |
float size = object.getSize(); |
|
34 | 46 |
mRotAxis = object.getRotationAxis(); |
35 | 47 |
mEnabled = object.getEnabled(); |
36 | 48 |
|
49 |
mMove2D = new float[2]; |
|
50 |
|
|
37 | 51 |
mPoint = new float[3]; |
38 | 52 |
mCamera= new float[3]; |
39 |
mEnabledRotAxis = new int[mRotAxis.length+1]; |
|
53 |
mTouch = new float[3]; |
|
54 |
|
|
55 |
int numRotAxis = mRotAxis.length; |
|
56 |
mEnabledRotAxis = new int[numRotAxis+1]; |
|
57 |
mCastedRotAxis = new float[numRotAxis][2]; |
|
58 |
|
|
59 |
computeBorders(cuts,rotatable,size); |
|
60 |
} |
|
61 |
|
|
62 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
63 |
|
|
64 |
private float[] computeBorder(float[] cuts, boolean[] rotatable, float size) |
|
65 |
{ |
|
66 |
if( cuts==null ) return null; |
|
67 |
|
|
68 |
int len = cuts.length; |
|
69 |
float[] border = new float[len]; |
|
70 |
|
|
71 |
for(int i=0; i<len; i++) |
|
72 |
{ |
|
73 |
if( !rotatable[i] ) |
|
74 |
{ |
|
75 |
border[i] = i>0 ? border[i-1] : -Float.MAX_VALUE; |
|
76 |
} |
|
77 |
else |
|
78 |
{ |
|
79 |
if( rotatable[i+1] ) border[i] = cuts[i]/size; |
|
80 |
else |
|
81 |
{ |
|
82 |
int found = -1; |
|
83 |
|
|
84 |
for(int j=i+2; j<=len; j++) |
|
85 |
{ |
|
86 |
if( rotatable[j] ) |
|
87 |
{ |
|
88 |
found=j; |
|
89 |
break; |
|
90 |
} |
|
91 |
} |
|
92 |
|
|
93 |
border[i] = found>0 ? (cuts[i]+cuts[found-1])/(2*size) : Float.MAX_VALUE; |
|
94 |
} |
|
95 |
} |
|
96 |
} |
|
97 |
|
|
98 |
return border; |
|
99 |
} |
|
100 |
|
|
101 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
102 |
// size, not numLayers (see Master Skewb where size!=numLayers) - also cuboids. |
|
103 |
|
|
104 |
void computeBorders(float[][] cuts, boolean[][] rotatable, float size) |
|
105 |
{ |
|
106 |
int numCuts = cuts.length; |
|
107 |
mTouchBorders = new float[numCuts][]; |
|
108 |
|
|
109 |
for(int axis=0; axis<numCuts; axis++) |
|
110 |
{ |
|
111 |
mTouchBorders[axis] = computeBorder(cuts[axis],rotatable[axis],size); |
|
112 |
} |
|
113 |
} |
|
114 |
|
|
115 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
116 |
|
|
117 |
private int computeRowFromOffset(int axisIndex, float offset) |
|
118 |
{ |
|
119 |
float[] borders = mTouchBorders[axisIndex]; |
|
120 |
if( borders==null ) return 0; |
|
121 |
int len = borders.length; |
|
122 |
|
|
123 |
for(int i=0; i<len; i++) |
|
124 |
{ |
|
125 |
if( offset<borders[i] ) return i; |
|
126 |
} |
|
127 |
|
|
128 |
return len; |
|
40 | 129 |
} |
41 | 130 |
|
42 | 131 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
56 | 145 |
float vy = mCamera[1]-mPoint[1]; |
57 | 146 |
float vz = mCamera[2]-mPoint[2]; |
58 | 147 |
|
59 |
float px = cx + alpha*vx;
|
|
60 |
float py = cy + alpha*vy;
|
|
61 |
float pz = cz + alpha*vz;
|
|
148 |
mX = cx + alpha*vx;
|
|
149 |
mY = cy + alpha*vy;
|
|
150 |
mZ = cz + alpha*vz;
|
|
62 | 151 |
|
63 |
mLongitude = pz==0 ? 0 : (float)Math.atan(px/pz);
|
|
64 |
mLatitude = (float)Math.asin(2*py);
|
|
152 |
mLongitude = mZ==0 ? 0 : (float)Math.atan(mX/mZ);
|
|
153 |
mLatitude = (float)Math.asin(2*mY);
|
|
65 | 154 |
|
66 |
if( pz<0 ) mLongitude += Math.PI;
|
|
67 |
else if( px<0 ) mLongitude += 2*Math.PI;
|
|
155 |
if( mZ<0 ) mLongitude += Math.PI;
|
|
156 |
else if( mX<0 ) mLongitude += 2*Math.PI;
|
|
68 | 157 |
} |
69 | 158 |
|
70 | 159 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
86 | 175 |
return 0; |
87 | 176 |
} |
88 | 177 |
|
178 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
179 |
|
|
180 |
private float computeOffset(int rotIndex) |
|
181 |
{ |
|
182 |
Static3D axis = mRotAxis[rotIndex]; |
|
183 |
return mX*axis.get0() + mY*axis.get1() + mZ*axis.get2(); |
|
184 |
} |
|
185 |
|
|
89 | 186 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
90 | 187 |
|
91 | 188 |
private void computeEnabledAxis() |
... | ... | |
149 | 246 |
} |
150 | 247 |
|
151 | 248 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
152 |
// TODO |
|
153 | 249 |
|
154 | 250 |
public void newRotation(int[] output, Static4D rotatedTouchPoint, Static4D quat) |
155 | 251 |
{ |
156 | 252 |
computeEnabledAxis(); |
157 |
/* |
|
158 |
int rotIndex = computeRotationIndex( mCastedRotAxis[mLastTouchedFace], mMove2D, mEnabledRotAxis); |
|
159 |
float offset = computeOffset(mPoint2D, mCastedRotAxis[mLastTouchedFace][rotIndex]); |
|
160 |
int row = computeRowFromOffset(mLastTouchedFace,rotIndex,offset); |
|
161 |
*/ |
|
162 |
int rotIndex = 0; |
|
163 |
int row = 0; |
|
253 |
|
|
254 |
mTouch[0] = rotatedTouchPoint.get0()/mObjectRatio; |
|
255 |
mTouch[1] = rotatedTouchPoint.get1()/mObjectRatio; |
|
256 |
mTouch[2] = rotatedTouchPoint.get2()/mObjectRatio; |
|
257 |
|
|
258 |
float x = mTouch[0]-mPoint[0]; |
|
259 |
float y = mTouch[1]-mPoint[1]; |
|
260 |
float z = mTouch[2]-mPoint[2]; |
|
261 |
|
|
262 |
QuatHelper.rotateVectorByQuat(mTmp,x,y,z,0,quat); |
|
263 |
mMove2D[0] = mTmp[0]; |
|
264 |
mMove2D[1] = mTmp[1]; |
|
265 |
|
|
266 |
for(int i=1; i<=mEnabledRotAxis[0]; i++) |
|
267 |
{ |
|
268 |
int enabled = mEnabledRotAxis[i]; |
|
269 |
Static3D axis = mRotAxis[enabled]; |
|
270 |
float[] vector = mCastedRotAxis[enabled]; |
|
271 |
float bx = axis.get0(); |
|
272 |
float by = axis.get1(); |
|
273 |
float bz = axis.get2(); |
|
274 |
|
|
275 |
QuatHelper.rotateVectorByQuat(mTmp,bx,by,bz,0,quat); |
|
276 |
float len = (float)Math.sqrt(mTmp[0]*mTmp[0] + mTmp[1]*mTmp[1]); |
|
277 |
|
|
278 |
if( len<MIN_LEN ) |
|
279 |
{ |
|
280 |
vector[0] = 1000f; // switch off the axis because when casted |
|
281 |
vector[1] = 1000f; // onto the screen it is too short |
|
282 |
} |
|
283 |
else |
|
284 |
{ |
|
285 |
vector[0] = mTmp[0]/len; |
|
286 |
vector[1] = mTmp[1]/len; |
|
287 |
} |
|
288 |
} |
|
289 |
|
|
290 |
int rotIndex = computeRotationIndex( mCastedRotAxis, mMove2D, mEnabledRotAxis); |
|
291 |
float offset = computeOffset(rotIndex); |
|
292 |
int row = computeRowFromOffset(rotIndex,offset); |
|
164 | 293 |
|
165 | 294 |
output[0] = rotIndex; |
166 | 295 |
output[1] = row; |
Also available in: Unified diff
Finish TouchControl for the Masterball.
detection of the solved staet remains.