Project

General

Profile

« Previous | Next » 

Revision c8f3a765

Added by Leszek Koltunski about 2 years ago

fix the 'band' problem in the TwistyBandagedMegaminx.

View differences:

src/main/java/org/distorted/objectlib/bandaged/FactoryBandaged.java
118 118
  private ArrayList<float[]> mTmpArray;
119 119
  private ArrayList<float[][]> mVertexArray;
120 120
  private BandagedElement[] mElements;
121
  private Static3D[] mNormals;
121
  private Static3D[] mPuzzleNormals;
122 122
  private float[] mDist3D;
123 123
  private int[][] mFaceBelongsBitmap;
124 124
  private float[][] mDiaAxis;
......
132 132
  private int[] mNumLayers;
133 133
  private float[] mTmp;
134 134
  private float[][][] mAllPositions;
135
  private boolean mCalledFromBandagedObject; // true if this class is being called from the
136
                                             // one of the 'BandagedObject*' classes; false if
137
                                             // called from one of the 'TwistyBandaged*' classes.
135 138

  
136 139
///////////////////////////////////////////////////////////////////////////////////////////////////
137 140

  
......
153 156
  abstract float[][] getVertices(int[] numLayers, int variant);
154 157
  abstract int[][] getIndices(int[] numLayers, int variant);
155 158
  abstract int getNumVariants(int[] numLayers);
156

  
159
  abstract float sizeCorrection(int[] numLayers); // again workaround for the Megaminx
160
                                                  // '2-3-4-5' vs. '3-3-5-5' problem.
157 161
///////////////////////////////////////////////////////////////////////////////////////////////////
158 162

  
159
  private int[] computeFaceBelongsBitmap(float[][] vertices, float[] move)
163
  private int[] computeFaceBelongsBitmap(float[][] vertices, float[] move, float corr)
160 164
    {
161 165
    int numVerts = vertices.length;
162 166
    int[] ret = new int[numVerts];
163 167

  
164
    for(int i=0; i<numVerts; i++)
168
    for(int v=0; v<numVerts; v++)
165 169
      {
166 170
      int vertBelongsBitmap=0x00000000;
167
      float[] vert=vertices[i];
171
      float[] vert=vertices[v];
168 172

  
169
      for(int j=0; j<mNumFaces; j++)
170
        if( vertInFace(vert, move, mNormals[j], mDist3D[j]) ) vertBelongsBitmap |= (1<<j);
173
      for(int f=0; f<mNumFaces; f++)
174
        if( vertInFace(vert, move, mPuzzleNormals[f], mDist3D[f], corr) )
175
          {
176
          vertBelongsBitmap |= (1<<f);
177
          }
171 178

  
172
      ret[i]=vertBelongsBitmap;
179
      ret[v]=vertBelongsBitmap;
173 180
      }
174 181

  
175 182
    return ret;
......
456 463

  
457 464
///////////////////////////////////////////////////////////////////////////////////////////////////
458 465

  
459
  static boolean vertInFace(float[] vertex, float[] move, Static3D faceAxis, float dist)
466
  static boolean vertInFace(float[] vertex, float[] move, Static3D faceAxis, float dist, float corr)
460 467
    {
461 468
    final float MAX_ERROR = 0.01f;
462 469

  
......
464 471
    float y= faceAxis.get1();
465 472
    float z= faceAxis.get2();
466 473

  
467
    float a = (vertex[0]+move[0])*x + (vertex[1]+move[1])*y + (vertex[2]+move[2])*z;
474
    float vx = vertex[0]*corr;
475
    float vy = vertex[1]*corr;
476
    float vz = vertex[2]*corr;
477

  
478
    float a = (vx+move[0])*x + (vy+move[1])*y + (vz+move[2])*z;
468 479
    float diff = a - dist;
469 480

  
470 481
    return diff>-MAX_ERROR && diff<MAX_ERROR;
......
472 483

  
473 484
///////////////////////////////////////////////////////////////////////////////////////////////////
474 485

  
475
  private void computeVectorFace(float[] prev, float[] curr, float[] next, float[] output)
486
  private float[] computeVector(int index, float[][] vertices, int[][][] indices, int[] bandIndices, float[][] normals)
476 487
    {
477
    float ax = prev[0]-curr[0];
478
    float ay = prev[1]-curr[1];
479
    float az = prev[2]-curr[2];
488
    int numFaces = indices.length;
489
    int numBordering=0, numExternal=0;
490
    float x=0, y=0, z=0;
480 491

  
481
    float bx = next[0]-curr[0];
482
    float by = next[1]-curr[1];
483
    float bz = next[2]-curr[2];
492
    for(int f=0; f<numFaces; f++)
493
      {
494
      int numComponentsInFace = indices[f].length;
484 495

  
485
    float lena = (float)Math.sqrt(ax*ax + ay*ay + az*az);
486
    float lenb = (float)Math.sqrt(bx*bx + by*by + bz*bz);
496
      for(int c=0; c<numComponentsInFace; c++)
497
        {
498
        int[] ind = indices[f][c];
499
        int numVertsInComponent = ind.length;
487 500

  
488
    ax /= lena;
489
    ay /= lena;
490
    az /= lena;
501
        for(int v=0; v<numVertsInComponent; v++)
502
          {
503
          if( ind[v]==index )
504
            {
505
            float[] nor = normals[f];
491 506

  
492
    bx /= lenb;
493
    by /= lenb;
494
    bz /= lenb;
507
            x += nor[0];
508
            y += nor[1];
509
            z += nor[2];
495 510

  
496
    output[0] = ay*bz - az*by;
497
    output[1] = az*bx - ax*bz;
498
    output[2] = ax*by - ay*bx;
511
            numBordering++;
512
            if( bandIndices[f]>0 ) numExternal++;
499 513

  
500
    output[3] = ax;
501
    output[4] = ay;
502
    output[5] = az;
514
            v = numVertsInComponent;
515
            c = numComponentsInFace;
516
            }
517
          }
518
        }
519
      }
503 520

  
504
    output[6] = bx;
505
    output[7] = by;
506
    output[8] = bz;
521
    return ( numExternal<2 || numBordering<3 ) ? null : new float[] { x/numBordering, y/numBordering, z/numBordering};
507 522
    }
508 523

  
509 524
///////////////////////////////////////////////////////////////////////////////////////////////////
510
// 'concave' vertices do not get pushed!
511 525

  
512
  private boolean vertexIsConcave(float[][] vecs, int numVecs)
526
  private void createCubitFaceNormal(float[] output, float[] v0, float[] v1, float[] v2)
513 527
    {
514
    for(int i=0; i<numVecs; i++)
515
      {
516
      float[] v1 = vecs[i];
528
    float ax = v0[0]-v1[0];
529
    float ay = v0[1]-v1[1];
530
    float az = v0[2]-v1[2];
517 531

  
518
      for(int j=0; j<numVecs; j++)
519
        {
520
        if( i==j ) continue;
532
    float bx = v2[0]-v1[0];
533
    float by = v2[1]-v1[1];
534
    float bz = v2[2]-v1[2];
521 535

  
522
        float[] v2 = vecs[j];
536
    output[0] = ay*bz - az*by;
537
    output[1] = az*bx - ax*bz;
538
    output[2] = ax*by - ay*bx;
523 539

  
524
        float scalar1 = v1[0]*v2[3] + v1[1]*v2[4] + v1[2]*v2[5];
525
        float scalar2 = v1[0]*v2[6] + v1[1]*v2[7] + v1[2]*v2[8];
540
    float len = (float)Math.sqrt(output[0]*output[0] + output[1]*output[1] + output[2]*output[2]);
526 541

  
527
        if( scalar1<0 || scalar2<0 ) return true;
528
        }
542
    if( len!=0 )
543
      {
544
      output[0] /= len;
545
      output[1] /= len;
546
      output[2] /= len;
547
      }
548
    else
549
      {
550
      android.util.Log.e("D", "ERROR in createCubitFaceNormal!");
529 551
      }
530

  
531
    return false;
532 552
    }
533 553

  
534 554
///////////////////////////////////////////////////////////////////////////////////////////////////
535 555

  
536
  private float[] computeVector(int index, float[][] vertices, int[][][] indices, int[] bandIndices)
556
  private float[][] generateCubitFaceNormals(float[][] vertices, int[][][] indices)
537 557
    {
538
    int band=0;
539 558
    int numFaces = indices.length;
540
    int numBordering = 0;
541
    float x=0, y=0, z=0;
542

  
543
    float[][] vecs = new float[numFaces][9];
544
    int vecIndex = 0;
559
    float[][] ret = new float[numFaces][3];
545 560

  
546 561
    for(int f=0; f<numFaces; f++)
547 562
      {
548
      int numComponentsInFace = indices[f].length;
563
      int[] verts = indices[f][0];
564
      int numVerts = verts.length;
549 565

  
550
      for(int c=0; c<numComponentsInFace; c++)
566
      for(int v=0; v<numVerts; v++)
551 567
        {
552
        int[] ind = indices[f][c];
553
        int numVertsInComponent = ind.length;
568
        int i0 = verts[0];
569
        int i1 = verts[1];
570
        int i2 = verts[2];
554 571

  
555
        for(int v=0; v<numVertsInComponent; v++)
556
          {
557
          if(ind[v]==index)
558
            {
559
            int prev=v>0 ? v-1 : numVertsInComponent-1;
560
            int next=v<numVertsInComponent-1 ? v+1 : 0;
561

  
562
            int prevIndex=ind[prev];
563
            int currIndex=ind[v];
564
            int nextIndex=ind[next];
565

  
566
            float[] vec = vecs[vecIndex++];
567
            computeVectorFace(vertices[prevIndex], vertices[currIndex], vertices[nextIndex], vec);
568
            band|=bandIndices[f];
569
            v = numVertsInComponent;
570
            c = numComponentsInFace;
571
            numBordering++;
572
        float[] v0 = vertices[i0];
573
        float[] v1 = vertices[i1];
574
        float[] v2 = vertices[i2];
572 575

  
573
            x += vec[0];
574
            y += vec[1];
575
            z += vec[2];
576
            }
577
          }
576
        createCubitFaceNormal(ret[f], v0,v1,v2);
578 577
        }
579 578
      }
580 579

  
581
    boolean concave = vertexIsConcave(vecs,vecIndex);
582

  
583
    return ( concave || band==0 || numBordering<3 ) ? null : new float[] { x/numBordering, y/numBordering, z/numBordering};
580
    return ret;
584 581
    }
585 582

  
586 583
///////////////////////////////////////////////////////////////////////////////////////////////////
......
589 586
    {
590 587
    int len = vertices.length;
591 588
    float[][] vectors = new float[len][];
589
    float[][] normals = generateCubitFaceNormals(vertices,indices);
592 590

  
593 591
    for(int i=0; i<len; i++)
594 592
      {
595
      vectors[i] = computeVector(i,vertices,indices,bandIndices);
593
      vectors[i] = computeVector(i,vertices,indices,bandIndices,normals);
596 594
      }
597 595

  
598 596
    return vectors;
......
863 861
  public void prepare(int numVariants, int[] numLayers)
864 862
    {
865 863
    if( mVertexArray==null ) mVertexArray = new ArrayList<>();
864
    mCalledFromBandagedObject = false;
866 865
    mVertices= new float[numVariants][][];
867 866
    mIndices = new int[numVariants][][][];
868 867
    mMove = new float[numVariants][3];
......
878 877
    mNumLayers = new int[num];
879 878
    for(int l=0; l<num; l++) mNumLayers[l] = numLayers[l];
880 879

  
881
    mNormals   = getNormals();
882
    mNumFaces  = mNormals.length;
883
    mDist3D    = getDist3D(mNumLayers);
884
    mDiaAxis   = getDiameterAxis();
885
    mMinMax    = new float[mDiaAxis.length][2];
880
    mPuzzleNormals= getNormals();
881
    mNumFaces     = mPuzzleNormals.length;
882
    mDist3D       = getDist3D(mNumLayers);
883
    mDiaAxis      = getDiameterAxis();
884
    mMinMax       = new float[mDiaAxis.length][2];
886 885
    }
887 886

  
888 887
///////////////////////////////////////////////////////////////////////////////////////////////////
......
930 929
  public ObjectFaceShape createIrregularFaceShape(int variant, boolean iconMode)
931 930
    {
932 931
    float[][] bands = getBands(iconMode, mNumLayers);
932
    float corr = mCalledFromBandagedObject ? 1.0f : sizeCorrection(mNumLayers);
933 933

  
934 934
    if( mBandIndices[variant]==null )
935 935
      {
936
      mFaceBelongsBitmap[variant] = computeFaceBelongsBitmap(mVertices[variant], mMove[variant]);
936
      mFaceBelongsBitmap[variant] = computeFaceBelongsBitmap(mVertices[variant], mMove[variant],corr);
937 937
      mBandIndices[variant] = generateBandIndices(mVertices[variant], mIndices[variant], mFaceBelongsBitmap[variant]);
938 938
      }
939 939

  
......
974 974
  public MeshBase createMesh(float[] pos, int[] numLayers, boolean iconMode, boolean roundCorners)
975 975
    {
976 976
    prepare(1,numLayers);
977

  
978
    mCalledFromBandagedObject = true;
979

  
977 980
    ObjectShape shape           = createIrregularShape(0,pos);
978 981
    ObjectFaceShape face        = createIrregularFaceShape(0,iconMode);
979 982
    ObjectVertexEffects effects = createVertexEffects(0,roundCorners);
src/main/java/org/distorted/objectlib/bandaged/FactoryBandagedCuboid.java
136 136
     return new float[][] { {1,0,0},{0,1,0},{0,0,1} };
137 137
     }
138 138

  
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

  
141
  public float sizeCorrection(int[] numLayers)
142
    {
143
    return 1.0f;
144
    }
145

  
139 146
///////////////////////////////////////////////////////////////////////////////////////////////////
140 147

  
141 148
  public int diameterMap(float diameter)
src/main/java/org/distorted/objectlib/bandaged/FactoryBandagedMegaminx.java
1060 1060
            };
1061 1061
    }
1062 1062

  
1063
///////////////////////////////////////////////////////////////////////////////////////////////////
1064

  
1065
  public float sizeCorrection(int[] numLayers)
1066
    {
1067
    switch(numLayers[0])
1068
      {
1069
      case 2: return 2.0f/3;
1070
      case 3: return 3.0f/3;
1071
      case 4: return 4.0f/5;
1072
      case 5: return 5.0f/5;
1073
      }
1074

  
1075
    return 1.0f;
1076
    }
1077

  
1063 1078
///////////////////////////////////////////////////////////////////////////////////////////////////
1064 1079

  
1065 1080
  public int diameterMap(float diameter)
......
1074 1089
  public float[][] getBands(boolean iconMode, int[] numLayers)
1075 1090
    {
1076 1091
    float height= iconMode ? 0.001f : 0.05f;
1077
    int[] angle = {72,55,50,46,42,39,36,34,31,29,27};
1092
    int[] angle = {1,55,50,46,42,39,36,34,31,29,27};
1078 1093
    float R     = 0.5f;
1079 1094
    float S     = 0.5f;
1080 1095
    int extraI  = 0;
......
1082 1097
    int numVertA= numLayers[0]>=4 ? 4 : 5;
1083 1098
    int numVertI= numLayers[0]>=4 ? 2 : 3;
1084 1099

  
1085
    return new float[][] { {  0.001f    ,angle[ 0],R,S,numVertI,extraV,extraI},
1100
    return new float[][] { {0.001f      ,angle[ 0],R,S,numVertI,extraV,extraI},
1086 1101
                           {height      ,angle[ 1],R,S,numVertA,extraV,extraI},
1087 1102
                           {height      ,angle[ 1],R,S,numVertA,extraV,extraI},
1088 1103
                           {height/ 1.5f,angle[ 2],R,S,numVertA,extraV,extraI},
src/main/java/org/distorted/objectlib/bandaged/FactoryBandagedPyraminx.java
220 220
            };
221 221
    }
222 222

  
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224

  
225
  public float sizeCorrection(int[] numLayers)
226
    {
227
    return 1.0f;
228
    }
229

  
223 230
///////////////////////////////////////////////////////////////////////////////////////////////////
224 231

  
225 232
  public int diameterMap(float diameter)

Also available in: Unified diff