| 52 | 52 |     private RubikRenderer mRenderer;
 | 
  | 53 | 53 |     private RubikCube mCube;
 | 
  | 54 | 54 | 
 | 
  | 55 |  |     private float[] mPoi, mCam, mTouchedPointCastOntoFace, mDiff; // all in screen space
 | 
  |  | 55 |     private float[] mPoint, mCamera, mTouchPointCastOntoFace, mDiff, mTouchPoint; // all in screen space
 | 
  | 56 | 56 |     private int mLastTouchedFace;
 | 
  | 57 | 57 |     private int mScreenWidth, mScreenHeight, mScreenMin;
 | 
  | 58 | 58 |     private float mCameraDistance;
 | 
  | ... | ... |  | 
  | 67 | 67 |       mBeginRot = false;
 | 
  | 68 | 68 |       mRotationVect = VECT[0];
 | 
  | 69 | 69 | 
 | 
  | 70 |  |       mPoi   = new float[3];
 | 
  | 71 |  |       mCam   = new float[3];
 | 
  |  | 70 |       mPoint = new float[3];
 | 
  |  | 71 |       mCamera= new float[3];
 | 
  | 72 | 72 |       mDiff  = new float[3];
 | 
  | 73 |  |       mTouchedPointCastOntoFace = new float[3];
 | 
  |  | 73 |       mTouchPoint = new float[3];
 | 
  |  | 74 |       mTouchPointCastOntoFace = new float[3];
 | 
  | 74 | 75 | 
 | 
  | 75 | 76 |       mScreenWidth = mScreenHeight = mScreenMin = 0;
 | 
  | 76 | 77 | 
 | 
  | ... | ... |  | 
  | 165 | 166 |       }
 | 
  | 166 | 167 | 
 | 
  | 167 | 168 | ///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
  | 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
 | 
  | 170 | 169 | 
 | 
  | 171 | 170 |     private int faceTouched(int xTouch, int yTouch)
 | 
  | 172 | 171 |       {
 | 
  | ... | ... |  | 
  | 179 | 178 |         {
 | 
  | 180 | 179 |         if( faceIsVisible(face,cubeHalfSize) )
 | 
  | 181 | 180 |           {
 | 
  | 182 |  |           castTouchPointOntoFace(face,cubeHalfSize, mTouchedPointCastOntoFace);
 | 
  |  | 181 |           castTouchPointOntoFace(face,cubeHalfSize, mTouchPointCastOntoFace);
 | 
  | 183 | 182 | 
 | 
  | 184 |  |           float qX= (mTouchedPointCastOntoFace[0]+cubeHalfSize) / (2*cubeHalfSize);
 | 
  | 185 |  |           float qY= (mTouchedPointCastOntoFace[1]+cubeHalfSize) / (2*cubeHalfSize);
 | 
  | 186 |  |           float qZ= (mTouchedPointCastOntoFace[2]+cubeHalfSize) / (2*cubeHalfSize);
 | 
  |  | 183 |           float qX= (mTouchPointCastOntoFace[0]+cubeHalfSize) / (2*cubeHalfSize);
 | 
  |  | 184 |           float qY= (mTouchPointCastOntoFace[1]+cubeHalfSize) / (2*cubeHalfSize);
 | 
  |  | 185 |           float qZ= (mTouchPointCastOntoFace[2]+cubeHalfSize) / (2*cubeHalfSize);
 | 
  | 187 | 186 | 
 | 
  | 188 | 187 |           if( qX<=1 && qX>=0 && qY<=1 && qY>=0 && qZ<=1 && qZ>=0 ) return face;
 | 
  | 189 | 188 |           }
 | 
  | ... | ... |  | 
  | 201 | 200 |       convertTouchPointToScreenSpace(x,y);
 | 
  | 202 | 201 |       castTouchPointOntoFace(mLastTouchedFace,cubeHalfSize,mDiff);
 | 
  | 203 | 202 | 
 | 
  | 204 |  |       mDiff[0] -= mTouchedPointCastOntoFace[0];
 | 
  | 205 |  |       mDiff[1] -= mTouchedPointCastOntoFace[1];
 | 
  | 206 |  |       mDiff[2] -= mTouchedPointCastOntoFace[2];
 | 
  |  | 203 |       mDiff[0] -= mTouchPointCastOntoFace[0];
 | 
  |  | 204 |       mDiff[1] -= mTouchPointCastOntoFace[1];
 | 
  |  | 205 |       mDiff[2] -= mTouchPointCastOntoFace[2];
 | 
  | 207 | 206 | 
 | 
  | 208 | 207 |       int xAxis = retFaceXaxis(mLastTouchedFace);
 | 
  | 209 | 208 |       int yAxis = retFaceYaxis(mLastTouchedFace);
 | 
  | 210 | 209 |       mRotationVect = (isVertical( mDiff[xAxis], mDiff[yAxis]) ? VECT[xAxis]:VECT[yAxis]);
 | 
  | 211 |  |       float offset= (mTouchedPointCastOntoFace[mRotationVect]+cubeHalfSize)/(2*cubeHalfSize);
 | 
  |  | 210 |       float offset= (mTouchPointCastOntoFace[mRotationVect]+cubeHalfSize)/(2*cubeHalfSize);
 | 
  | 212 | 211 | 
 | 
  | 213 |  |       mTouchedPointCastOntoFace[0] = mDiff[0] + mTouchedPointCastOntoFace[0];
 | 
  | 214 |  |       mTouchedPointCastOntoFace[1] = mDiff[1] + mTouchedPointCastOntoFace[1];
 | 
  | 215 |  |       mTouchedPointCastOntoFace[2] = mDiff[2] + mTouchedPointCastOntoFace[2];
 | 
  |  | 212 |       mTouchPoint[0] = mPoint[0];
 | 
  |  | 213 |       mTouchPoint[1] = mPoint[1];
 | 
  |  | 214 |       mTouchPoint[2] = mPoint[2];
 | 
  | 216 | 215 | 
 | 
  | 217 | 216 |       mCube.addNewRotation(mRotationVect,offset);
 | 
  | 218 | 217 |       }
 | 
  | ... | ... |  | 
  | 228 | 227 | 
 | 
  | 229 | 228 |     private void continueRotation(int x, int y)
 | 
  | 230 | 229 |       {
 | 
  | 231 |  |       float cubeHalfSize= mRenderer.returnCubeSizeInScreenSpace()*0.5f;
 | 
  | 232 |  | 
 | 
  | 233 | 230 |       convertTouchPointToScreenSpace(x,y);
 | 
  | 234 |  |       castTouchPointOntoFace(mLastTouchedFace,cubeHalfSize,mDiff);
 | 
  | 235 | 231 | 
 | 
  | 236 |  |       mDiff[0] -= mTouchedPointCastOntoFace[0];
 | 
  | 237 |  |       mDiff[1] -= mTouchedPointCastOntoFace[1];
 | 
  | 238 |  |       mDiff[2] -= mTouchedPointCastOntoFace[2];
 | 
  |  | 232 |       mDiff[0] = mPoint[0]-mTouchPoint[0];
 | 
  |  | 233 |       mDiff[1] = mPoint[1]-mTouchPoint[1];
 | 
  |  | 234 |       mDiff[2] = mPoint[2]-mTouchPoint[2];
 | 
  | 239 | 235 | 
 | 
  | 240 | 236 |       int xAxis= retFaceXaxis(mLastTouchedFace);
 | 
  | 241 | 237 |       int yAxis= retFaceYaxis(mLastTouchedFace);
 | 
  | 242 | 238 |       int sign = retFaceRotationSign(mLastTouchedFace);
 | 
  | 243 |  | 
 | 
  | 244 | 239 |       float angle = (mRotationVect==xAxis ? mDiff[yAxis] : -mDiff[xAxis]);
 | 
  | 245 | 240 | 
 | 
  | 246 | 241 |       mCube.continueRotation(200.0f*sign*angle/mScreenMin);
 | 
  | ... | ... |  | 
  | 339 | 334 |       int sign = retFaceSign(face);
 | 
  | 340 | 335 |       int zAxis= retFaceZaxis(face);
 | 
  | 341 | 336 | 
 | 
  | 342 |  |       return sign*mCam[zAxis] > cubeHalfSize;
 | 
  |  | 337 |       return sign*mCamera[zAxis] > cubeHalfSize;
 | 
  | 343 | 338 |       }
 | 
  | 344 | 339 | 
 | 
  | 345 | 340 | ///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
  | ... | ... |  | 
  | 351 | 346 |       Static4D touchPoint = new Static4D(x-halfScrWidth, halfScrHeight-y, 0, 0);
 | 
  | 352 | 347 |       Static4D rotatedTouchPoint= rotateVectorByInvertedQuat(touchPoint, mQuatAccumulated);
 | 
  | 353 | 348 | 
 | 
  | 354 |  |       mPoi[0] = rotatedTouchPoint.get1();
 | 
  | 355 |  |       mPoi[1] = rotatedTouchPoint.get2();
 | 
  | 356 |  |       mPoi[2] = rotatedTouchPoint.get3();
 | 
  |  | 349 |       mPoint[0] = rotatedTouchPoint.get1();
 | 
  |  | 350 |       mPoint[1] = rotatedTouchPoint.get2();
 | 
  |  | 351 |       mPoint[2] = rotatedTouchPoint.get3();
 | 
  | 357 | 352 |       }
 | 
  | 358 | 353 | 
 | 
  | 359 | 354 | ///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
  | ... | ... |  | 
  | 363 | 358 |       Static4D cameraPoint = new Static4D(0, 0, mCameraDistance, 0);
 | 
  | 364 | 359 |       Static4D rotatedCamera= rotateVectorByInvertedQuat(cameraPoint, mQuatAccumulated);
 | 
  | 365 | 360 | 
 | 
  | 366 |  |       mCam[0] = rotatedCamera.get1();
 | 
  | 367 |  |       mCam[1] = rotatedCamera.get2();
 | 
  | 368 |  |       mCam[2] = rotatedCamera.get3();
 | 
  |  | 361 |       mCamera[0] = rotatedCamera.get1();
 | 
  |  | 362 |       mCamera[1] = rotatedCamera.get2();
 | 
  |  | 363 |       mCamera[2] = rotatedCamera.get3();
 | 
  | 369 | 364 |       }
 | 
  | 370 | 365 | 
 | 
  | 371 | 366 | ///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
  | ... | ... |  | 
  | 377 | 372 |       {
 | 
  | 378 | 373 |       int sign = retFaceSign(face);
 | 
  | 379 | 374 |       int zAxis= retFaceZaxis(face);
 | 
  | 380 |  |       float diff = mPoi[zAxis]-mCam[zAxis];
 | 
  |  | 375 |       float diff = mPoint[zAxis]-mCamera[zAxis];
 | 
  | 381 | 376 | 
 | 
  | 382 |  |       float ratio =  diff!=0.0f ? (sign*cubeHalfSize-mCam[zAxis])/diff : 0.0f;
 | 
  |  | 377 |       float ratio =  diff!=0.0f ? (sign*cubeHalfSize-mCamera[zAxis])/diff : 0.0f;
 | 
  | 383 | 378 | 
 | 
  | 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];
 | 
  |  | 379 |       output[0] = (mPoint[0]-mCamera[0])*ratio + mCamera[0];
 | 
  |  | 380 |       output[1] = (mPoint[1]-mCamera[1])*ratio + mCamera[1];
 | 
  |  | 381 |       output[2] = (mPoint[2]-mCamera[2])*ratio + mCamera[2];
 | 
  | 387 | 382 |       }
 | 
  | 388 | 383 | 
 | 
  | 389 | 384 | ///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
 
RubikApp: make the rotations smooth.