Revision 0b7e1b05
Added by Leszek Koltunski over 4 years ago
src/main/java/org/distorted/main/RubikSurfaceView.java | ||
---|---|---|
42 | 42 |
public class RubikSurfaceView extends GLSurfaceView |
43 | 43 |
{ |
44 | 44 |
private static final int NUM_SPEED_PROBES = 10; |
45 |
private static final int INVALID_POINTER_ID = -1; |
|
46 | 45 |
|
47 | 46 |
public static final int MODE_ROTATE = 0; |
48 | 47 |
public static final int MODE_DRAG = 1; |
... | ... | |
73 | 72 |
private boolean mDragging, mBeginningRotation, mContinuingRotation; |
74 | 73 |
private int mScreenWidth, mScreenHeight, mScreenMin; |
75 | 74 |
|
76 |
private int mPtrID1, mPtrID2;
|
|
77 |
private float mX, mY, mBegX1, mBegY1, mBegX2, mBegY2;
|
|
75 |
private int mNumFingersDown;
|
|
76 |
private float mX, mY; |
|
78 | 77 |
private float mStartRotX, mStartRotY; |
79 | 78 |
private float mAxisX, mAxisY; |
80 | 79 |
private float mRotationFactor; |
... | ... | |
211 | 210 |
mAxisY /= len; |
212 | 211 |
} |
213 | 212 |
|
214 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
215 |
|
|
216 |
private float continueRotation(float dx, float dy) |
|
217 |
{ |
|
218 |
float alpha = dx*mAxisX + dy*mAxisY; |
|
219 |
float x = dx - alpha*mAxisX; |
|
220 |
float y = dy - alpha*mAxisY; |
|
221 |
|
|
222 |
float len = (float)Math.sqrt(x*x + y*y); |
|
223 |
|
|
224 |
// we have the length of 1D vector 'angle', now the direction: |
|
225 |
float tmp = mAxisY==0 ? -mAxisX*y : mAxisY*x; |
|
226 |
|
|
227 |
return (tmp>0 ? 1:-1)*len*mRotationFactor; |
|
228 |
} |
|
229 |
|
|
230 | 213 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
231 | 214 |
// return quat1*quat2 |
232 | 215 |
|
... | ... | |
395 | 378 |
|
396 | 379 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
397 | 380 |
|
398 |
private void dragging(float x, float y)
|
|
381 |
private void drag(float x, float y) |
|
399 | 382 |
{ |
400 |
mTempCurrent.set(quatFromDrag(mX-x,y-mY)); |
|
401 |
mPreRender.setQuatCurrentOnNextRender(); |
|
402 |
|
|
403 | 383 |
if( retFingerDragDistanceInInches(mX,mY,x,y) > DIRECTION_SENSITIVITY ) |
404 | 384 |
{ |
405 | 385 |
mX = x; |
... | ... | |
409 | 389 |
mPreRender.setQuatCurrentOnNextRender(); |
410 | 390 |
mPreRender.setQuatAccumulatedOnNextRender(); |
411 | 391 |
} |
392 |
|
|
393 |
mTempCurrent.set(quatFromDrag(mX-x,y-mY)); |
|
394 |
mPreRender.setQuatCurrentOnNextRender(); |
|
395 |
} |
|
396 |
|
|
397 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
398 |
|
|
399 |
private void finishRotation() |
|
400 |
{ |
|
401 |
computeCurrentSpeedInInchesPerSecond(); |
|
402 |
int angle = mPreRender.getObject().computeNearestAngle(mCurrentAngle, mCurrRotSpeed); |
|
403 |
mPreRender.finishRotation(angle); |
|
404 |
|
|
405 |
if( RubikState.getCurrentState()==RubikState.SOLV && angle!=0 ) |
|
406 |
{ |
|
407 |
RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass(); |
|
408 |
solving.addMove(mCurrentAxis, mCurrentRow, angle); |
|
409 |
} |
|
410 |
|
|
411 |
mContinuingRotation = false; |
|
412 |
mBeginningRotation = false; |
|
413 |
mDragging = true; |
|
412 | 414 |
} |
413 | 415 |
|
414 | 416 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
415 | 417 |
|
416 |
private void continuingRotation(float x, float y)
|
|
418 |
private void continueRotation(float x, float y)
|
|
417 | 419 |
{ |
418 |
float angle = continueRotation(x-mStartRotX,y-mStartRotY); |
|
420 |
float dx = x-mStartRotX; |
|
421 |
float dy = y-mStartRotY; |
|
422 |
float alpha = dx*mAxisX + dy*mAxisY; |
|
423 |
float x2 = dx - alpha*mAxisX; |
|
424 |
float y2 = dy - alpha*mAxisY; |
|
425 |
|
|
426 |
float len = (float)Math.sqrt(x2*x2 + y2*y2); |
|
427 |
|
|
428 |
// we have the length of 1D vector 'angle', now the direction: |
|
429 |
float tmp = mAxisY==0 ? -mAxisX*y2 : mAxisY*x2; |
|
430 |
|
|
431 |
float angle = (tmp>0 ? 1:-1)*len*mRotationFactor; |
|
419 | 432 |
mCurrentAngle = SWIPING_SENSITIVITY*angle; |
420 | 433 |
mPreRender.getObject().continueRotation(mCurrentAngle); |
421 | 434 |
|
422 |
addSpeedProbe(x,y);
|
|
435 |
addSpeedProbe(x2,y2);
|
|
423 | 436 |
} |
424 | 437 |
|
425 | 438 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
426 | 439 |
|
427 |
private void beginningRotation(float x, float y)
|
|
440 |
private void beginRotation(float x, float y) |
|
428 | 441 |
{ |
429 | 442 |
mStartRotX = x; |
430 | 443 |
mStartRotY = y; |
... | ... | |
470 | 483 |
|
471 | 484 |
private void actionMove(MotionEvent event) |
472 | 485 |
{ |
473 |
if( mPtrID2 == INVALID_POINTER_ID ) |
|
474 |
{ |
|
475 |
float x = (event.getX() - mScreenWidth*0.5f)/mScreenMin; |
|
476 |
float y = (mScreenHeight*0.5f -event.getY())/mScreenMin; |
|
486 |
float x = (event.getX() - mScreenWidth*0.5f)/mScreenMin; |
|
487 |
float y = (mScreenHeight*0.5f -event.getY())/mScreenMin; |
|
477 | 488 |
|
478 |
if( mBeginningRotation ) |
|
479 |
{ |
|
480 |
if( retFingerDragDistanceInInches(mX,mY,x,y) > ROTATION_SENSITIVITY ) |
|
481 |
{ |
|
482 |
beginningRotation(x,y); |
|
483 |
} |
|
484 |
} |
|
485 |
else if( mContinuingRotation ) |
|
486 |
{ |
|
487 |
continuingRotation(x,y); |
|
488 |
} |
|
489 |
else if( mDragging ) |
|
490 |
{ |
|
491 |
dragging(x,y); |
|
492 |
} |
|
493 |
else |
|
489 |
|
|
490 |
//android.util.Log.e("view", "num fingers: "+mNumFingersDown+" x="+event.getX()+" y="+event.getY()); |
|
491 |
|
|
492 |
|
|
493 |
if( mBeginningRotation ) |
|
494 |
{ |
|
495 |
if( retFingerDragDistanceInInches(mX,mY,x,y) > ROTATION_SENSITIVITY ) |
|
494 | 496 |
{ |
495 |
setUpDragOrRotate(false,x,y);
|
|
497 |
beginRotation(x,y);
|
|
496 | 498 |
} |
497 | 499 |
} |
500 |
else if( mContinuingRotation ) |
|
501 |
{ |
|
502 |
continueRotation(x,y); |
|
503 |
} |
|
504 |
else if( mDragging ) |
|
505 |
{ |
|
506 |
drag(x,y); |
|
507 |
} |
|
498 | 508 |
else |
499 | 509 |
{ |
500 |
int index1 = event.findPointerIndex(mPtrID1); |
|
501 |
int index2 = event.findPointerIndex(mPtrID2); |
|
502 |
|
|
503 |
float nX1 = event.getX(index1); |
|
504 |
float nY1 = event.getY(index1); |
|
505 |
float nX2 = event.getX(index2); |
|
506 |
float nY2 = event.getY(index2); |
|
507 |
|
|
508 |
float angle1 = (float) Math.atan2(mBegY1-mBegY2, mBegX1-mBegX2); |
|
509 |
float angle2 = (float) Math.atan2( nY1-nY2 , nX1-nX2 ); |
|
510 |
|
|
511 |
mTempCurrent.set(quatFromAngle(angle1-angle2)); |
|
512 |
mPreRender.setQuatCurrentOnNextRender(); |
|
510 |
setUpDragOrRotate(false,x,y); |
|
513 | 511 |
} |
514 | 512 |
} |
515 | 513 |
|
... | ... | |
517 | 515 |
|
518 | 516 |
private void actionDown(MotionEvent event) |
519 | 517 |
{ |
520 |
mPtrID1 = event.getPointerId(0); |
|
518 |
mNumFingersDown++; |
|
519 |
|
|
520 |
//android.util.Log.e("view", "down1 num fingers: "+mNumFingersDown+" x="+event.getX()+" y="+event.getY()); |
|
521 | 521 |
|
522 | 522 |
mX = (event.getX() - mScreenWidth*0.5f)/mScreenMin; |
523 | 523 |
mY = (mScreenHeight*0.5f -event.getY())/mScreenMin; |
... | ... | |
527 | 527 |
|
528 | 528 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
529 | 529 |
|
530 |
private void actionUp() |
|
530 |
private void actionUp(MotionEvent event)
|
|
531 | 531 |
{ |
532 |
mPtrID1 = INVALID_POINTER_ID; |
|
532 |
mNumFingersDown--; |
|
533 |
|
|
534 |
//android.util.Log.e("view", "up1 num fingers: "+mNumFingersDown+" x="+event.getX()+" y="+event.getY()); |
|
533 | 535 |
|
534 | 536 |
if( mDragging ) |
535 | 537 |
{ |
... | ... | |
541 | 543 |
|
542 | 544 |
if( mContinuingRotation ) |
543 | 545 |
{ |
544 |
computeCurrentSpeedInInchesPerSecond(); |
|
545 |
int angle = mPreRender.getObject().computeNearestAngle(mCurrentAngle, mCurrRotSpeed); |
|
546 |
mPreRender.finishRotation(angle); |
|
547 |
|
|
548 |
if( RubikState.getCurrentState()==RubikState.SOLV && angle!=0 ) |
|
549 |
{ |
|
550 |
RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass(); |
|
551 |
solving.addMove(mCurrentAxis, mCurrentRow, angle); |
|
552 |
} |
|
546 |
finishRotation(); |
|
553 | 547 |
} |
554 | 548 |
|
555 | 549 |
if( mLastCubitColor>=0 ) |
... | ... | |
562 | 556 |
|
563 | 557 |
private void actionDown2(MotionEvent event) |
564 | 558 |
{ |
565 |
mPtrID2 = event.getPointerId(event.getActionIndex()); |
|
566 |
|
|
567 |
int index1 = event.findPointerIndex(mPtrID1); |
|
568 |
mBegX1 = event.getX(index1); |
|
569 |
mBegY1 = event.getY(index1); |
|
559 |
mNumFingersDown++; |
|
570 | 560 |
|
571 |
mX = (mBegX1 - mScreenWidth*0.5f)/mScreenMin; |
|
572 |
mY = (mScreenHeight*0.5f -mBegY1)/mScreenMin; |
|
561 |
if( mBeginningRotation ) |
|
562 |
{ |
|
563 |
mContinuingRotation = false; |
|
564 |
mBeginningRotation = false; |
|
565 |
mDragging = true; |
|
566 |
} |
|
567 |
else if( mContinuingRotation ) |
|
568 |
{ |
|
569 |
finishRotation(); |
|
570 |
} |
|
573 | 571 |
|
574 |
int index2 = event.findPointerIndex(mPtrID2); |
|
575 |
mBegX2 = event.getX(index2); |
|
576 |
mBegY2 = event.getY(index2); |
|
572 |
//android.util.Log.e("view", "down2 num fingers: "+mNumFingersDown+" x="+event.getX()+" y="+event.getY()); |
|
577 | 573 |
} |
578 | 574 |
|
579 | 575 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
580 | 576 |
|
581 |
private void actionUp2() |
|
577 |
private void actionUp2(MotionEvent event)
|
|
582 | 578 |
{ |
583 |
mPtrID2 = INVALID_POINTER_ID; |
|
579 |
mNumFingersDown--; |
|
580 |
|
|
581 |
//android.util.Log.e("view", "up2 num fingers: "+mNumFingersDown+" x="+event.getX()+" y="+event.getY()); |
|
584 | 582 |
} |
585 | 583 |
|
586 | 584 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
602 | 600 |
mFirstIndex =0; |
603 | 601 |
mLastIndex =0; |
604 | 602 |
|
605 |
mPtrID1 = INVALID_POINTER_ID; |
|
606 |
mPtrID2 = INVALID_POINTER_ID; |
|
603 |
mNumFingersDown = 0; |
|
607 | 604 |
|
608 | 605 |
mRenderer = new RubikRenderer(this); |
609 | 606 |
mPreRender = new RubikPreRender(this); |
... | ... | |
636 | 633 |
{ |
637 | 634 |
case MotionEvent.ACTION_DOWN : actionDown(event) ; break; |
638 | 635 |
case MotionEvent.ACTION_MOVE : actionMove(event) ; break; |
639 |
case MotionEvent.ACTION_UP : actionUp() ; break;
|
|
636 |
case MotionEvent.ACTION_UP : actionUp(event) ; break;
|
|
640 | 637 |
case MotionEvent.ACTION_POINTER_DOWN: actionDown2(event); break; |
641 |
case MotionEvent.ACTION_POINTER_UP : actionUp2() ; break;
|
|
638 |
case MotionEvent.ACTION_POINTER_UP : actionUp2(event) ; break;
|
|
642 | 639 |
} |
643 | 640 |
|
644 | 641 |
return true; |
Also available in: Unified diff
Progress with improvements for cube manipulation.