Project

General

Profile

« Previous | Next » 

Revision 0c5d8bf7

Added by Leszek Koltunski over 2 years ago

FIx some issues with ShapeChanging; implement per-object TouchControlSquare and TouchControlMirror.

View differences:

src/main/java/org/distorted/objectlib/touchcontrol/TouchControlShapeChanging.java
30 30
public class TouchControlShapeChanging extends TouchControl
31 31
  {
32 32
  private static final float NOT_TOUCHED = 1000000.0f;
33
  private static final float[] mTmp = new float[4];
33
  static final float[] mTmp = new float[4];
34 34

  
35
  private static class FaceInfo
35
  static class FaceInfo
36 36
    {
37
    private final float[] vector;
38
    private final float distance;
39
    private final float[][] vertices;
40
    private final float[][] rotated;
37
    private final float[] normal;      // vector normal to the surface of the face, pointing outside.
38
    private final float distance;      // distance from (0,0,0) to the surface of the face
39
    private final float[][] vertices;  // vertices of the face. Already rotated by the initQuat and
40
                                       // moved by 'position' (arithmetic average of all positions)
41
    private final float[][] rotated;   // temp array to store vertices times rotation quaternion.
42

  
43
    //////////////////////////////////////////////////////////
41 44

  
42 45
    FaceInfo(float[][] verts, float size)
43 46
      {
......
73 76
      vy/=len;
74 77
      vz/=len;
75 78

  
76
      float dist = vx*vertices[0][0] + vy*vertices[0][1] + vz*vertices[0][2];
79
      distance = vx*vertices[0][0] + vy*vertices[0][1] + vz*vertices[0][2];
77 80

  
78
      if( dist<0 )
79
        {
80
        dist = -dist;
81
        vx = -vx;
82
        vy = -vy;
83
        vz = -vz;
84
        }
81
      normal = new float[4];
82
      normal[0] = vx;
83
      normal[1] = vy;
84
      normal[2] = vz;
85
      normal[3] = 0.0f;
86
      }
85 87

  
86
      vector = new float[4];
87
      vector[0] = vx;
88
      vector[1] = vy;
89
      vector[2] = vz;
90
      vector[3] = 0.0f;
88
    //////////////////////////////////////////////////////////
91 89

  
92
      distance = dist;
90
    public float[] getNormal()
91
      {
92
      return normal;
93 93
      }
94 94
    }
95 95

  
96
  private final float[] mPoint, mCamera, mTouch;
97
  private final TwistyObject mObject;
98

  
99
  private float[][] mQuats;
96
  private final float[] mTouch;
97
  private final Static4D mTmpAxis;
100 98
  private int mNumCubits;
101 99
  private int[] mNumFaces;
102 100
  private boolean mPreparationDone;
103
  private FaceInfo[][] mInfos;
104
  private int mTouchedCubit;
105
  private int mTouchedFace;
106
  private final Static3D[] mRotAxis;
107
  private final int mNumAxis;
108
  private final Static4D mTmpAxis;
101

  
102
  final float[] mCamera, mPoint;
103
  final Static3D[] mRotAxis;
104
  final TwistyObject mObject;
105
  int mTouchedCubit, mTouchedFace, mNumAxis;
106
  FaceInfo[][] mInfos;
107
  float[][] mQuats;
109 108

  
110 109
///////////////////////////////////////////////////////////////////////////////////////////////////
111 110

  
......
120 119
    mPreparationDone = false;
121 120
    mRotAxis = object.getRotationAxis();
122 121
    mNumAxis = mRotAxis.length;
123

  
124 122
    mTmpAxis = new Static4D(0,0,0,0);
125 123
    }
126 124

  
......
381 379
//
382 380
// output = camera + alpha*(point-camera), where alpha = [dist-normalVec*camera] / [normalVec*(point-camera)]
383 381

  
384
  private void castTouchPointOntoFace(float nx, float ny, float nz, float distance, float[] output)
382
  void castTouchPointOntoFace(float nx, float ny, float nz, float distance, float[] output)
385 383
    {
386 384
    float d0 = mPoint[0]-mCamera[0];
387 385
    float d1 = mPoint[1]-mCamera[1];
......
402 400

  
403 401
///////////////////////////////////////////////////////////////////////////////////////////////////
404 402

  
405
  private boolean faceIsVisible(float nx, float ny, float nz, float distance)
403
  private boolean cubitFaceIsVisible(float nx, float ny, float nz, float distance)
406 404
    {
407 405
    return mCamera[0]*nx + mCamera[1]*ny + mCamera[2]*nz > distance;
408 406
    }
......
416 414
// 2) else, cast the line passing through mPoint and mCamera onto this plane
417 415
// 3) if Z of this point is further from us than the already computed closestSoFar, return NOT_TOUCHED
418 416
// 4) else, rotate 'vertices' by quat and see if the casted point lies inside the polygon defined by them
419
// 5) if yes, return its Z; otherwise, return NOT_TOUCHED
417
// 5) if yes, return the distance form this point to the camera; otherwise, return NOT_TOUCHED
420 418

  
421 419
  private float cubitFaceTouched(FaceInfo info, float[] quat, float closestSoFar)
422 420
    {
423
    QuatHelper.rotateVectorByQuat(mTmp,info.vector,quat);
421
    QuatHelper.rotateVectorByQuat(mTmp,info.normal,quat);
424 422
    float nx = mTmp[0];
425 423
    float ny = mTmp[1];
426 424
    float nz = mTmp[2];
427 425

  
428
    if( faceIsVisible(nx,ny,nz,info.distance) )
426
    if( cubitFaceIsVisible(nx,ny,nz,info.distance) )
429 427
      {
430 428
      castTouchPointOntoFace(nx,ny,nz,info.distance,mTouch);
431 429

  
......
446 444

  
447 445
///////////////////////////////////////////////////////////////////////////////////////////////////
448 446

  
449
  private int computeDisabledAxis()
450
    {
451
    float cx = mCamera[0];
452
    float cy = mCamera[1];
453
    float cz = mCamera[2];
454

  
455
    float len = (float)Math.sqrt(cx*cx+cy*cy+cz*cz);
456

  
457
    cx /= len;
458
    cy /= len;
459
    cz /= len;
460

  
461
    float max = -1.0f;
462
    int maxAxis = -1;
463

  
464
    for(int axis=0; axis<mNumAxis; axis++)
465
      {
466
      float ax = mRotAxis[axis].get0();
467
      float ay = mRotAxis[axis].get1();
468
      float az = mRotAxis[axis].get2();
469

  
470
      float angle = ax*cx + ay*cy + az*cz;
471
      if( angle<0 ) angle = -angle;
472

  
473
      if( angle>max )
474
        {
475
        max=angle;
476
        maxAxis = axis;
477
        }
478
      }
479

  
480
    return maxAxis;
481
    }
482

  
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

  
485
  private int computeRotationIndex(int disabled, float dx, float dy, float dz)
486
    {
487
    float min = Float.MAX_VALUE;
488
    int minAxis = -1;
489

  
490
    for(int axis=0; axis<mNumAxis; axis++)
491
      if( axis!=disabled )
492
        {
493
        float ax = mRotAxis[axis].get0();
494
        float ay = mRotAxis[axis].get1();
495
        float az = mRotAxis[axis].get2();
496

  
497
        float angle = dx*ax + dy*ay + dz*az;
498
        if( angle<0 ) angle=-angle;
499

  
500
        if( angle<min )
501
          {
502
          min=angle;
503
          minAxis = axis;
504
          }
505
        }
506

  
507
    return minAxis;
508
    }
509

  
510
///////////////////////////////////////////////////////////////////////////////////////////////////
511

  
512
  private int computeRow(int cubit, int rotIndex)
447
  int computeRow(int cubit, int rotIndex)
513 448
    {
514 449
    int row = mObject.getCubitRotRow(cubit,rotIndex);
515 450

  
......
569 504
    }
570 505

  
571 506
///////////////////////////////////////////////////////////////////////////////////////////////////
507
// really implemented in derived classes; here present only because we need to be able to
508
// instantiate an object of this class for MODE_REPLACE.
572 509

  
573 510
  public void newRotation(int[] output, Static4D rotatedTouchPoint)
574 511
    {
575
    if( !mPreparationDone ) prepare();
576

  
577
    float dx = mPoint[0] - rotatedTouchPoint.get0()/mObjectRatio;
578
    float dy = mPoint[1] - rotatedTouchPoint.get1()/mObjectRatio;
579
    float dz = mPoint[2] - rotatedTouchPoint.get2()/mObjectRatio;
580

  
581
    int disabledAxis = computeDisabledAxis();
582
    int rotIndex     = computeRotationIndex(disabledAxis,dx,dy,dz);
583
    int row          = computeRow(mTouchedCubit,rotIndex);
584 512

  
585
    output[0] = rotIndex;
586
    output[1] = row;
587 513
    }
588 514

  
589 515
///////////////////////////////////////////////////////////////////////////////////////////////////

Also available in: Unified diff