Project

General

Profile

« Previous | Next » 

Revision 4946b635

Added by Leszek Koltunski over 2 years ago

Major abstraction - automatically compute the 'computeRowFromOffset()' function from CUTS.
Still one thing left: it appears like the CUTS of Mega/Kilominxes are not correct.

View differences:

src/main/java/org/distorted/objects/Movement.java
34 34
  private final float[] mPoint, mCamera, mTouch;
35 35
  private final float[] mPoint2D, mMove2D;
36 36
  private final int[] mEnabledRotAxis;
37
  private final float mDistanceCenterFace3D, mDistanceCenterFace2D;
37
  private final float mDistanceCenterFace3D;
38 38
  private final Static3D[] mFaceAxis;
39 39

  
40 40
  private int mLastTouchedFace;
41 41
  private float[][][] mCastedRotAxis;
42 42
  private Static4D[][] mCastedRotAxis4D;
43
  private float[][] mTouchBorders, mA, mB;
43 44

  
44 45
///////////////////////////////////////////////////////////////////////////////////////////////////
45 46

  
46 47
  abstract boolean isInsideFace(int face, float[] point);
47 48
  abstract void computeEnabledAxis(int face, float[] touchPoint, int[] enabledAxis);
48
  abstract int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset);
49 49
  public abstract float returnRotationFactor(int numLayers, int row);
50 50

  
51 51
///////////////////////////////////////////////////////////////////////////////////////////////////
52 52

  
53
  Movement(Static3D[] rotAxis, Static3D[] faceAxis, float distance3D, float distance2D)
53
  Movement(Static3D[] rotAxis, Static3D[] faceAxis, float[][] cuts, boolean[][] rotatable, float distance3D, int size)
54 54
    {
55 55
    mPoint = new float[3];
56 56
    mCamera= new float[3];
......
65 65
    mEnabledRotAxis = new int[rotAxis.length+1];
66 66

  
67 67
    mDistanceCenterFace3D = distance3D; // distance from the center of the object to each of its faces
68
    mDistanceCenterFace2D = distance2D; // distance from the center of a face to its edge
69 68

  
70 69
    computeCastedAxis(rotAxis);
70
    computeBorders(cuts,rotatable,size);
71
    computeLinear(distance3D,rotAxis,faceAxis);
71 72
    }
72 73

  
73 74
///////////////////////////////////////////////////////////////////////////////////////////////////
......
249 250

  
250 251
///////////////////////////////////////////////////////////////////////////////////////////////////
251 252

  
252
  float[] computeBorder(float scale, float[] cuts, boolean[] rotatable)
253
  private float[] computeBorder(float[] cuts, boolean[] rotatable, int size)
253 254
    {
254 255
    int len = cuts.length;
255 256
    float[] border = new float[len];
......
262 263
        }
263 264
      else
264 265
        {
265
        if( rotatable[i+1] ) border[i] = scale*cuts[i];
266
        if( rotatable[i+1] ) border[i] = cuts[i]/size;
266 267
        else
267 268
          {
268 269
          int found = -1;
......
276 277
              }
277 278
            }
278 279

  
279
          border[i] = found>0 ? scale*(cuts[i]+cuts[found-1])/2 : Float.MAX_VALUE;
280
          border[i] = found>0 ? (cuts[i]+cuts[found-1])/(2*size) : Float.MAX_VALUE;
280 281
          }
281 282
        }
282 283
      }
......
285 286
    }
286 287

  
287 288
///////////////////////////////////////////////////////////////////////////////////////////////////
289
// size, not numLayers (see Master Skewb where size!=numLayers)
288 290

  
289
  float[][] computeBorders(float coeff, float[][] cuts, boolean[][] rotatable)
291
  void computeBorders(float[][] cuts, boolean[][] rotatable, int size)
290 292
    {
291 293
    int numCuts = cuts.length;
292
    float[][] borders = new float[numCuts][];
294
    mTouchBorders = new float[numCuts][];
293 295

  
294 296
    for(int i=0; i<numCuts; i++)
295 297
      {
296
      borders[i] = computeBorder(coeff,cuts[i],rotatable[i]);
298
      mTouchBorders[i] = computeBorder(cuts[i],rotatable[i],size);
299
      }
300
    }
301

  
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

  
304
  private int computeSign(Static3D a, Static3D b)
305
    {
306
    float a1 = a.get0();
307
    float a2 = a.get1();
308
    float a3 = a.get2();
309
    float b1 = b.get0();
310
    float b2 = b.get1();
311
    float b3 = b.get2();
312

  
313
    return a1*b1+a2*b2+a3*b3 < 0 ? 1:-1;
314
    }
315

  
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

  
318
  private float crossProductLen(Static3D a, Static3D b)
319
    {
320
    float a1 = a.get0();
321
    float a2 = a.get1();
322
    float a3 = a.get2();
323
    float b1 = b.get0();
324
    float b2 = b.get1();
325
    float b3 = b.get2();
326

  
327
    float x1 = a2*b3-a3*b2;
328
    float x2 = a3*b1-a1*b3;
329
    float x3 = a1*b2-a2*b1;
330

  
331
    return (float)Math.sqrt(x1*x1 + x2*x2 + x3*x3);
332
    }
333

  
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335
// compute the array of 'A' and 'B' coeffs of the Ax+B linear function by which we need to multiply
336
// the 3D 'cuts' to translate it from 3D (i.e. with respect to the rotAxis) to 2D in-face (i.e. with
337
// respect to the 2D rotAxis cast into a particular face)
338

  
339
  void computeLinear(float distance3D, Static3D[] rotAxis, Static3D[] faceAxis)
340
    {
341
    int numFaces = faceAxis.length;
342
    int numRot   = rotAxis.length;
343

  
344
    mA = new float[numFaces][numRot];
345
    mB = new float[numFaces][numRot];
346

  
347
    for(int i=0; i<numFaces; i++)
348
      for(int j=0; j<numRot; j++)
349
        {
350
        mA[i][j] = crossProductLen(faceAxis[i],rotAxis[j]);
351

  
352
        if( mA[i][j]!=0.0f )
353
          {
354
          float coeff = (float)Math.sqrt(1/(mA[i][j]*mA[i][j]) -1);
355
          int sign = computeSign(faceAxis[i],rotAxis[j]);
356
          mB[i][j] = sign*distance3D*coeff;
357
          }
358
        else mB[i][j] = 0.0f;
359

  
360
        android.util.Log.e("D", "face="+i+" rot="+j+" a="+mA[i][j]+" B="+mB[i][j]);
361
        }
362
    }
363

  
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

  
366
  private int computeRowFromOffset(int face, int axisIndex, float offset)
367
    {
368
    float[] borders = mTouchBorders[axisIndex];
369
    int len = borders.length;
370
    float A = mA[face][axisIndex];
371

  
372
    if( A!=0.0f )
373
      {
374
      float B = mB[face][axisIndex];
375

  
376
      for(int i=0; i<len; i++)
377
        {
378
        float translated = B + borders[i]/A;
379

  
380
        android.util.Log.e("D", "offset="+offset+" borders[i]="+borders[i]+" translated="+translated+" A="+A+" B="+B);
381

  
382
        if( offset<translated ) return i;
383
        }
297 384
      }
298 385

  
299
    return borders;
386
    return len;
300 387
    }
301 388

  
302 389
///////////////////////////////////////////////////////////////////////////////////////////////////
......
328 415

  
329 416
///////////////////////////////////////////////////////////////////////////////////////////////////
330 417

  
331
  public Static2D newRotation(int numLayers, Static4D rotatedTouchPoint, float objectRatio)
418
  public Static2D newRotation(Static4D rotatedTouchPoint, float objectRatio)
332 419
    {
333 420
    mPoint[0] = rotatedTouchPoint.get0()/objectRatio;
334 421
    mPoint[1] = rotatedTouchPoint.get1()/objectRatio;
......
343 430
    computeEnabledAxis(mLastTouchedFace, mPoint2D, mEnabledRotAxis);
344 431
    int rotIndex = computeRotationIndex(mLastTouchedFace, mMove2D, mEnabledRotAxis);
345 432
    float offset = computeOffset(mPoint2D, mCastedRotAxis[mLastTouchedFace][rotIndex]);
346
    int row      = computeRowFromOffset(mLastTouchedFace,rotIndex,numLayers,offset);
433
    int row      = computeRowFromOffset(mLastTouchedFace,rotIndex,offset);
347 434

  
348 435
    return new Static2D(rotIndex,row);
349 436
    }

Also available in: Unified diff