Revision af8b42cc
Added by Leszek Koltunski over 6 years ago
| src/main/java/org/distorted/examples/rubik/RubikActivity.java | ||
|---|---|---|
| 35 | 35 |
public class RubikActivity extends Activity |
| 36 | 36 |
{
|
| 37 | 37 |
static final int DEFAULT_SIZE = 3; |
| 38 |
private static final int STARTING_SIZE = 2;
|
|
| 38 |
private static final int SMALLEST_SIZE = 2;
|
|
| 39 | 39 |
private static final int[] button_ids = {R.id.rubikSize2, R.id.rubikSize3, R.id.rubikSize4};
|
| 40 | 40 |
|
| 41 | 41 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 103 | 103 |
for(int b=0; b<button_ids.length; b++) |
| 104 | 104 |
if( button_ids[b] == id ) |
| 105 | 105 |
{
|
| 106 |
size = b+STARTING_SIZE;
|
|
| 106 |
size = b+SMALLEST_SIZE;
|
|
| 107 | 107 |
break; |
| 108 | 108 |
} |
| 109 | 109 |
|
| ... | ... | |
| 121 | 121 |
{
|
| 122 | 122 |
Drawable d = findViewById(button_ids[b]).getBackground(); |
| 123 | 123 |
|
| 124 |
if( size == b+STARTING_SIZE )
|
|
| 124 |
if( size == b+SMALLEST_SIZE )
|
|
| 125 | 125 |
{
|
| 126 | 126 |
d.setColorFilter(ContextCompat.getColor(this,R.color.red), PorterDuff.Mode.MULTIPLY); |
| 127 | 127 |
} |
| src/main/java/org/distorted/examples/rubik/RubikCube.java | ||
|---|---|---|
| 393 | 393 |
|
| 394 | 394 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 395 | 395 |
|
| 396 |
float getSize()
|
|
| 396 |
int getSize()
|
|
| 397 | 397 |
{
|
| 398 | 398 |
return mSize; |
| 399 | 399 |
} |
| src/main/java/org/distorted/examples/rubik/RubikRenderer.java | ||
|---|---|---|
| 49 | 49 |
private boolean mCanRotate; |
| 50 | 50 |
private RubikCube mCube; |
| 51 | 51 |
|
| 52 |
private int mScreenWidth, mScreenHeight; |
|
| 53 |
|
|
| 52 | 54 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 53 | 55 |
|
| 54 | 56 |
RubikRenderer(RubikSurfaceView v) |
| ... | ... | |
| 62 | 64 |
mQuatCurrent = new Static4D(0,0,0,1); |
| 63 | 65 |
mQuatAccumulated = initializeQuat(); |
| 64 | 66 |
|
| 67 |
mScreenWidth = mScreenHeight = 0; |
|
| 68 |
|
|
| 65 | 69 |
mMove = new Static3D(0,0,0); |
| 66 | 70 |
mScale = new Static3D(1,1,1); |
| 67 | 71 |
|
| ... | ... | |
| 71 | 75 |
mFinishDragAccumulated = false; |
| 72 | 76 |
|
| 73 | 77 |
mCanRotate = true; |
| 74 |
|
|
| 75 |
mCube = new RubikCube( RubikActivity.DEFAULT_SIZE, mMove, mScale, mQuatCurrent, mQuatAccumulated); |
|
| 76 | 78 |
} |
| 77 | 79 |
|
| 78 | 80 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 131 | 133 |
mScreen.setProjection( fovInDegrees, 0.1f); |
| 132 | 134 |
mView.setScreenSize(width,height); |
| 133 | 135 |
mView.setCameraDist(cameraDistance); |
| 136 |
mScreen.resize(width, height); |
|
| 134 | 137 |
|
| 135 |
mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(width>height ? height:width); |
|
| 136 |
float texSize = mCube.getTextureSize(); |
|
| 137 |
float scaleFactor = mCubeSizeInScreenSpace/(texSize*mCube.getSize()); |
|
| 138 |
|
|
| 139 |
mMove.set( (width-scaleFactor*texSize)/2 , (height-scaleFactor*texSize)/2 , -scaleFactor*texSize/2 ); |
|
| 140 |
mScale.set(scaleFactor,scaleFactor,scaleFactor); |
|
| 138 |
recomputeScaleFactor(width,height); |
|
| 141 | 139 |
|
| 142 |
mScreen.resize(width, height); |
|
| 140 |
mScreenHeight = height; |
|
| 141 |
mScreenWidth = width; |
|
| 143 | 142 |
} |
| 144 | 143 |
|
| 145 | 144 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 164 | 163 |
|
| 165 | 164 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 166 | 165 |
|
| 167 |
private float computeFOV(float cameraDistance, int screenHeight)
|
|
| 168 |
{
|
|
| 169 |
double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
|
|
| 170 |
return (float)(2*halfFOVInRadians*(180/Math.PI));
|
|
| 171 |
}
|
|
| 166 |
private float computeFOV(float cameraDistance, int screenHeight) |
|
| 167 |
{
|
|
| 168 |
double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) ); |
|
| 169 |
return (float)(2*halfFOVInRadians*(180/Math.PI)); |
|
| 170 |
} |
|
| 172 | 171 |
|
| 173 | 172 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 174 | 173 |
// no this will not race with onDrawFrame |
| 175 | 174 |
|
| 176 |
void finishRotation()
|
|
| 177 |
{
|
|
| 178 |
mFinishRotation = true;
|
|
| 179 |
}
|
|
| 175 |
void finishRotation() |
|
| 176 |
{
|
|
| 177 |
mFinishRotation = true; |
|
| 178 |
} |
|
| 180 | 179 |
|
| 181 | 180 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 182 | 181 |
|
| 183 |
float returnCubeSizeInScreenSpace() |
|
| 184 |
{
|
|
| 185 |
return mCubeSizeInScreenSpace; |
|
| 186 |
} |
|
| 182 |
void createCube(int newSize) |
|
| 183 |
{
|
|
| 184 |
int oldSize = mCube==null ? 0 : mCube.getSize(); |
|
| 185 |
|
|
| 186 |
if( oldSize!=newSize ) |
|
| 187 |
{
|
|
| 188 |
mCube = new RubikCube(newSize, mMove, mScale, mQuatCurrent, mQuatAccumulated); |
|
| 189 |
mCube.createTexture(); |
|
| 190 |
|
|
| 191 |
if( mScreenWidth!=0 ) |
|
| 192 |
{
|
|
| 193 |
recomputeScaleFactor(mScreenWidth,mScreenHeight); |
|
| 194 |
} |
|
| 195 |
|
|
| 196 |
mScreen.detachAll(); |
|
| 197 |
mCube.attachToScreen(mScreen); |
|
| 198 |
} |
|
| 199 |
} |
|
| 187 | 200 |
|
| 188 | 201 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 189 | 202 |
|
| 190 |
boolean canRotate() |
|
| 191 |
{
|
|
| 192 |
return mCanRotate; |
|
| 193 |
} |
|
| 203 |
void recomputeScaleFactor(int screenWidth, int screenHeight) |
|
| 204 |
{
|
|
| 205 |
mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth); |
|
| 206 |
float texSize = mCube.getTextureSize(); |
|
| 207 |
float scaleFactor = mCubeSizeInScreenSpace/(texSize*mCube.getSize()); |
|
| 208 |
|
|
| 209 |
mMove.set( (screenWidth-scaleFactor*texSize)/2 , (screenHeight-scaleFactor*texSize)/2 , -scaleFactor*texSize/2 ); |
|
| 210 |
mScale.set(scaleFactor,scaleFactor,scaleFactor); |
|
| 211 |
} |
|
| 194 | 212 |
|
| 195 | 213 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 196 | 214 |
|
| 197 |
RubikCube getCube() |
|
| 198 |
{
|
|
| 199 |
return mCube; |
|
| 200 |
} |
|
| 215 |
void scrambleCube() |
|
| 216 |
{
|
|
| 217 |
|
|
| 218 |
} |
|
| 219 |
|
|
| 220 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 221 |
|
|
| 222 |
float returnCubeSizeInScreenSpace() |
|
| 223 |
{
|
|
| 224 |
return mCubeSizeInScreenSpace; |
|
| 225 |
} |
|
| 226 |
|
|
| 227 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 228 |
|
|
| 229 |
boolean canRotate() |
|
| 230 |
{
|
|
| 231 |
return mCanRotate; |
|
| 232 |
} |
|
| 233 |
|
|
| 234 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 235 |
|
|
| 236 |
RubikCube getCube() |
|
| 237 |
{
|
|
| 238 |
return mCube; |
|
| 239 |
} |
|
| 201 | 240 |
|
| 202 | 241 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 203 | 242 |
// Initial rotation of the cube. Something semi-random that looks good. |
| 204 | 243 |
|
| 205 |
Static4D initializeQuat()
|
|
| 206 |
{
|
|
| 207 |
return new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
|
|
| 208 |
}
|
|
| 244 |
Static4D initializeQuat() |
|
| 245 |
{
|
|
| 246 |
return new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f); |
|
| 247 |
} |
|
| 209 | 248 |
|
| 210 | 249 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 211 | 250 |
|
| 212 |
void setQuatCurrent(Static4D current)
|
|
| 213 |
{
|
|
| 214 |
mTempCurrent.set(current);
|
|
| 215 |
mFinishDragCurrent = true;
|
|
| 216 |
}
|
|
| 251 |
void setQuatCurrent(Static4D current) |
|
| 252 |
{
|
|
| 253 |
mTempCurrent.set(current); |
|
| 254 |
mFinishDragCurrent = true; |
|
| 255 |
} |
|
| 217 | 256 |
|
| 218 | 257 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 219 | 258 |
|
| 220 |
void setQuatAccumulated(Static4D accumulated)
|
|
| 221 |
{
|
|
| 222 |
mTempAccumulated.set(accumulated);
|
|
| 223 |
mFinishDragAccumulated = true;
|
|
| 224 |
}
|
|
| 259 |
void setQuatAccumulated(Static4D accumulated) |
|
| 260 |
{
|
|
| 261 |
mTempAccumulated.set(accumulated); |
|
| 262 |
mFinishDragAccumulated = true; |
|
| 263 |
} |
|
| 225 | 264 |
} |
| src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java | ||
|---|---|---|
| 32 | 32 |
|
| 33 | 33 |
class RubikSurfaceView extends GLSurfaceView |
| 34 | 34 |
{
|
| 35 |
// Moving the finger from the middle of the vertical screen to the right edge will rotate a |
|
| 36 |
// given face by SWIPING_SENSITIVITY/2 degrees. |
|
| 37 |
private final static int SWIPING_SENSITIVITY = 240; |
|
| 38 |
|
|
| 35 | 39 |
private final static int NONE =-1; |
| 36 | 40 |
private final static int FRONT = 0; // has to be 6 consecutive ints |
| 37 | 41 |
private final static int BACK = 1; // FRONT ... BOTTOM |
| ... | ... | |
| 41 | 45 |
private final static int BOTTOM = 5; // |
| 42 | 46 |
|
| 43 | 47 |
static final int VECTX = 0; // |
| 44 |
static final int VECTY = 1; // dont change this |
|
| 48 |
static final int VECTY = 1; // don't change this
|
|
| 45 | 49 |
static final int VECTZ = 2; // |
| 46 | 50 |
|
| 47 | 51 |
private static final int[] VECT = {VECTX,VECTY,VECTZ};
|
| ... | ... | |
| 51 | 55 |
private Static4D mQuatCurrent, mQuatAccumulated; |
| 52 | 56 |
private int mRotationVect; |
| 53 | 57 |
private RubikRenderer mRenderer; |
| 54 |
private RubikCube mCube; |
|
| 55 | 58 |
|
| 56 | 59 |
private float[] mPoint, mCamera, mTouchPointCastOntoFace, mDiff, mTouchPoint; // all in screen space |
| 57 | 60 |
private int mLastTouchedFace; |
| ... | ... | |
| 77 | 80 |
mScreenWidth = mScreenHeight = mScreenMin = 0; |
| 78 | 81 |
|
| 79 | 82 |
mRenderer = new RubikRenderer(this); |
| 80 |
mCube = mRenderer.getCube();
|
|
| 83 |
mRenderer.createCube(RubikActivity.DEFAULT_SIZE);
|
|
| 81 | 84 |
|
| 82 | 85 |
mQuatCurrent = new Static4D(0,0,0,1); |
| 83 | 86 |
mQuatAccumulated = mRenderer.initializeQuat(); |
| ... | ... | |
| 89 | 92 |
} |
| 90 | 93 |
} |
| 91 | 94 |
|
| 92 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 93 |
|
|
| 94 |
public RubikRenderer getRenderer() |
|
| 95 |
{
|
|
| 96 |
return mRenderer; |
|
| 97 |
} |
|
| 98 |
|
|
| 99 | 95 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 100 | 96 |
|
| 101 | 97 |
@Override |
| ... | ... | |
| 168 | 164 |
|
| 169 | 165 |
void setNewCubeSize(int newCubeSize) |
| 170 | 166 |
{
|
| 171 |
android.util.Log.e("view", "new size="+newCubeSize);
|
|
| 167 |
mRenderer.createCube(newCubeSize);
|
|
| 172 | 168 |
} |
| 173 | 169 |
|
| 174 | 170 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 175 | 171 |
|
| 176 | 172 |
void scrambleCube() |
| 177 | 173 |
{
|
| 178 |
android.util.Log.e("view", "scrambling...");
|
|
| 174 |
mRenderer.scrambleCube();
|
|
| 179 | 175 |
} |
| 180 | 176 |
|
| 181 | 177 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 243 | 239 |
mTouchPoint[1] = mPoint[1]; |
| 244 | 240 |
mTouchPoint[2] = mPoint[2]; |
| 245 | 241 |
|
| 246 |
mCube.addNewRotation(mRotationVect,offset);
|
|
| 242 |
mRenderer.getCube().addNewRotation(mRotationVect,offset);
|
|
| 247 | 243 |
} |
| 248 | 244 |
|
| 249 | 245 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 254 | 250 |
} |
| 255 | 251 |
|
| 256 | 252 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 257 |
// 240 --> moving finger from the middle of the vertical screen to the right edge will rotate a |
|
| 258 |
// given face by 240/2 = 120 degrees. |
|
| 259 | 253 |
|
| 260 | 254 |
private void continueRotation(int x, int y) |
| 261 | 255 |
{
|
| ... | ... | |
| 270 | 264 |
int sign = retFaceRotationSign(mLastTouchedFace); |
| 271 | 265 |
float angle = (mRotationVect==xAxis ? mDiff[yAxis] : -mDiff[xAxis]); |
| 272 | 266 |
|
| 273 |
mCube.continueRotation(240.0f*sign*angle/mScreenMin);
|
|
| 267 |
mRenderer.getCube().continueRotation(SWIPING_SENSITIVITY*sign*angle/mScreenMin);
|
|
| 274 | 268 |
} |
| 275 | 269 |
|
| 276 | 270 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Port changes from the 'distorted-cube' target.