Revision 123d6172
Added by Leszek Koltunski almost 6 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.