Project

General

Profile

« Previous | Next » 

Revision 168b6b56

Added by Leszek Koltunski almost 4 years ago

Improvements for the way we rotate layers of Objects. (take the speed into account - so even if we rotated a layer of a Cube to less than 45 degrees, but we did it fast, do a 90 degree rotation!)

View differences:

src/main/java/org/distorted/main/RubikPreRender.java
65 65
  private ActionFinishedListener mAddActionListener;
66 66
  private long mAddRotationID, mRemoveRotationID;
67 67
  private int mCubit, mFace, mNewColor;
68
  private int mNearestAngle;
68 69

  
69 70
///////////////////////////////////////////////////////////////////////////////////////////////////
70 71

  
......
224 225
    mFinishRotation = false;
225 226
    mCanRotate      = false;
226 227
    mCanPlay        = false;
227
    mRotationFinishedID = mNewObject.finishRotationNow(this);
228
    mRotationFinishedID = mNewObject.finishRotationNow(this, mNearestAngle);
228 229

  
229 230
    if( mRotationFinishedID==0 ) // failed to add effect - should never happen
230 231
      {
......
366 367

  
367 368
///////////////////////////////////////////////////////////////////////////////////////////////////
368 369

  
369
  void finishRotation()
370
  void finishRotation(int nearestAngle)
370 371
    {
372
    mNearestAngle   = nearestAngle;
371 373
    mFinishRotation = true;
372 374
    }
373 375

  
src/main/java/org/distorted/main/RubikSurfaceView.java
40 40

  
41 41
public class RubikSurfaceView extends GLSurfaceView
42 42
{
43
    private static final int NUM_SPEED_PROBES = 10;
44

  
43 45
    public static final int MODE_ROTATE  = 0;
44 46
    public static final int MODE_DRAG    = 1;
45 47
    public static final int MODE_REPLACE = 2;
......
75 77
    private float mRotationFactor;
76 78
    private int mLastCubitColor, mLastCubitFace, mLastCubit;
77 79
    private int mCurrentAxis, mCurrentRow;
78
    private float mCurrentAngle;
80
    private float mCurrentAngle, mCurrRotSpeed;
81
    private float[] mLastAngles;
82
    private long[] mLastTimestamps;
83
    private int mFirstIndex, mLastIndex;
79 84

  
80 85
    private static Static4D mQuatCurrent    = new Static4D(0,0,0,1);
81 86
    private static Static4D mQuatAccumulated= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
......
315 320
      return quatMultiply(tmp,quat);
316 321
      }
317 322

  
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

  
325
    private void addSpeedProbe(float angle)
326
      {
327
      long currTime = System.currentTimeMillis();
328
      boolean theSame = mLastIndex==mFirstIndex;
329

  
330
      mLastIndex++;
331
      if( mLastIndex>=NUM_SPEED_PROBES ) mLastIndex=0;
332

  
333
      mLastTimestamps[mLastIndex] = currTime;
334
      mLastAngles[mLastIndex] = angle;
335

  
336
      if( mLastIndex==mFirstIndex)
337
        {
338
        mFirstIndex++;
339
        if( mFirstIndex>=NUM_SPEED_PROBES ) mFirstIndex=0;
340
        }
341

  
342
      if( theSame )
343
        {
344
        mLastTimestamps[mFirstIndex] = currTime;
345
        mLastAngles[mFirstIndex] = angle;
346
        }
347
      }
348

  
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350

  
351
    private void computeCurrentSpeed()
352
      {
353
      long firstTime = mLastTimestamps[mFirstIndex];
354
      long lastTime  = mLastTimestamps[mLastIndex];
355
      float firstAngle = mLastAngles[mFirstIndex];
356
      float lastAngle  = mLastAngles[mLastIndex];
357

  
358
      long timeDiff = lastTime-firstTime;
359

  
360
      mLastIndex = 0;
361
      mFirstIndex= 0;
362

  
363
      mCurrRotSpeed = timeDiff>0 ? (lastAngle-firstAngle)/timeDiff : 0;
364
      }
365

  
318 366
///////////////////////////////////////////////////////////////////////////////////////////////////
319 367
// PUBLIC API
320 368
///////////////////////////////////////////////////////////////////////////////////////////////////
......
326 374
      if(!isInEditMode())
327 375
        {
328 376
        mLastCubitColor = -1;
377
        mCurrRotSpeed   = 0.0f;
378

  
379
        mLastAngles = new float[NUM_SPEED_PROBES];
380
        mLastTimestamps = new long[NUM_SPEED_PROBES];
381
        mFirstIndex =0;
382
        mLastIndex  =0;
329 383

  
330 384
        mRenderer  = new RubikRenderer(this);
331 385
        mPreRender = new RubikPreRender(this);
......
390 444
                                               });
391 445
                                             }
392 446

  
447
                                           addSpeedProbe(0.0f);
448

  
393 449
                                           mBeginningRotation = false;
394 450
                                           mContinuingRotation= true;
395 451
                                           }
......
399 455
                                         float angle = continueRotation(x-mStartRotX,y-mStartRotY);
400 456
                                         mCurrentAngle = SWIPING_SENSITIVITY*angle;
401 457
                                         mPreRender.getObject().continueRotation(mCurrentAngle);
458

  
459
                                         addSpeedProbe(mCurrentAngle);
402 460
                                         }
403 461
                                       else if( mDragging )
404 462
                                         {
......
430 488

  
431 489
                                       if( mContinuingRotation )
432 490
                                         {
433
                                         mPreRender.finishRotation();
491
                                         computeCurrentSpeed();
492
                                         int angle = mPreRender.getObject().computeNearestAngle(mCurrentAngle, mCurrRotSpeed);
493
                                         mPreRender.finishRotation(angle);
434 494

  
435 495
                                         if( RubikState.getCurrentState()==RubikState.SOLV )
436 496
                                           {
437 497
                                           RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
438 498

  
439
                                           int angle = mPreRender.getObject().computeNearestAngle(mCurrentAngle);
440

  
441 499
                                           if( angle!=0 )
442 500
                                             solving.addMove(mCurrentAxis, mCurrentRow, angle);
443 501
                                           }
src/main/java/org/distorted/objects/RubikObject.java
520 520

  
521 521
///////////////////////////////////////////////////////////////////////////////////////////////////
522 522

  
523
  public long finishRotationNow(EffectListener listener)
523
  public long finishRotationNow(EffectListener listener, int nearestAngleInDegrees)
524 524
    {
525 525
    float angle = getAngle();
526
    int nearestAngleInDegrees = computeNearestAngle(angle);
527 526
    mRotationAngleStatic.set0(angle);
528 527
    mRotationAngleFinal.set0(nearestAngleInDegrees);
529 528
    mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-angle)*0.2f );
......
561 560
///////////////////////////////////////////////////////////////////////////////////////////////////
562 561

  
563 562
  public void removeRotationNow()
564
     {
565
     float angle = getAngle();
566
     int nearestAngleInDegrees = computeNearestAngle(angle);
567
     double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
568
     float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
569
     float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
570
     float axisX = ROTATION_AXIS[mRotAxis].get0();
571
     float axisY = ROTATION_AXIS[mRotAxis].get1();
572
     float axisZ = ROTATION_AXIS[mRotAxis].get2();
573
     Static4D quat = new Static4D( axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
574

  
575
     mRotationAngle.removeAll();
576
     mRotationAngleStatic.set0(0);
577

  
578
     for(int i=0; i<NUM_CUBITS; i++)
579
       if( belongsToRotation(i,mRotAxis,mRotRowBitmap) )
580
         {
581
         int index = mCubits[i].removeRotationNow(quat);
582
         mMesh.setEffectAssociation(i,mCubits[i].computeAssociation(),index);
583
         }
584
     }
563
    {
564
    float angle = getAngle();
565
    double nearestAngleInRadians = angle*Math.PI/180;
566
    float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
567
    float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
568
    float axisX = ROTATION_AXIS[mRotAxis].get0();
569
    float axisY = ROTATION_AXIS[mRotAxis].get1();
570
    float axisZ = ROTATION_AXIS[mRotAxis].get2();
571
    Static4D quat = new Static4D( axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
572

  
573
    mRotationAngle.removeAll();
574
    mRotationAngleStatic.set0(0);
575

  
576
    for(int i=0; i<NUM_CUBITS; i++)
577
      if( belongsToRotation(i,mRotAxis,mRotRowBitmap) )
578
        {
579
        int index = mCubits[i].removeRotationNow(quat);
580
        mMesh.setEffectAssociation(i,mCubits[i].computeAssociation(),index);
581
        }
582
    }
585 583

  
586 584
///////////////////////////////////////////////////////////////////////////////////////////////////
587 585

  
......
618 616

  
619 617
///////////////////////////////////////////////////////////////////////////////////////////////////
620 618

  
621
  public int computeNearestAngle(float angle)
619
  public int computeNearestAngle(float angle, float speed)
622 620
    {
623 621
    final int NEAREST = 360/getBasicAngle();
624 622

  
625
    int tmp = (int)((angle+NEAREST/2)/NEAREST);
626
    if( angle< -(NEAREST*0.5) ) tmp-=1;
623
    float angleAndSpeed = angle + 100*speed;
624

  
625
    int tmp1 = (int)((angle+NEAREST/2)/NEAREST);
626
    if( angle< -(NEAREST*0.5) ) tmp1-=1;
627

  
628
    int tmp2 = (int)((angleAndSpeed+NEAREST/2)/NEAREST);
629
    if( angleAndSpeed< -(NEAREST*0.5) ) tmp2-=1;
627 630

  
628
    return NEAREST*tmp;
631
    return NEAREST*(tmp1==0 ? tmp2 : tmp1);
629 632
    }
630 633

  
631 634
///////////////////////////////////////////////////////////////////////////////////////////////////

Also available in: Unified diff