28 |
28 |
|
29 |
29 |
public class TouchControlShapeChanging extends TouchControl
|
30 |
30 |
{
|
31 |
|
private static final float NOT_TOUCHED = -1000000.0f;
|
|
31 |
private static final float NOT_TOUCHED = 1000000.0f;
|
32 |
32 |
private static final float[] mTmp = new float[4];
|
33 |
33 |
|
34 |
34 |
private static class FaceInfo
|
... | ... | |
38 |
38 |
private final float[][] vertices;
|
39 |
39 |
private final float[][] rotated;
|
40 |
40 |
|
41 |
|
FaceInfo(float[][] verts)
|
|
41 |
FaceInfo(float[][] verts, float size)
|
42 |
42 |
{
|
43 |
|
vertices = verts;
|
44 |
|
vector = new float[4];
|
|
43 |
int numV = verts.length;
|
|
44 |
|
|
45 |
vertices = new float[numV][];
|
|
46 |
rotated = new float[numV][];
|
45 |
47 |
|
46 |
|
int numV = vertices.length;
|
47 |
|
rotated = new float[numV][];
|
48 |
|
for(int i=0; i<numV; i++) rotated[i] = new float[vertices[i].length];
|
|
48 |
for(int i=0; i<numV; i++)
|
|
49 |
{
|
|
50 |
int len = verts[i].length;
|
|
51 |
vertices[i]= new float[len];
|
|
52 |
rotated[i] = new float[len];
|
|
53 |
|
|
54 |
for(int j=0; j<len; j++) vertices[i][j] = verts[i][j]/size;
|
|
55 |
}
|
49 |
56 |
|
50 |
57 |
// assuming the first three vertices are linearly independent
|
51 |
58 |
float a1 = vertices[0][0] - vertices[1][0];
|
... | ... | |
75 |
82 |
vz = -vz;
|
76 |
83 |
}
|
77 |
84 |
|
|
85 |
vector = new float[4];
|
78 |
86 |
vector[0] = vx;
|
79 |
87 |
vector[1] = vy;
|
80 |
88 |
vector[2] = vz;
|
81 |
89 |
vector[3] = 0.0f;
|
82 |
|
distance = dist;
|
|
90 |
|
|
91 |
distance = dist;
|
83 |
92 |
}
|
84 |
93 |
}
|
85 |
94 |
|
... | ... | |
107 |
116 |
|
108 |
117 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
109 |
118 |
|
110 |
|
private FaceInfo[] computeInfos(float[][] vertices, int[][] indices, float[] position, Static4D quat)
|
|
119 |
private FaceInfo[] computeInfos(float[][] vertices, int[][] indices, float[] position, Static4D quat, float size)
|
111 |
120 |
{
|
112 |
121 |
int numFaces = indices.length;
|
113 |
122 |
|
... | ... | |
151 |
160 |
verts[j][3] = 1.0f;
|
152 |
161 |
}
|
153 |
162 |
|
154 |
|
infos[i] = new FaceInfo(verts);
|
|
163 |
infos[i] = new FaceInfo(verts,size);
|
155 |
164 |
}
|
156 |
165 |
|
157 |
166 |
return infos;
|
... | ... | |
163 |
172 |
{
|
164 |
173 |
int[] numLayers = mObject.getNumLayers();
|
165 |
174 |
float[][] positions = mObject.getCubitPositions(numLayers);
|
|
175 |
float size = mObject.getSize();
|
166 |
176 |
mNumCubits = positions.length;
|
167 |
177 |
mNumFaces = new int[mNumCubits];
|
168 |
178 |
|
... | ... | |
175 |
185 |
Static4D quat = mObject.getQuat(i,numLayers);
|
176 |
186 |
float[][] vertices = shape.getVertices();
|
177 |
187 |
int[][] indices = shape.getVertIndices();
|
178 |
|
mInfos[i] = computeInfos(vertices,indices,positions[i],quat);
|
|
188 |
mInfos[i] = computeInfos(vertices,indices,positions[i],quat,size);
|
179 |
189 |
mNumFaces[i] = indices.length;
|
180 |
190 |
}
|
181 |
191 |
|
... | ... | |
211 |
221 |
private boolean areOnDifferentSides(float[] p1, float[] p2, float[] point1, float[] point2 )
|
212 |
222 |
{
|
213 |
223 |
float a1 = point2[0] - point1[0];
|
214 |
|
float a2 = point2[1] - point1[2];
|
215 |
|
float a3 = point2[2] - point1[3];
|
|
224 |
float a2 = point2[1] - point1[1];
|
|
225 |
float a3 = point2[2] - point1[2];
|
216 |
226 |
float b1 = p1[0] - point2[0];
|
217 |
|
float b2 = p1[1] - point2[2];
|
218 |
|
float b3 = p1[2] - point2[3];
|
|
227 |
float b2 = p1[1] - point2[1];
|
|
228 |
float b3 = p1[2] - point2[2];
|
219 |
229 |
float c1 = p2[0] - point2[0];
|
220 |
|
float c2 = p2[1] - point2[2];
|
221 |
|
float c3 = p2[2] - point2[3];
|
|
230 |
float c2 = p2[1] - point2[1];
|
|
231 |
float c3 = p2[2] - point2[2];
|
222 |
232 |
|
223 |
233 |
float vx1 = a2*b3-a3*b2;
|
224 |
234 |
float vy1 = a3*b1-a1*b3;
|
... | ... | |
313 |
323 |
// 4) else, rotate 'vertices' by quat and see if the casted point lies inside the polygon defined by them
|
314 |
324 |
// 5) if yes, return its Z; otherwise, return NOT_TOUCHED
|
315 |
325 |
|
316 |
|
private float cubitFaceTouched(FaceInfo info, float[] quat, float closestSoFar)
|
|
326 |
private float cubitFaceTouched(FaceInfo info, float[] quat, float closestSoFar, int cubit, int face)
|
317 |
327 |
{
|
318 |
328 |
QuatHelper.rotateVectorByQuat(mTmp,info.vector,quat);
|
319 |
329 |
float nx = mTmp[0];
|
... | ... | |
324 |
334 |
{
|
325 |
335 |
castTouchPointOntoFace(nx,ny,nz,info.distance,mTouch);
|
326 |
336 |
|
327 |
|
if( mTouch[2]>closestSoFar )
|
|
337 |
float dx = mTouch[0]-mCamera[0];
|
|
338 |
float dy = mTouch[1]-mCamera[1];
|
|
339 |
float dz = mTouch[2]-mCamera[2];
|
|
340 |
float dist = dx*dx + dy*dy + dz*dz;
|
|
341 |
|
|
342 |
if( dist<closestSoFar )
|
328 |
343 |
{
|
329 |
344 |
rotateVertices(info.vertices,info.rotated,quat);
|
330 |
|
if( isInside(mTouch,info.rotated) ) return mTouch[2];
|
|
345 |
if( isInside(mTouch,info.rotated) ) return dist;
|
331 |
346 |
}
|
332 |
347 |
}
|
333 |
348 |
|
... | ... | |
354 |
369 |
mTouchedCubit = -1;
|
355 |
370 |
mTouchedFace = -1;
|
356 |
371 |
|
357 |
|
for(int i=0; i<mNumCubits; i++)
|
|
372 |
for(int cubit=0; cubit<mNumCubits; cubit++)
|
358 |
373 |
{
|
359 |
|
int quatIndex = mObject.getCubitQuatIndex(i);
|
|
374 |
int quatIndex = mObject.getCubitQuatIndex(cubit);
|
360 |
375 |
float[] quat = mQuats[quatIndex];
|
361 |
376 |
|
362 |
|
for(int j=0; j<mNumFaces[i]; j++)
|
|
377 |
for(int face=0; face<mNumFaces[cubit]; face++)
|
363 |
378 |
{
|
364 |
|
float dist = cubitFaceTouched(mInfos[i][j],quat,closestSoFar);
|
|
379 |
float dist = cubitFaceTouched(mInfos[cubit][face],quat,closestSoFar,cubit,face);
|
|
380 |
|
365 |
381 |
if( dist!=NOT_TOUCHED )
|
366 |
382 |
{
|
367 |
|
mTouchedCubit = i;
|
368 |
|
mTouchedFace = j;
|
|
383 |
mTouchedCubit= cubit;
|
|
384 |
mTouchedFace = face;
|
|
385 |
closestSoFar = dist;
|
369 |
386 |
}
|
370 |
|
closestSoFar = dist;
|
371 |
387 |
}
|
372 |
388 |
}
|
373 |
389 |
|
374 |
390 |
if( closestSoFar!=NOT_TOUCHED )
|
375 |
391 |
{
|
376 |
|
android.util.Log.e("D", "cubit="+mTouchedCubit+" face="+mTouchedFace);
|
|
392 |
android.util.Log.e("D", "cubit="+mTouchedCubit+" face="+mTouchedFace+" result: "+closestSoFar);
|
377 |
393 |
}
|
378 |
394 |
|
379 |
395 |
return closestSoFar!=NOT_TOUCHED;
|
Fixes for the ShapeChanging touch control.