Revision f0533889
Added by Leszek Koltunski over 4 years ago
src/main/java/org/distorted/main/RubikSurfaceView.java | ||
---|---|---|
180 | 180 |
return new Static4D(0f, 0f, 0f, 1f); |
181 | 181 |
} |
182 | 182 |
|
183 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
184 |
|
|
185 |
private void setUpDragOrRotate(boolean down, float x, float y) |
|
186 |
{ |
|
187 |
int mode = RubikState.getMode(); |
|
188 |
|
|
189 |
if( mode==MODE_DRAG ) |
|
190 |
{ |
|
191 |
mDragging = true; |
|
192 |
mBeginningRotation = false; |
|
193 |
mContinuingRotation = false; |
|
194 |
} |
|
195 |
else |
|
196 |
{ |
|
197 |
Static4D touchPoint1 = new Static4D(x, y, 0, 0); |
|
198 |
Static4D rotatedTouchPoint1= rotateVectorByInvertedQuat(touchPoint1, mQuatAccumulated); |
|
199 |
Static4D rotatedCamera= rotateVectorByInvertedQuat(CAMERA_POINT, mQuatAccumulated); |
|
200 |
|
|
201 |
if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint1,rotatedCamera) ) |
|
202 |
{ |
|
203 |
mDragging = false; |
|
204 |
mContinuingRotation = false; |
|
205 |
|
|
206 |
if( mode==MODE_ROTATE ) |
|
207 |
{ |
|
208 |
mBeginningRotation= mPreRender.canRotate(); |
|
209 |
} |
|
210 |
else if( mode==MODE_REPLACE ) |
|
211 |
{ |
|
212 |
mBeginningRotation= false; |
|
213 |
|
|
214 |
if( down ) |
|
215 |
{ |
|
216 |
RubikStateSolver solver = (RubikStateSolver) RubikState.SVER.getStateClass(); |
|
217 |
mLastCubitFace = mMovement.getTouchedFace(); |
|
218 |
float[] point = mMovement.getTouchedPoint3D(); |
|
219 |
int color = solver.getCurrentColor(); |
|
220 |
RubikObject object = mPreRender.getObject(); |
|
221 |
mLastCubit = object.getCubit(point); |
|
222 |
mPreRender.setTextureMap( mLastCubit, mLastCubitFace, color ); |
|
223 |
mLastCubitColor = SolverMain.cubitIsLocked(object.getObjectList(), object.getSize(), mLastCubit); |
|
224 |
} |
|
225 |
} |
|
226 |
} |
|
227 |
else |
|
228 |
{ |
|
229 |
mDragging = true; |
|
230 |
mBeginningRotation = false; |
|
231 |
mContinuingRotation = false; |
|
232 |
} |
|
233 |
} |
|
234 |
} |
|
235 |
|
|
236 | 183 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
237 | 184 |
// cast the 3D axis we are currently rotating along to the 2D in-screen-surface axis |
238 | 185 |
|
... | ... | |
363 | 310 |
mCurrRotSpeed = timeDiff>0 ? (lastAngle-firstAngle)/timeDiff : 0; |
364 | 311 |
} |
365 | 312 |
|
313 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
314 |
|
|
315 |
private boolean canBeginRotate(float x, float y) |
|
316 |
{ |
|
317 |
return (mX-x)*(mX-x) + (mY-y)*(mY-y) > 1.0f/(ROTATION_SENSITIVITY*ROTATION_SENSITIVITY); |
|
318 |
} |
|
319 |
|
|
320 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
321 |
|
|
322 |
private boolean shouldChangeDirection(float x, float y) |
|
323 |
{ |
|
324 |
return (mX-x)*(mX-x) + (mY-y)*(mY-y) > 1.0f/(DIRECTION_SENSITIVITY*DIRECTION_SENSITIVITY); |
|
325 |
} |
|
326 |
|
|
327 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
328 |
|
|
329 |
private void setUpDragOrRotate(boolean down, float x, float y) |
|
330 |
{ |
|
331 |
int mode = RubikState.getMode(); |
|
332 |
|
|
333 |
if( mode==MODE_DRAG ) |
|
334 |
{ |
|
335 |
mDragging = true; |
|
336 |
mBeginningRotation = false; |
|
337 |
mContinuingRotation = false; |
|
338 |
} |
|
339 |
else |
|
340 |
{ |
|
341 |
Static4D touchPoint1 = new Static4D(x, y, 0, 0); |
|
342 |
Static4D rotatedTouchPoint1= rotateVectorByInvertedQuat(touchPoint1, mQuatAccumulated); |
|
343 |
Static4D rotatedCamera= rotateVectorByInvertedQuat(CAMERA_POINT, mQuatAccumulated); |
|
344 |
|
|
345 |
if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint1,rotatedCamera) ) |
|
346 |
{ |
|
347 |
mDragging = false; |
|
348 |
mContinuingRotation = false; |
|
349 |
|
|
350 |
if( mode==MODE_ROTATE ) |
|
351 |
{ |
|
352 |
mBeginningRotation= mPreRender.canRotate(); |
|
353 |
} |
|
354 |
else if( mode==MODE_REPLACE ) |
|
355 |
{ |
|
356 |
mBeginningRotation= false; |
|
357 |
|
|
358 |
if( down ) |
|
359 |
{ |
|
360 |
RubikStateSolver solver = (RubikStateSolver) RubikState.SVER.getStateClass(); |
|
361 |
mLastCubitFace = mMovement.getTouchedFace(); |
|
362 |
float[] point = mMovement.getTouchedPoint3D(); |
|
363 |
int color = solver.getCurrentColor(); |
|
364 |
RubikObject object = mPreRender.getObject(); |
|
365 |
mLastCubit = object.getCubit(point); |
|
366 |
mPreRender.setTextureMap( mLastCubit, mLastCubitFace, color ); |
|
367 |
mLastCubitColor = SolverMain.cubitIsLocked(object.getObjectList(), object.getSize(), mLastCubit); |
|
368 |
} |
|
369 |
} |
|
370 |
} |
|
371 |
else |
|
372 |
{ |
|
373 |
mDragging = true; |
|
374 |
mBeginningRotation = false; |
|
375 |
mContinuingRotation = false; |
|
376 |
} |
|
377 |
} |
|
378 |
} |
|
379 |
|
|
380 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
381 |
|
|
382 |
private void actionDown(float x, float y) |
|
383 |
{ |
|
384 |
mX = x; |
|
385 |
mY = y; |
|
386 |
setUpDragOrRotate(true,x,y); |
|
387 |
} |
|
388 |
|
|
389 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
390 |
|
|
391 |
private void actionMove(float x, float y) |
|
392 |
{ |
|
393 |
if( mBeginningRotation ) |
|
394 |
{ |
|
395 |
if( canBeginRotate(x,y) ) |
|
396 |
{ |
|
397 |
mStartRotX = x; |
|
398 |
mStartRotY = y; |
|
399 |
|
|
400 |
Static4D touchPoint2 = new Static4D(x, y, 0, 0); |
|
401 |
Static4D rotatedTouchPoint2= rotateVectorByInvertedQuat(touchPoint2, mQuatAccumulated); |
|
402 |
|
|
403 |
Static2D res = mMovement.newRotation(rotatedTouchPoint2); |
|
404 |
RubikObject object = mPreRender.getObject(); |
|
405 |
|
|
406 |
mCurrentAxis = (int)res.get0(); |
|
407 |
float offset = res.get1(); |
|
408 |
mCurrentRow = (int)(object.returnMultiplier()*offset); |
|
409 |
computeCurrentAxis( object.getRotationAxis()[mCurrentAxis] ); |
|
410 |
mRotationFactor = object.returnRotationFactor(offset); |
|
411 |
|
|
412 |
object.beginNewRotation( mCurrentAxis, mCurrentRow ); |
|
413 |
|
|
414 |
if( RubikState.getCurrentState()==RubikState.READ ) |
|
415 |
{ |
|
416 |
RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass(); |
|
417 |
solving.resetElapsed(); |
|
418 |
|
|
419 |
final RubikActivity act = (RubikActivity)getContext(); |
|
420 |
|
|
421 |
act.runOnUiThread(new Runnable() |
|
422 |
{ |
|
423 |
@Override |
|
424 |
public void run() |
|
425 |
{ |
|
426 |
RubikState.switchState( act, RubikState.SOLV); |
|
427 |
} |
|
428 |
}); |
|
429 |
} |
|
430 |
|
|
431 |
addSpeedProbe(0.0f); |
|
432 |
|
|
433 |
mBeginningRotation = false; |
|
434 |
mContinuingRotation= true; |
|
435 |
} |
|
436 |
} |
|
437 |
else if( mContinuingRotation ) |
|
438 |
{ |
|
439 |
float angle = continueRotation(x-mStartRotX,y-mStartRotY); |
|
440 |
mCurrentAngle = SWIPING_SENSITIVITY*angle; |
|
441 |
mPreRender.getObject().continueRotation(mCurrentAngle); |
|
442 |
|
|
443 |
addSpeedProbe(mCurrentAngle); |
|
444 |
} |
|
445 |
else if( mDragging ) |
|
446 |
{ |
|
447 |
mTempCurrent.set(quatFromDrag(mX-x,y-mY)); |
|
448 |
mPreRender.setQuatCurrentOnNextRender(); |
|
449 |
|
|
450 |
if( shouldChangeDirection(x,y) ) |
|
451 |
{ |
|
452 |
mX = x; |
|
453 |
mY = y; |
|
454 |
mTempAccumulated.set(quatMultiply(mQuatCurrent, mQuatAccumulated)); |
|
455 |
mTempCurrent.set(0f, 0f, 0f, 1f); |
|
456 |
mPreRender.setQuatCurrentOnNextRender(); |
|
457 |
mPreRender.setQuatAccumulatedOnNextRender(); |
|
458 |
} |
|
459 |
} |
|
460 |
else |
|
461 |
{ |
|
462 |
setUpDragOrRotate(false,x,y); |
|
463 |
} |
|
464 |
} |
|
465 |
|
|
466 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
467 |
|
|
468 |
private void actionUp() |
|
469 |
{ |
|
470 |
if( mDragging ) |
|
471 |
{ |
|
472 |
mTempAccumulated.set(quatMultiply(mQuatCurrent, mQuatAccumulated)); |
|
473 |
mTempCurrent.set(0f, 0f, 0f, 1f); |
|
474 |
mPreRender.setQuatCurrentOnNextRender(); |
|
475 |
mPreRender.setQuatAccumulatedOnNextRender(); |
|
476 |
} |
|
477 |
|
|
478 |
if( mContinuingRotation ) |
|
479 |
{ |
|
480 |
computeCurrentSpeed(); |
|
481 |
int angle = mPreRender.getObject().computeNearestAngle(mCurrentAngle, mCurrRotSpeed); |
|
482 |
mPreRender.finishRotation(angle); |
|
483 |
|
|
484 |
if( RubikState.getCurrentState()==RubikState.SOLV && angle!=0 ) |
|
485 |
{ |
|
486 |
RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass(); |
|
487 |
solving.addMove(mCurrentAxis, mCurrentRow, angle); |
|
488 |
} |
|
489 |
} |
|
490 |
|
|
491 |
if( mLastCubitColor>=0 ) |
|
492 |
{ |
|
493 |
mPreRender.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor ); |
|
494 |
} |
|
495 |
} |
|
496 |
|
|
366 | 497 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
367 | 498 |
// PUBLIC API |
368 | 499 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
402 | 533 |
|
403 | 534 |
switch(action) |
404 | 535 |
{ |
405 |
case MotionEvent.ACTION_DOWN: mX = x; |
|
406 |
mY = y; |
|
407 |
setUpDragOrRotate(true,x,y); |
|
408 |
break; |
|
409 |
case MotionEvent.ACTION_MOVE: if( mBeginningRotation ) |
|
410 |
{ |
|
411 |
if( (mX-x)*(mX-x)+(mY-y)*(mY-y) > 1.0f/(ROTATION_SENSITIVITY*ROTATION_SENSITIVITY) ) |
|
412 |
{ |
|
413 |
mStartRotX = x; |
|
414 |
mStartRotY = y; |
|
415 |
|
|
416 |
Static4D touchPoint2 = new Static4D(x, y, 0, 0); |
|
417 |
Static4D rotatedTouchPoint2= rotateVectorByInvertedQuat(touchPoint2, mQuatAccumulated); |
|
418 |
|
|
419 |
Static2D res = mMovement.newRotation(rotatedTouchPoint2); |
|
420 |
RubikObject object = mPreRender.getObject(); |
|
421 |
|
|
422 |
mCurrentAxis = (int)res.get0(); |
|
423 |
float offset = res.get1(); |
|
424 |
mCurrentRow = (int)(object.returnMultiplier()*offset); |
|
425 |
computeCurrentAxis( object.getRotationAxis()[mCurrentAxis] ); |
|
426 |
mRotationFactor = object.returnRotationFactor(offset); |
|
427 |
|
|
428 |
object.beginNewRotation( mCurrentAxis, mCurrentRow ); |
|
429 |
|
|
430 |
if( RubikState.getCurrentState()==RubikState.READ ) |
|
431 |
{ |
|
432 |
RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass(); |
|
433 |
solving.resetElapsed(); |
|
434 |
|
|
435 |
final RubikActivity act = (RubikActivity)getContext(); |
|
436 |
|
|
437 |
act.runOnUiThread(new Runnable() |
|
438 |
{ |
|
439 |
@Override |
|
440 |
public void run() |
|
441 |
{ |
|
442 |
RubikState.switchState( act, RubikState.SOLV); |
|
443 |
} |
|
444 |
}); |
|
445 |
} |
|
446 |
|
|
447 |
addSpeedProbe(0.0f); |
|
448 |
|
|
449 |
mBeginningRotation = false; |
|
450 |
mContinuingRotation= true; |
|
451 |
} |
|
452 |
} |
|
453 |
else if( mContinuingRotation ) |
|
454 |
{ |
|
455 |
float angle = continueRotation(x-mStartRotX,y-mStartRotY); |
|
456 |
mCurrentAngle = SWIPING_SENSITIVITY*angle; |
|
457 |
mPreRender.getObject().continueRotation(mCurrentAngle); |
|
458 |
|
|
459 |
addSpeedProbe(mCurrentAngle); |
|
460 |
} |
|
461 |
else if( mDragging ) |
|
462 |
{ |
|
463 |
mTempCurrent.set(quatFromDrag(mX-x,y-mY)); |
|
464 |
mPreRender.setQuatCurrentOnNextRender(); |
|
465 |
|
|
466 |
if( (mX-x)*(mX-x) + (mY-y)*(mY-y) > 1.0f/(DIRECTION_SENSITIVITY*DIRECTION_SENSITIVITY) ) |
|
467 |
{ |
|
468 |
mX = x; |
|
469 |
mY = y; |
|
470 |
mTempAccumulated.set(quatMultiply(mQuatCurrent, mQuatAccumulated)); |
|
471 |
mTempCurrent.set(0f, 0f, 0f, 1f); |
|
472 |
mPreRender.setQuatCurrentOnNextRender(); |
|
473 |
mPreRender.setQuatAccumulatedOnNextRender(); |
|
474 |
} |
|
475 |
} |
|
476 |
else |
|
477 |
{ |
|
478 |
setUpDragOrRotate(false,x,y); |
|
479 |
} |
|
480 |
break; |
|
481 |
case MotionEvent.ACTION_UP : if( mDragging ) |
|
482 |
{ |
|
483 |
mTempAccumulated.set(quatMultiply(mQuatCurrent, mQuatAccumulated)); |
|
484 |
mTempCurrent.set(0f, 0f, 0f, 1f); |
|
485 |
mPreRender.setQuatCurrentOnNextRender(); |
|
486 |
mPreRender.setQuatAccumulatedOnNextRender(); |
|
487 |
} |
|
488 |
|
|
489 |
if( mContinuingRotation ) |
|
490 |
{ |
|
491 |
computeCurrentSpeed(); |
|
492 |
int angle = mPreRender.getObject().computeNearestAngle(mCurrentAngle, mCurrRotSpeed); |
|
493 |
mPreRender.finishRotation(angle); |
|
494 |
|
|
495 |
if( RubikState.getCurrentState()==RubikState.SOLV ) |
|
496 |
{ |
|
497 |
RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass(); |
|
498 |
|
|
499 |
if( angle!=0 ) |
|
500 |
solving.addMove(mCurrentAxis, mCurrentRow, angle); |
|
501 |
} |
|
502 |
} |
|
503 |
if( mLastCubitColor>=0 ) |
|
504 |
{ |
|
505 |
mPreRender.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor ); |
|
506 |
} |
|
507 |
break; |
|
536 |
case MotionEvent.ACTION_DOWN: actionDown(x,y); break; |
|
537 |
case MotionEvent.ACTION_MOVE: actionMove(x,y); break; |
|
538 |
case MotionEvent.ACTION_UP : actionUp() ; break; |
|
508 | 539 |
} |
509 | 540 |
|
510 | 541 |
return true; |
Also available in: Unified diff
Split up the onTouch() part of the View.