Project

General

Profile

« Previous | Next » 

Revision 6983badf

Added by Leszek Koltunski about 3 years ago

Port bugfixes from DistortedCube; add Ivy Corner & Ivy Face meshes.

View differences:

src/main/java/org/distorted/examples/meshfile/FactoryCubit.java
47 47

  
48 48
  private static FactoryCubit mThis;
49 49

  
50
  private static class StickerInfo
50
  private static class StickerCoords
51 51
    {
52 52
    double[] vertices;
53 53
    }
54 54

  
55
  private static class FaceInfo
55
  private static class FaceTransform
56 56
    {
57 57
    int sticker;
58 58
    double vx,vy,vz;
......
61 61
    boolean flip;
62 62
    }
63 63

  
64
  private static final ArrayList<FaceInfo>       mFaceInfo = new ArrayList<>();
65
  private static final ArrayList<StickerInfo> mStickerInfo = new ArrayList<>();
64
  private static final ArrayList<FaceTransform> mNewFaceTransf = new ArrayList<>();
65
  private static final ArrayList<FaceTransform> mOldFaceTransf = new ArrayList<>();
66
  private static final ArrayList<StickerCoords> mStickerCoords = new ArrayList<>();
67

  
66 68

  
67 69
///////////////////////////////////////////////////////////////////////////////////////////////////
68 70

  
......
290 292

  
291 293
///////////////////////////////////////////////////////////////////////////////////////////////////
292 294

  
293
  private void fitInSquare(FaceInfo info, double[][] vert3D)
295
  private void fitInSquare(FaceTransform info, double[][] vert3D)
294 296
    {
295 297
    double minX = Double.MAX_VALUE;
296 298
    double maxX =-Double.MAX_VALUE;
......
320 322
    info.scale = max3/0.5;
321 323

  
322 324
    int len = vert3D.length;
323
    StickerInfo sInfo = new StickerInfo();
325
    StickerCoords sInfo = new StickerCoords();
324 326
    sInfo.vertices = new double[2*len];
325 327

  
326 328
    for( int vertex=0; vertex<len; vertex++ )
......
329 331
      sInfo.vertices[2*vertex+1] = vert3D[vertex][1] / info.scale;
330 332
      }
331 333

  
332
    mStickerInfo.add(sInfo);
334
    mStickerCoords.add(sInfo);
333 335

  
334
    info.sticker = mStickerInfo.size() -1;
336
    info.sticker = mStickerCoords.size() -1;
335 337
    info.flip = false;
336 338
    }
337 339

  
338 340
///////////////////////////////////////////////////////////////////////////////////////////////////
339 341

  
340
  private void constructNew(FaceInfo info, final double[][] vert3D)
342
  private FaceTransform constructNewTransform(final double[][] vert3D)
341 343
    {
344
    FaceTransform ft = new FaceTransform();
345

  
342 346
    // compute center of gravity
343
    info.vx = 0.0f;
344
    info.vy = 0.0f;
345
    info.vz = 0.0f;
347
    ft.vx = 0.0f;
348
    ft.vy = 0.0f;
349
    ft.vz = 0.0f;
346 350
    int len = vert3D.length;
347 351

  
348 352
    for (double[] vert : vert3D)
349 353
      {
350
      info.vx += vert[0];
351
      info.vy += vert[1];
352
      info.vz += vert[2];
354
      ft.vx += vert[0];
355
      ft.vy += vert[1];
356
      ft.vz += vert[2];
353 357
      }
354 358

  
355
    info.vx /= len;
356
    info.vy /= len;
357
    info.vz /= len;
359
    ft.vx /= len;
360
    ft.vy /= len;
361
    ft.vz /= len;
358 362

  
359 363
    // move all vertices so that their center of gravity is at (0,0,0)
360 364
    for (int i=0; i<len; i++)
361 365
      {
362
      vert3D[i][0] -= info.vx;
363
      vert3D[i][1] -= info.vy;
364
      vert3D[i][2] -= info.vz;
366
      vert3D[i][0] -= ft.vx;
367
      vert3D[i][1] -= ft.vy;
368
      vert3D[i][2] -= ft.vz;
365 369
      }
366 370

  
367 371
    // find 3 non-colinear vertices
......
427 431
      }
428 432

  
429 433
    // fit the whole thing in a square and remember the scale & 2D vertices
430
    fitInSquare(info, vert3D);
434
    fitInSquare(ft, vert3D);
431 435

  
432 436
    // remember the rotation
433
    info.qx =-mQuat1[0];
434
    info.qy =-mQuat1[1];
435
    info.qz =-mQuat1[2];
436
    info.qw = mQuat1[3];
437
    ft.qx =-mQuat1[0];
438
    ft.qy =-mQuat1[1];
439
    ft.qz =-mQuat1[2];
440
    ft.qw = mQuat1[3];
441

  
442
    return ft;
437 443
    }
438 444

  
439 445
///////////////////////////////////////////////////////////////////////////////////////////////////
......
472 478

  
473 479
///////////////////////////////////////////////////////////////////////////////////////////////////
474 480

  
475
  private double computeScale(double[] v1, double[] v2)
481
  private double computeScale(double[] v1, double[] v2, int v1i, int v2i)
476 482
    {
477
    double lenSq1 = v1[0]*v1[0] + v1[1]*v1[1];
478
    double lenSq2 = v2[0]*v2[0] + v2[1]*v2[1];
483
    double v1x = v1[2*v1i];
484
    double v1y = v1[2*v1i+1];
485
    double v2x = v2[2*v2i];
486
    double v2y = v2[2*v2i+1];
487

  
488
    double lenSq1 = v1x*v1x + v1y*v1y;
489
    double lenSq2 = v2x*v2x + v2y*v2y;
479 490

  
480 491
    return Math.sqrt(lenSq2/lenSq1);
481 492
    }
482 493

  
483 494
///////////////////////////////////////////////////////////////////////////////////////////////////
495
// valid for 0<angle<2*PI
484 496

  
485 497
  private double computeSinHalf(double cos)
486 498
    {
......
488 500
    }
489 501

  
490 502
///////////////////////////////////////////////////////////////////////////////////////////////////
503
// valid for 0<angle<2*PI
491 504

  
492 505
  private double computeCosHalf(double sin, double cos)
493 506
    {
......
510 523

  
511 524
  private boolean isScaledVersionOf(double[] newVert, double[] oldVert, int len, int vertex, boolean inverted)
512 525
    {
526
    int newZeroIndex = computeRotatedIndex(0,len,vertex,inverted);
513 527
    double EPSILON = 0.001;
514
    double scale = computeScale(newVert,oldVert);
528
    double scale = computeScale(newVert,oldVert,newZeroIndex,0);
515 529

  
516 530
    for(int i=1; i<len; i++)
517 531
      {
......
539 553

  
540 554
///////////////////////////////////////////////////////////////////////////////////////////////////
541 555

  
542
  private void correctInfo(FaceInfo info, double scale, double sin, double cos, int oldSticker, boolean flip)
556
  private void correctTransform(FaceTransform ft, double scale, double sin, double cos, int oldSticker, boolean flip)
543 557
    {
544
    mStickerInfo.remove(info.sticker);
558
    mStickerCoords.remove(ft.sticker);
545 559

  
546
    info.flip    = flip;
547
    info.sticker = oldSticker;
548
    info.scale  *= scale;
560
    ft.flip    = flip;
561
    ft.sticker = oldSticker;
562
    ft.scale  *= scale;
549 563

  
550
    mQuat1[0] = info.qx;
551
    mQuat1[1] = info.qy;
552
    mQuat1[2] = info.qz;
553
    mQuat1[3] = info.qw;
564
    mQuat1[0] = ft.qx;
565
    mQuat1[1] = ft.qy;
566
    mQuat1[2] = ft.qz;
567
    mQuat1[3] = ft.qw;
554 568

  
555 569
    double sinHalf = computeSinHalf(cos);
556 570
    double cosHalf = computeCosHalf(sin,cos);
......
579 593

  
580 594
    quatMultiply( mQuat1, mQuat2, mQuat3 );
581 595

  
582
    info.qx = mQuat3[0];
583
    info.qy = mQuat3[1];
584
    info.qz = mQuat3[2];
585
    info.qw = mQuat3[3];
596
    ft.qx = mQuat3[0];
597
    ft.qy = mQuat3[1];
598
    ft.qz = mQuat3[2];
599
    ft.qw = mQuat3[3];
586 600
    }
587 601

  
588 602
///////////////////////////////////////////////////////////////////////////////////////////////////
......
602 616

  
603 617
///////////////////////////////////////////////////////////////////////////////////////////////////
604 618

  
605
  private boolean foundVertex(FaceInfo info, double[] buffer, int len, double[] newVert,
619
  private boolean foundVertex(FaceTransform ft, double[] buffer, int len, double[] newVert,
606 620
                              double[] oldVert, double lenFirstOld, int oldSticker, boolean inverted)
607 621
    {
608 622
    for(int vertex=0; vertex<len; vertex++)
......
617 631

  
618 632
      if( isScaledVersionOf(buffer,oldVert,len,vertex,inverted) )
619 633
        {
620
        double scale = computeScale(oldVert,newVert);
621
        correctInfo(info,scale,sin,cos,oldSticker,inverted);
634
        int newZeroIndex = computeRotatedIndex(0,len,vertex,inverted);
635
        double scale = computeScale(oldVert,newVert,0,newZeroIndex);
636
        correctTransform(ft,scale,sin,cos,oldSticker,inverted);
622 637
        return true;
623 638
        }
624 639
      }
......
628 643

  
629 644
///////////////////////////////////////////////////////////////////////////////////////////////////
630 645

  
631
  private boolean successfullyCollapsedStickers(final FaceInfo newInfo, final FaceInfo oldInfo)
646
  private boolean successfullyCollapsedStickers(final FaceTransform newInfo, final FaceTransform oldInfo)
632 647
    {
633
    StickerInfo sNewInfo = mStickerInfo.get(newInfo.sticker);
634
    StickerInfo sOldInfo = mStickerInfo.get(oldInfo.sticker);
648
    StickerCoords sNewInfo = mStickerCoords.get(newInfo.sticker);
649
    StickerCoords sOldInfo = mStickerCoords.get(oldInfo.sticker);
635 650
    double[] newVert = sNewInfo.vertices;
636 651
    double[] oldVert = sOldInfo.vertices;
637 652
    int oldLen = oldVert.length;
......
671 686

  
672 687
///////////////////////////////////////////////////////////////////////////////////////////////////
673 688

  
674
  private void prepareFaceInfo( final double[][] vertices, final int[][] indexes)
675
    {
676
    mFaceInfo.clear();
677
    mStickerInfo.clear();
678

  
679
    int numFaces = indexes.length;
680
    FaceInfo oldInfo;
681

  
682
    for(int face=0; face<numFaces; face++)
683
      {
684
      FaceInfo newInfo = new FaceInfo();
685
      int[] index = indexes[face];
686
      double[][] vert = constructVert(vertices,index);
687
      constructNew(newInfo,vert);
688

  
689
      for(int previous=0; previous<face; previous++)
690
        {
691
        oldInfo = mFaceInfo.get(previous);
692
        if( successfullyCollapsedStickers(newInfo,oldInfo) ) break;
693
        }
694

  
695
      mFaceInfo.add(newInfo);
696
      }
697
    }
698

  
699
///////////////////////////////////////////////////////////////////////////////////////////////////
700

  
701
  private void prepareAndRoundCorners(MeshBase mesh, double[][] vertices, int[][] vertIndexes,
702
                                      float[][] corners, int[] cornerIndexes )
689
  private void prepareAndRoundCorners(MeshBase mesh, double[][] vertices,
690
                                      float[][] corners, int[] cornerIndexes,
691
                                      float[][] centers, int[] centerIndexes )
703 692
    {
704
    int numNeig, lenFV;
705 693
    int lenV = vertices.length;
706
    int[] verts = new int[2*(lenV-1)];
707 694
    Static3D[] staticVert = new Static3D[1];
708 695
    Static3D center = new Static3D(0,0,0);
709
    double cx, cy, cz;
710
    double[] singleV;
711 696

  
712 697
    for(int v=0; v<lenV; v++)
713 698
      {
714
      // prepare verts[]
715
      numNeig = 0;
699
      staticVert[0] = new Static3D( (float)vertices[v][0], (float)vertices[v][1], (float)vertices[v][2]);
716 700

  
717
      for (int[] vertIndex : vertIndexes)
701
      int cent = centerIndexes[v];
702

  
703
      if( cent>=0 )
718 704
        {
719
        lenFV = vertIndex.length;
705
        center.set( centers[cent][0], centers[cent][1], centers[cent][2]);
720 706

  
721
        for (int fv = 0; fv < lenFV; fv++)
722
          if (vertIndex[fv] == v)
723
            {
724
            int prev = fv > 0 ? fv - 1 : lenFV - 1;
725
            int next = fv < lenFV - 1 ? fv + 1 : 0;
707
        int corn = cornerIndexes[v];
708
        float strength = corners[corn][0];
709
        float radius   = corners[corn][1];
726 710

  
727
            verts[numNeig++] = vertIndex[prev];
728
            verts[numNeig++] = vertIndex[next];
729
            }
711
        roundCorners(mesh, center, staticVert, strength, radius);
730 712
        }
713
      }
714
    }
731 715

  
732
      cx=cy=cz=0.0f;
716
///////////////////////////////////////////////////////////////////////////////////////////////////
733 717

  
734
      // from verts[] prepare center
735
      for(int n=0; n<numNeig; n++)
736
        {
737
        singleV = vertices[verts[n]];
718
  private void correctComponents(MeshBase mesh, int numComponents)
719
    {
720
    int numTexToBeAdded = numComponents-mesh.getNumTexComponents();
738 721

  
739
        cx += singleV[0];
740
        cy += singleV[1];
741
        cz += singleV[2];
742
        }
743
      center.set( (float)(cx/numNeig - vertices[v][0]),
744
                  (float)(cy/numNeig - vertices[v][1]),
745
                  (float)(cz/numNeig - vertices[v][2]));
722
    //mesh.mergeEffComponents();
746 723

  
747
      // round Corners
748
      staticVert[0] = new Static3D( (float)vertices[v][0], (float)vertices[v][1], (float)vertices[v][2]);
724
    for(int i=0; i<numTexToBeAdded; i++ ) mesh.addEmptyTexComponent();
725
    }
749 726

  
750
      int corn = cornerIndexes[v];
751
      float strength = corners[corn][0];
752
      float radius   = corners[corn][1];
727
///////////////////////////////////////////////////////////////////////////////////////////////////
753 728

  
754
      roundCorners(mesh, center, staticVert, strength, radius);
755
      }
729
  private void printTransform(FaceTransform f)
730
    {
731
    android.util.Log.e("D", "q=("+f.qx+", "+f.qy+", "+f.qz+", "+f.qw+") v=("
732
                       +f.vx+", "+f.vy+", "+f.vz+") scale="+f.scale+" sticker="+f.sticker);
756 733
    }
757 734

  
758 735
///////////////////////////////////////////////////////////////////////////////////////////////////
736
// PUBLIC
759 737

  
760
  private void printInfo()
738
  public void printStickerCoords()
761 739
    {
762
    int stickers = mStickerInfo.size();
740
    int stickers = mStickerCoords.size();
763 741

  
764
    android.util.Log.d("D", "-------------------------");
742
    android.util.Log.d("D", "---- STICKER COORDS ----");
765 743

  
766 744
    for(int s=0; s<stickers; s++)
767 745
      {
768
      String ver = "";
769
      StickerInfo info = mStickerInfo.get(s);
746
      String ver = "{ ";
747
      StickerCoords info = mStickerCoords.get(s);
770 748
      int len = info.vertices.length/2;
771 749

  
772 750
      for(int i =0; i<len; i++)
773 751
        {
774
        ver += ("("+info.vertices[2*i]+","+info.vertices[2*i+1]+") ");
752
        if( i!=0 ) ver += ", ";
753
        ver += ( (float)info.vertices[2*i]+"f, "+(float)info.vertices[2*i+1]+"f");
775 754
        }
776 755

  
777
      android.util.Log.e("D", "sticker "+s+" "+ver);
756
      ver += " }";
757
      android.util.Log.d("D", ver);
778 758
      }
779 759

  
780
    android.util.Log.d("D", "-------------------------");
760
    android.util.Log.d("D", "---- END STICKER COORDS ----");
761
    }
762

  
763
///////////////////////////////////////////////////////////////////////////////////////////////////
764

  
765
  public void printFaceTransform()
766
    {
767
    android.util.Log.d("D", "---- OLD FACE TRANSFORM ---");
781 768

  
782
    int faces = mFaceInfo.size();
769
    int oldfaces = mOldFaceTransf.size();
783 770

  
784
    for(int f=0; f<faces; f++)
771
    for(int f=0; f<oldfaces; f++)
785 772
      {
786
      FaceInfo info = mFaceInfo.get(f);
773
      printTransform(mOldFaceTransf.get(f));
774
      }
775

  
776
    android.util.Log.d("D", "---- NEW FACE TRANSFORM ---");
787 777

  
788
      android.util.Log.e("D", "q=("+info.qx+", "+info.qy+", "+info.qz+", "+info.qw+") v=("
789
                       +info.vx+", "+info.vy+", "+info.vz+") scale="+info.scale+" sticker="+info.sticker);
778
    int newfaces = mNewFaceTransf.size();
779

  
780
    for(int f=0; f<newfaces; f++)
781
      {
782
      printTransform(mNewFaceTransf.get(f));
790 783
      }
784
    }
791 785

  
792
    android.util.Log.d("D", "-------------------------");
786
///////////////////////////////////////////////////////////////////////////////////////////////////
787

  
788
  public void clear()
789
    {
790
    mStickerCoords.clear();
791
    mNewFaceTransf.clear();
792
    mOldFaceTransf.clear();
793 793
    }
794 794

  
795 795
///////////////////////////////////////////////////////////////////////////////////////////////////
796 796

  
797
  MeshBase createRoundedSolid(final double[][] vertices, final int[][] vertIndexes,
798
                              final float[][] bands    , final int[]   bandIndexes,
799
                              final float[][] corners  , final int[]   cornerIndexes)
797
  public void createNewFaceTransform( final double[][] vertices, final int[][] indexes)
800 798
    {
801
    prepareFaceInfo(vertices,vertIndexes);
799
    FaceTransform ft;
800
    int numNew = mNewFaceTransf.size();
801

  
802
    for(int i=0; i<numNew; i++)
803
      {
804
      ft = mNewFaceTransf.remove(0);
805
      mOldFaceTransf.add(ft);
806
      }
807

  
808
    int numFaces = indexes.length;
809
    int numOld = mOldFaceTransf.size();
810

  
811
    for (int face=0; face<numFaces; face++)
812
      {
813
      boolean collapsed = false;
814

  
815
      double[][] vert = constructVert(vertices, indexes[face]);
816

  
817
      FaceTransform newT = constructNewTransform(vert);
818

  
819
      for (int old=0; !collapsed && old<numOld; old++)
820
        {
821
        ft = mOldFaceTransf.get(old);
822
        if (successfullyCollapsedStickers(newT, ft)) collapsed = true;
823
        }
824

  
825
      for (int pre=0; !collapsed && pre<face; pre++)
826
        {
827
        ft = mNewFaceTransf.get(pre);
828
        if (successfullyCollapsedStickers(newT, ft)) collapsed = true;
829
        }
802 830

  
831
      mNewFaceTransf.add(newT);
832
      }
833
    }
834

  
835
///////////////////////////////////////////////////////////////////////////////////////////////////
836

  
837
  public MeshBase createRoundedSolid(final double[][] vertices, final int[][] vertIndexes,
838
                                     final float[][] bands    , final int[]   bandIndexes,
839
                                     final float[][] corners  , final int[]   cornerIndexes,
840
                                     final float[][] centers  , final int[]   centerIndexes,
841
                                     final int numComponents )
842
    {
803 843
    int numFaces = vertIndexes.length;
804 844
    float[] band, bandsComputed;
805 845
    MeshBase[] meshes = new MeshBase[numFaces];
806
    FaceInfo fInfo;
807
    StickerInfo sInfo;
808

  
809
    printInfo();
846
    FaceTransform fInfo;
847
    StickerCoords sInfo;
810 848

  
811 849
    for(int face=0; face<numFaces; face++)
812 850
      {
813
      fInfo = mFaceInfo.get(face);
814
      sInfo = mStickerInfo.get(fInfo.sticker);
851
      fInfo = mNewFaceTransf.get(face);
852
      sInfo = mStickerCoords.get(fInfo.sticker);
815 853

  
816 854
      double[] verts = sInfo.vertices;
817 855
      int lenVerts = verts.length;
......
830 868
    for(int face=0; face<numFaces; face++)
831 869
      {
832 870
      int assoc = (1<<face);
833
      fInfo = mFaceInfo.get(face);
871
      fInfo = mNewFaceTransf.get(face);
834 872

  
835 873
      float vx = (float)fInfo.vx;
836 874
      float vy = (float)fInfo.vy;
......
850 888
      mesh.apply(new MatrixEffectMove(move3D)           ,assoc,-1);
851 889
      }
852 890

  
853
    prepareAndRoundCorners(mesh, vertices, vertIndexes, corners, cornerIndexes);
891
    prepareAndRoundCorners(mesh, vertices, corners, cornerIndexes, centers, centerIndexes);
892

  
893
    correctComponents(mesh,numComponents);
854 894

  
855 895
    return mesh;
856 896
    }

Also available in: Unified diff