Project

General

Profile

« Previous | Next » 

Revision dc8979ba

Added by Leszek Koltunski over 5 years ago

RubikApp: simplifications.

View differences:

src/main/java/org/distorted/examples/rubik/RubikCube.java
66 66
      mSize = size;
67 67

  
68 68
      mRotationAngleStatic = new Static1D(0);
69
      mRotAxis= RubikSurfaceView.VECTN;
69
      mRotAxis= RubikSurfaceView.VECTX;
70 70
      mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
71 71

  
72 72
      mCubes          = new MeshCubes[mSize][mSize][mSize];
src/main/java/org/distorted/examples/rubik/RubikRenderer.java
109 109
      float h = mCube.getHeight();
110 110
      float d = mCube.getDepth();
111 111

  
112
      mScaleFactor = CUBE_SCREEN_RATIO*(width>height ? height/h:width/w)/ NUM_CUBES;
112
      mScaleFactor = CUBE_SCREEN_RATIO*(width>height ? height:width)/mCube.getSizeInModelSpace();
113 113

  
114 114
      mMove.set( (width-mScaleFactor*w)/2 , (height-mScaleFactor*h)/2 , -mScaleFactor*d/2 );
115 115
      mScale.set(mScaleFactor,mScaleFactor,mScaleFactor);
......
147 147

  
148 148
///////////////////////////////////////////////////////////////////////////////////////////////////
149 149

  
150
    float returnCubeSize()
150
    float returnCubeSizeInScreenSpace()
151 151
      {
152 152
      return mScaleFactor*mCube.getSizeInModelSpace();
153 153
      }
src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
39 39
    private final static int TOP    = 4;  //
40 40
    private final static int BOTTOM = 5;  //
41 41

  
42
    static final int VECTX = 0;
43
    static final int VECTY = 1;
44
    static final int VECTZ = 2;
45
    static final int VECTN = 3;
42
    static final int VECTX = 0;  //
43
    static final int VECTY = 1;  // dont change this
44
    static final int VECTZ = 2;  //
45

  
46
    private static final int[] VECT = {VECTX,VECTY,VECTZ};
46 47

  
47 48
    private boolean mDragging, mBeginRot;
48 49
    private int mX, mY;
......
51 52
    private RubikRenderer mRenderer;
52 53
    private RubikCube mCube;
53 54

  
54
    private float mPoiX, mPoiY, mPoiZ, mCamX, mCamY, mCamZ;
55
    private float mStartX, mStartY, mStartZ;
55
    private float[] mPoi, mCam, mTouchedPointCastOntoFace, mDiff; // all in screen space
56 56
    private int mLastTouchedFace;
57 57
    private int mScreenWidth, mScreenHeight, mScreenMin;
58 58
    private float mCameraDistance;
......
65 65

  
66 66
      mDragging = false;
67 67
      mBeginRot = false;
68
      mRotationVect = VECTN;
68
      mRotationVect = VECT[0];
69

  
70
      mPoi   = new float[3];
71
      mCam   = new float[3];
72
      mDiff  = new float[3];
73
      mTouchedPointCastOntoFace = new float[3];
69 74

  
70 75
      mScreenWidth = mScreenHeight = mScreenMin = 0;
71 76

  
......
160 165
      }
161 166

  
162 167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
// mTouchedPointCastOntoFace[x] is the x distance between the x-center of the face and the point
169
// we just touched cast onto the face. The face is touched iff -cH <= mTouchedPointCastOntoFace[0,1,2] <= +cH
163 170

  
164
    private void addNewRotation(int x, int y)
171
    private int faceTouched(int xTouch, int yTouch)
165 172
      {
166
      fillTouchPoint(x,y);
167

  
168
      float cubeHalfSize= mRenderer.returnCubeSize()*0.5f;
169
      float A=retA(mLastTouchedFace,cubeHalfSize);
173
      float cubeHalfSize= mRenderer.returnCubeSizeInScreenSpace()*0.5f;
170 174

  
171
      float diffX = (mPoiX-mCamX)*A + mCamX - mStartX;
172
      float diffY = (mPoiY-mCamY)*A + mCamY - mStartY;
173
      float diffZ = (mPoiZ-mCamZ)*A + mCamZ - mStartZ;
175
      convertTouchPointToScreenSpace(xTouch,yTouch);
176
      convertCameraPointToScreenSpace();
174 177

  
175
      switch(mLastTouchedFace)
178
      for(int face=FRONT; face<=BOTTOM; face++)
176 179
        {
177
        case FRONT :
178
        case BACK  : mRotationVect = (isVertical(diffX, diffY) ? VECTX:VECTY); break;
179
        case LEFT  :
180
        case RIGHT : mRotationVect = (isVertical(diffZ, diffY) ? VECTZ:VECTY); break;
181
        case TOP   :
182
        case BOTTOM: mRotationVect = (isVertical(diffX, diffZ) ? VECTX:VECTZ); break;
183
        }
180
        if( faceIsVisible(face,cubeHalfSize) )
181
          {
182
          castTouchPointOntoFace(face,cubeHalfSize, mTouchedPointCastOntoFace);
184 183

  
185
      float offset=0;
184
          float qX= (mTouchedPointCastOntoFace[0]+cubeHalfSize) / (2*cubeHalfSize);
185
          float qY= (mTouchedPointCastOntoFace[1]+cubeHalfSize) / (2*cubeHalfSize);
186
          float qZ= (mTouchedPointCastOntoFace[2]+cubeHalfSize) / (2*cubeHalfSize);
186 187

  
187
      switch(mRotationVect)
188
        {
189
        case VECTX: offset = (mStartX+cubeHalfSize)/(2*cubeHalfSize); break;
190
        case VECTY: offset = (mStartY+cubeHalfSize)/(2*cubeHalfSize); break;
191
        case VECTZ: offset = (mStartZ+cubeHalfSize)/(2*cubeHalfSize); break;
188
          if( qX<=1 && qX>=0 && qY<=1 && qY>=0 && qZ<=1 && qZ>=0 ) return face;
189
          }
192 190
        }
193 191

  
194
      mStartX = diffX + mStartX;
195
      mStartY = diffY + mStartY;
196
      mStartZ = diffZ + mStartZ;
192
      return NONE;
193
      }
194

  
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

  
197
    private void addNewRotation(int x, int y)
198
      {
199
      float cubeHalfSize= mRenderer.returnCubeSizeInScreenSpace()*0.5f;
200

  
201
      convertTouchPointToScreenSpace(x,y);
202
      castTouchPointOntoFace(mLastTouchedFace,cubeHalfSize,mDiff);
203

  
204
      mDiff[0] -= mTouchedPointCastOntoFace[0];
205
      mDiff[1] -= mTouchedPointCastOntoFace[1];
206
      mDiff[2] -= mTouchedPointCastOntoFace[2];
207

  
208
      int xAxis = retFaceXaxis(mLastTouchedFace);
209
      int yAxis = retFaceYaxis(mLastTouchedFace);
210
      mRotationVect = (isVertical( mDiff[xAxis], mDiff[yAxis]) ? VECT[xAxis]:VECT[yAxis]);
211
      float offset= (mTouchedPointCastOntoFace[mRotationVect]+cubeHalfSize)/(2*cubeHalfSize);
212

  
213
      mTouchedPointCastOntoFace[0] = mDiff[0] + mTouchedPointCastOntoFace[0];
214
      mTouchedPointCastOntoFace[1] = mDiff[1] + mTouchedPointCastOntoFace[1];
215
      mTouchedPointCastOntoFace[2] = mDiff[2] + mTouchedPointCastOntoFace[2];
197 216

  
198 217
      mCube.addNewRotation(mRotationVect,offset);
199 218
      }
......
209 228

  
210 229
    private void continueRotation(int x, int y)
211 230
      {
212
      fillTouchPoint(x,y);
231
      float cubeHalfSize= mRenderer.returnCubeSizeInScreenSpace()*0.5f;
213 232

  
214
      float cubeHalfSize= mRenderer.returnCubeSize()*0.5f;
215
      float A=retA(mLastTouchedFace,cubeHalfSize);
233
      convertTouchPointToScreenSpace(x,y);
234
      castTouchPointOntoFace(mLastTouchedFace,cubeHalfSize,mDiff);
216 235

  
217
      float diffX = (mPoiX-mCamX)*A + mCamX - mStartX;
218
      float diffY = (mPoiY-mCamY)*A + mCamY - mStartY;
219
      float diffZ = (mPoiZ-mCamZ)*A + mCamZ - mStartZ;
236
      mDiff[0] -= mTouchedPointCastOntoFace[0];
237
      mDiff[1] -= mTouchedPointCastOntoFace[1];
238
      mDiff[2] -= mTouchedPointCastOntoFace[2];
220 239

  
221
      float angle=0.0f;
240
      int xAxis= retFaceXaxis(mLastTouchedFace);
241
      int yAxis= retFaceYaxis(mLastTouchedFace);
242
      int sign = retFaceRotationSign(mLastTouchedFace);
222 243

  
223
      switch(mLastTouchedFace)
224
        {
225
        case FRONT : angle = (mRotationVect==VECTX ? -diffY : diffX); break;
226
        case BACK  : angle = (mRotationVect==VECTX ?  diffY :-diffX); break;
227
        case LEFT  : angle = (mRotationVect==VECTY ?  diffZ :-diffY); break;
228
        case RIGHT : angle = (mRotationVect==VECTY ? -diffZ : diffY); break;
229
        case TOP   : angle = (mRotationVect==VECTZ ? -diffX : diffZ); break;
230
        case BOTTOM: angle = (mRotationVect==VECTZ ?  diffX :-diffZ); break;
231
        }
244
      float angle = (mRotationVect==xAxis ? mDiff[yAxis] : -mDiff[xAxis]);
232 245

  
233
      mCube.continueRotation(200.0f*angle/mScreenMin);
246
      mCube.continueRotation(200.0f*sign*angle/mScreenMin);
234 247
      }
235 248

  
236 249
///////////////////////////////////////////////////////////////////////////////////////////////////
237 250

  
238 251
    private void finishRotation()
239 252
      {
240
      mRotationVect = VECTN;
241 253
      mRenderer.finishRotation();
242 254
      }
243 255

  
......
322 334

  
323 335
///////////////////////////////////////////////////////////////////////////////////////////////////
324 336

  
325
    private boolean faceIsVisible(int face)
337
    private boolean faceIsVisible(int face, float cubeHalfSize)
326 338
      {
327
      float cubeHalfSize= mRenderer.returnCubeSize()*0.5f;
339
      int sign = retFaceSign(face);
340
      int zAxis= retFaceZaxis(face);
328 341

  
329
      Static4D rotated = rotateVectorByInvertedQuat(new Static4D(0,0,mCameraDistance,0), mQuatAccumulated);
342
      return sign*mCam[zAxis] > cubeHalfSize;
343
      }
330 344

  
331
      switch(face)
332
        {
333
        case FRONT : return rotated.get3() >  cubeHalfSize;
334
        case BACK  : return rotated.get3() < -cubeHalfSize;
335
        case LEFT  : return rotated.get1() < -cubeHalfSize;
336
        case RIGHT : return rotated.get1() >  cubeHalfSize;
337
        case TOP   : return rotated.get2() >  cubeHalfSize;
338
        case BOTTOM: return rotated.get2() < -cubeHalfSize;
339
        }
345
///////////////////////////////////////////////////////////////////////////////////////////////////
340 346

  
341
      return false;
347
    private void convertTouchPointToScreenSpace(int x, int y)
348
      {
349
      float halfScrWidth  = mScreenWidth *0.5f;
350
      float halfScrHeight = mScreenHeight*0.5f;
351
      Static4D touchPoint = new Static4D(x-halfScrWidth, halfScrHeight-y, 0, 0);
352
      Static4D rotatedTouchPoint= rotateVectorByInvertedQuat(touchPoint, mQuatAccumulated);
353

  
354
      mPoi[0] = rotatedTouchPoint.get1();
355
      mPoi[1] = rotatedTouchPoint.get2();
356
      mPoi[2] = rotatedTouchPoint.get3();
342 357
      }
343 358

  
344 359
///////////////////////////////////////////////////////////////////////////////////////////////////
345 360

  
346
    private int faceTouched(int xTouch, int yTouch)
361
    private void convertCameraPointToScreenSpace()
347 362
      {
348
      float cubeHalfSize= mRenderer.returnCubeSize()*0.5f;
349

  
350
      fillTouchPoint(xTouch,yTouch);
351
      fillCamera();
363
      Static4D cameraPoint = new Static4D(0, 0, mCameraDistance, 0);
364
      Static4D rotatedCamera= rotateVectorByInvertedQuat(cameraPoint, mQuatAccumulated);
352 365

  
353
      for(int face=FRONT; face<=BOTTOM; face++)
354
        {
355
        if( faceIsVisible(face) && faceCondition(face) )
356
          {
357
          float A = retA(face,cubeHalfSize);
366
      mCam[0] = rotatedCamera.get1();
367
      mCam[1] = rotatedCamera.get2();
368
      mCam[2] = rotatedCamera.get3();
369
      }
358 370

  
359
          mStartX = (mPoiX-mCamX)*A + mCamX;
360
          mStartY = (mPoiY-mCamY)*A + mCamY;
361
          mStartZ = (mPoiZ-mCamZ)*A + mCamZ;
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372
// given precomputed mCam and mPoi, respectively camera and touch point positions in ScreenSpace,
373
// cast this touch point onto the 'face' and write the cast coords to 'output'.
374
// Center of the 'face' = (0,0)
362 375

  
363
          float qX= (mStartX+cubeHalfSize) / (2*cubeHalfSize);
364
          float qY= (mStartY+cubeHalfSize) / (2*cubeHalfSize);
365
          float qZ= (mStartZ+cubeHalfSize) / (2*cubeHalfSize);
376
    private void castTouchPointOntoFace(int face, float cubeHalfSize, float[] output)
377
      {
378
      int sign = retFaceSign(face);
379
      int zAxis= retFaceZaxis(face);
380
      float diff = mPoi[zAxis]-mCam[zAxis];
366 381

  
367
          if( qX<=1 && qX>=0 && qY<=1 && qY>=0 && qZ<=1 && qZ>=0 ) return face;
368
          }
369
        }
382
      float ratio =  diff!=0.0f ? (sign*cubeHalfSize-mCam[zAxis])/diff : 0.0f;
370 383

  
371
      return NONE;
384
      output[0] = (mPoi[0]-mCam[0])*ratio + mCam[0];
385
      output[1] = (mPoi[1]-mCam[1])*ratio + mCam[1];
386
      output[2] = (mPoi[2]-mCam[2])*ratio + mCam[2];
372 387
      }
373 388

  
374 389
///////////////////////////////////////////////////////////////////////////////////////////////////
375 390

  
376
    private void fillTouchPoint(int x, int y)
391
    private int retFaceSign(int face)
377 392
      {
378
      float halfScrWidth  = mScreenWidth *0.5f;
379
      float halfScrHeight = mScreenHeight*0.5f;
380
      Static4D touchPoint = new Static4D(x-halfScrWidth, halfScrHeight-y, 0, 0);
381
      Static4D rotatedTouchPoint= rotateVectorByInvertedQuat(touchPoint, mQuatAccumulated);
393
      return (face==FRONT || face==RIGHT || face==TOP) ? 1:-1;
394
      }
395

  
396
///////////////////////////////////////////////////////////////////////////////////////////////////
382 397

  
383
      mPoiX = rotatedTouchPoint.get1();
384
      mPoiY = rotatedTouchPoint.get2();
385
      mPoiZ = rotatedTouchPoint.get3();
398
    private int retFaceRotationSign(int face)
399
      {
400
      return (face==BACK || face==RIGHT || face==TOP) ? 1:-1;
386 401
      }
387 402

  
388 403
///////////////////////////////////////////////////////////////////////////////////////////////////
389 404

  
390
    private void fillCamera()
405
    private int retFaceXaxis(int face)
391 406
      {
392
      Static4D cameraPoint = new Static4D(0, 0, mCameraDistance, 0);
393
      Static4D rotatedCamera= rotateVectorByInvertedQuat(cameraPoint, mQuatAccumulated);
407
      switch(face)
408
        {
409
        case FRONT :
410
        case BACK  : return VECTX;
411
        case LEFT  :
412
        case RIGHT : return VECTZ;
413
        case TOP   :
414
        case BOTTOM: return VECTX;
415
        }
394 416

  
395
      mCamX = rotatedCamera.get1();
396
      mCamY = rotatedCamera.get2();
397
      mCamZ = rotatedCamera.get3();
417
      return -1;
398 418
      }
399 419

  
400 420
///////////////////////////////////////////////////////////////////////////////////////////////////
401 421

  
402
    private float retA(int face, float cubeHalfSize)
422
    private int retFaceYaxis(int face)
403 423
      {
404 424
      switch(face)
405 425
        {
406
        case FRONT : return ( mPoiZ!=mCamZ ? ( cubeHalfSize-mCamZ)/(mPoiZ-mCamZ) : 0f);
407
        case BACK  : return ( mPoiZ!=mCamZ ? (-cubeHalfSize-mCamZ)/(mPoiZ-mCamZ) : 0f);
408
        case LEFT  : return ( mPoiX!=mCamX ? (-cubeHalfSize-mCamX)/(mPoiX-mCamX) : 0f);
409
        case RIGHT : return ( mPoiX!=mCamX ? ( cubeHalfSize-mCamX)/(mPoiX-mCamX) : 0f);
410
        case TOP   : return ( mPoiY!=mCamY ? ( cubeHalfSize-mCamY)/(mPoiY-mCamY) : 0f);
411
        case BOTTOM: return ( mPoiY!=mCamY ? (-cubeHalfSize-mCamY)/(mPoiY-mCamY) : 0f);
426
        case FRONT :
427
        case BACK  : return VECTY;
428
        case LEFT  :
429
        case RIGHT : return VECTY;
430
        case TOP   :
431
        case BOTTOM: return VECTZ;
412 432
        }
413 433

  
414
      return 0.0f;
434
      return -1;
415 435
      }
416 436

  
417 437
///////////////////////////////////////////////////////////////////////////////////////////////////
418 438

  
419
    private boolean faceCondition(int face)
439
    private int retFaceZaxis(int face)
420 440
      {
421 441
      switch(face)
422 442
        {
423 443
        case FRONT :
424
        case BACK  : return ( mPoiZ!=mCamZ );
444
        case BACK  : return VECTZ;
425 445
        case LEFT  :
426
        case RIGHT : return ( mPoiX!=mCamX );
446
        case RIGHT : return VECTX;
427 447
        case TOP   :
428
        case BOTTOM: return ( mPoiY!=mCamY );
448
        case BOTTOM: return VECTY;
429 449
        }
430 450

  
431
      return false;
451
      return -1;
432 452
      }
433 453
}
434 454

  

Also available in: Unified diff