Revision 123d6172
Added by Leszek Koltunski almost 5 years ago
src/main/java/org/distorted/magic/RubikRenderer.java | ||
---|---|---|
38 | 38 |
|
39 | 39 |
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener |
40 | 40 |
{ |
41 |
private static final float CAMERA_DISTANCE = 0.6f; // 0.6 of the length of max(scrHeight,scrWidth)
|
|
42 |
public static final int TEXTURE_SIZE = 600;
|
|
41 |
public static final float CAMERA_DISTANCE = 0.6f; // 0.6 of the length of max(scrHeight,scrWidth)
|
|
42 |
public static final int TEXTURE_SIZE = 600; |
|
43 | 43 |
|
44 | 44 |
private RubikSurfaceView mView; |
45 | 45 |
private DistortedScreen mScreen; |
... | ... | |
85 | 85 |
mNextCubeSize = RubikSize.getSize(mView.getRedButton()).getCubeSize(); |
86 | 86 |
} |
87 | 87 |
|
88 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
89 |
|
|
90 |
private float computeFOV(float cameraDistance, int screenHeight) |
|
91 |
{ |
|
92 |
double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) ); |
|
93 |
return (float)(2*halfFOVInRadians*(180/Math.PI)); |
|
94 |
} |
|
95 |
|
|
96 | 88 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
97 | 89 |
|
98 | 90 |
private void createCubeNow(int newSize) |
... | ... | |
297 | 289 |
{ |
298 | 290 |
if( mNewCube!=null ) mNewCube.createTexture(); |
299 | 291 |
|
300 |
float cameraDistance = CAMERA_DISTANCE*(width>height ? width:height); |
|
301 |
float fovInDegrees = computeFOV(cameraDistance,height); |
|
302 |
|
|
303 |
mView.setScreenSize(width,height); |
|
304 |
mView.setCameraDist(cameraDistance); |
|
292 |
double halfFOVInRadians = Math.atan( 1.0f/(2*CAMERA_DISTANCE) ); |
|
293 |
float fovInDegrees = (float)(2*halfFOVInRadians*(180/Math.PI)); |
|
305 | 294 |
|
306 | 295 |
mScreen.setProjection( fovInDegrees, 0.1f); |
307 | 296 |
mScreen.resize(width, height); |
297 |
mView.setScreenSize(width,height); |
|
308 | 298 |
|
309 | 299 |
if( mNewCube!=null ) |
310 | 300 |
{ |
311 |
mNewCube.recomputeScaleFactor(width, height);
|
|
301 |
mNewCube.recomputeScaleFactor(width,height); |
|
312 | 302 |
} |
313 | 303 |
|
314 | 304 |
mScreenHeight = height; |
src/main/java/org/distorted/magic/RubikSurfaceView.java | ||
---|---|---|
61 | 61 |
|
62 | 62 |
private boolean mDragging, mBeginningRotation, mContinuingRotation; |
63 | 63 |
private float mX, mY; |
64 |
private int mLastTouchedFace; |
|
65 |
private float mCameraDistance; |
|
66 | 64 |
private int mScreenWidth, mScreenHeight, mScreenMin; |
67 | 65 |
|
68 | 66 |
private static Static4D mQuatCurrent = new Static4D(0,0,0,1); |
... | ... | |
135 | 133 |
mScreenMin = width<height ? width:height; |
136 | 134 |
} |
137 | 135 |
|
138 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
139 |
|
|
140 |
void setCameraDist(float distance) |
|
141 |
{ |
|
142 |
mCameraDistance = distance; |
|
143 |
} |
|
144 |
|
|
145 | 136 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
146 | 137 |
|
147 | 138 |
RubikRenderer getRenderer() |
... | ... | |
359 | 350 |
{ |
360 | 351 |
case MotionEvent.ACTION_DOWN: mX = x; |
361 | 352 |
mY = y; |
362 |
mLastTouchedFace = mMovement.faceTouched(mQuatAccumulated,mCameraDistance/mScreenMin, x, y); |
|
363 | 353 |
|
364 |
if( mLastTouchedFace != RubikCubeMovement.NONE )
|
|
354 |
if( mMovement.faceTouched(mQuatAccumulated, x, y) )
|
|
365 | 355 |
{ |
366 | 356 |
mDragging = false; |
367 | 357 |
mBeginningRotation = mRenderer.canRotate(); |
... | ... | |
393 | 383 |
{ |
394 | 384 |
if( (mX-x)*(mX-x)+(mY-y)*(mY-y) > 1.0f/(ROTATION_SENSITIVITY*ROTATION_SENSITIVITY) ) |
395 | 385 |
{ |
396 |
Static2D rot = mMovement.newRotation(mQuatAccumulated,mLastTouchedFace, x, y);
|
|
386 |
Static2D rot = mMovement.newRotation(mQuatAccumulated, x, y); |
|
397 | 387 |
RubikCube cube = mRenderer.getCube(); |
398 | 388 |
|
399 | 389 |
cube.addNewRotation( (int)rot.get1(), (int)(cube.getSize()*rot.get2()) ); |
... | ... | |
404 | 394 |
} |
405 | 395 |
else if( mContinuingRotation ) |
406 | 396 |
{ |
407 |
float angle = mMovement.continueRotation(mQuatAccumulated,mLastTouchedFace, x, y); |
|
408 |
|
|
397 |
float angle = mMovement.continueRotation(mQuatAccumulated, x, y); |
|
409 | 398 |
mRenderer.getCube().continueRotation(SWIPING_SENSITIVITY*angle); |
410 | 399 |
} |
411 | 400 |
break; |
src/main/java/org/distorted/object/RubikCubeMovement.java | ||
---|---|---|
21 | 21 |
|
22 | 22 |
import org.distorted.library.type.Static2D; |
23 | 23 |
import org.distorted.library.type.Static4D; |
24 |
import org.distorted.magic.RubikRenderer; |
|
24 | 25 |
import org.distorted.magic.RubikSurfaceView; |
25 | 26 |
|
26 | 27 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
38 | 39 |
private static final int[] VECT = {RubikCube.VECTX,RubikCube.VECTY,RubikCube.VECTZ}; |
39 | 40 |
|
40 | 41 |
private float[] mPoint, mCamera, mTouchPointCastOntoFace, mDiff, mTouchPoint; |
41 |
private int mRotationVect; |
|
42 |
private int mRotationVect, mLastTouchedFace;
|
|
42 | 43 |
|
43 | 44 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
44 | 45 |
|
... | ... | |
139 | 140 |
|
140 | 141 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
141 | 142 |
|
142 |
private void convertCameraPointToScreenSpace(Static4D accumulated, float cameraDistance)
|
|
143 |
private void convertCameraPointToScreenSpace(Static4D accumulated) |
|
143 | 144 |
{ |
144 |
Static4D cameraPoint = new Static4D(0, 0, cameraDistance, 0);
|
|
145 |
Static4D cameraPoint = new Static4D(0, 0, RubikRenderer.CAMERA_DISTANCE, 0);
|
|
145 | 146 |
Static4D rotatedCamera= RubikSurfaceView.rotateVectorByInvertedQuat(cameraPoint, accumulated); |
146 | 147 |
|
147 | 148 |
mCamera[0] = rotatedCamera.get1(); |
... | ... | |
184 | 185 |
|
185 | 186 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
186 | 187 |
|
187 |
public int faceTouched(Static4D accumulated, float cameraDistance, float x, float y)
|
|
188 |
public boolean faceTouched(Static4D rotQuaternion, float x, float y)
|
|
188 | 189 |
{ |
189 | 190 |
float cubeHalfSize= RubikCube.CUBE_SCREEN_RATIO*0.5f; |
190 | 191 |
|
191 |
convertTouchPointToScreenSpace(accumulated,x,y);
|
|
192 |
convertCameraPointToScreenSpace(accumulated, cameraDistance);
|
|
192 |
convertTouchPointToScreenSpace(rotQuaternion,x,y);
|
|
193 |
convertCameraPointToScreenSpace(rotQuaternion);
|
|
193 | 194 |
|
194 |
for(int face=FRONT; face<=BOTTOM; face++)
|
|
195 |
for( mLastTouchedFace=FRONT; mLastTouchedFace<=BOTTOM; mLastTouchedFace++)
|
|
195 | 196 |
{ |
196 |
if( faceIsVisible(face,cubeHalfSize) )
|
|
197 |
if( faceIsVisible(mLastTouchedFace,cubeHalfSize) )
|
|
197 | 198 |
{ |
198 |
castTouchPointOntoFace(face,cubeHalfSize, mTouchPointCastOntoFace);
|
|
199 |
castTouchPointOntoFace(mLastTouchedFace,cubeHalfSize, mTouchPointCastOntoFace);
|
|
199 | 200 |
|
200 | 201 |
float qX= (mTouchPointCastOntoFace[0]+cubeHalfSize) / (2*cubeHalfSize); |
201 | 202 |
float qY= (mTouchPointCastOntoFace[1]+cubeHalfSize) / (2*cubeHalfSize); |
202 | 203 |
float qZ= (mTouchPointCastOntoFace[2]+cubeHalfSize) / (2*cubeHalfSize); |
203 | 204 |
|
204 |
if( qX<=1 && qX>=0 && qY<=1 && qY>=0 && qZ<=1 && qZ>=0 ) return face;
|
|
205 |
if( qX<=1 && qX>=0 && qY<=1 && qY>=0 && qZ<=1 && qZ>=0 ) return true;
|
|
205 | 206 |
} |
206 | 207 |
} |
207 | 208 |
|
208 |
return NONE; |
|
209 |
mLastTouchedFace = NONE; |
|
210 |
return false; |
|
209 | 211 |
} |
210 | 212 |
|
211 | 213 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
212 | 214 |
|
213 |
public Static2D newRotation(Static4D accumulated, int lastTouchedFace, float x, float y)
|
|
215 |
public Static2D newRotation(Static4D rotQuaternion, float x, float y)
|
|
214 | 216 |
{ |
215 | 217 |
float cubeHalfSize= RubikCube.CUBE_SCREEN_RATIO*0.5f; |
216 | 218 |
|
217 |
convertTouchPointToScreenSpace(accumulated,x,y);
|
|
218 |
castTouchPointOntoFace(lastTouchedFace,cubeHalfSize,mDiff);
|
|
219 |
convertTouchPointToScreenSpace(rotQuaternion,x,y);
|
|
220 |
castTouchPointOntoFace(mLastTouchedFace,cubeHalfSize,mDiff);
|
|
219 | 221 |
|
220 | 222 |
mDiff[0] -= mTouchPointCastOntoFace[0]; |
221 | 223 |
mDiff[1] -= mTouchPointCastOntoFace[1]; |
222 | 224 |
mDiff[2] -= mTouchPointCastOntoFace[2]; |
223 | 225 |
|
224 |
int xAxis = retFaceXaxis(lastTouchedFace);
|
|
225 |
int yAxis = retFaceYaxis(lastTouchedFace);
|
|
226 |
int xAxis = retFaceXaxis(mLastTouchedFace);
|
|
227 |
int yAxis = retFaceYaxis(mLastTouchedFace);
|
|
226 | 228 |
mRotationVect = (isVertical( mDiff[xAxis], mDiff[yAxis]) ? VECT[xAxis]:VECT[yAxis]); |
227 | 229 |
float offset= (mTouchPointCastOntoFace[mRotationVect]+cubeHalfSize)/(2*cubeHalfSize); |
228 | 230 |
|
... | ... | |
235 | 237 |
|
236 | 238 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
237 | 239 |
|
238 |
public float continueRotation(Static4D accumulated, int lastTouchedFace, float x, float y)
|
|
240 |
public float continueRotation(Static4D rotQuaternion, float x, float y)
|
|
239 | 241 |
{ |
240 |
convertTouchPointToScreenSpace(accumulated,x,y);
|
|
242 |
convertTouchPointToScreenSpace(rotQuaternion,x,y);
|
|
241 | 243 |
|
242 | 244 |
mDiff[0] = mPoint[0]-mTouchPoint[0]; |
243 | 245 |
mDiff[1] = mPoint[1]-mTouchPoint[1]; |
244 | 246 |
mDiff[2] = mPoint[2]-mTouchPoint[2]; |
245 | 247 |
|
246 |
int xAxis= retFaceXaxis(lastTouchedFace);
|
|
247 |
int yAxis= retFaceYaxis(lastTouchedFace);
|
|
248 |
int sign = retFaceRotationSign(lastTouchedFace);
|
|
248 |
int xAxis= retFaceXaxis(mLastTouchedFace);
|
|
249 |
int yAxis= retFaceYaxis(mLastTouchedFace);
|
|
250 |
int sign = retFaceRotationSign(mLastTouchedFace);
|
|
249 | 251 |
float angle = (mRotationVect==xAxis ? mDiff[yAxis] : -mDiff[xAxis]); |
250 | 252 |
|
251 | 253 |
return sign*angle; |
Also available in: Unified diff
Further simplifications for object movement.