Project

General

Profile

« Previous | Next » 

Revision 45aedaa7

Added by Leszek Koltunski 10 months ago

Progress with a generic FactoryBandaged.

View differences:

src/main/java/org/distorted/objectlib/bandaged/FactoryBandaged.java
10 10
package org.distorted.objectlib.bandaged;
11 11

  
12 12
import static org.distorted.objectlib.main.TwistyObject.MESH_NICE;
13
import static org.distorted.objectlib.main.TwistyObject.SQ2;
14
import static org.distorted.objectlib.main.TwistyObject.SQ5;
13 15
import static org.distorted.objectlib.objects.TwistyBandagedCuboid.REGION_SIZE;
14 16
import static org.distorted.objectlib.objects.TwistyBandagedCuboid.STRENGTH;
15 17

  
......
21 23
import org.distorted.objectlib.helpers.ObjectVertexEffects;
22 24

  
23 25
import java.util.ArrayList;
26
import java.util.Collections;
27
import java.util.Comparator;
24 28

  
25 29
///////////////////////////////////////////////////////////////////////////////////////////////////
26 30

  
27 31
abstract public class FactoryBandaged
28 32
  {
33
  private static class BandagedCubitFace
34
    {
35
    private static final float[] sortVect = new float[] { 1/(2*SQ2), SQ2/(2*SQ2), SQ5/(2*SQ2) };
36

  
37
    float[] vertices;
38
    float[] center;
39
    float[] normal;
40
    float centerCast;
41

  
42
    BandagedCubitFace(float[] verts)
43
      {
44
      vertices = verts;
45
      computeCenter();
46
      computeNormal();
47
      computeCenterCast();
48
      }
49

  
50
    private void computeCenter()
51
      {
52
      int num = vertices.length/3;
53
      center = new float[3];
54

  
55
      for(int v=0; v<num; v++)
56
        {
57
        center[0] += vertices[3*v  ];
58
        center[1] += vertices[3*v+1];
59
        center[2] += vertices[3*v+2];
60
        }
61

  
62
      center[0] /= num;
63
      center[1] /= num;
64
      center[2] /= num;
65
      }
66

  
67
    private void computeNormal()
68
      {
69
      normal = new float[3];
70

  
71
      float x1 = vertices[0];
72
      float y1 = vertices[1];
73
      float z1 = vertices[2];
74
      float x2 = vertices[3];
75
      float y2 = vertices[4];
76
      float z2 = vertices[5];
77
      float x3 = vertices[6];
78
      float y3 = vertices[7];
79
      float z3 = vertices[8];
80

  
81
      float v1x = x2-x1;
82
      float v1y = y2-y1;
83
      float v1z = z2-z1;
84
      float v2x = x3-x1;
85
      float v2y = y3-y1;
86
      float v2z = z3-z1;
87

  
88
      normal[0] = v1y*v2z - v2y*v1z;
89
      normal[1] = v1z*v2x - v2z*v1x;
90
      normal[2] = v1x*v2y - v2x*v1y;
91

  
92
      double len = normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2];
93
      len = Math.sqrt(len);
94
      normal[0] /= len;
95
      normal[1] /= len;
96
      normal[2] /= len;
97
      }
98

  
99
    private void computeCenterCast()
100
      {
101
      centerCast = center[0]*sortVect[0] + center[1]*sortVect[1] + center[2]*sortVect[2];
102
      }
103
    }
104

  
105
  static class SortByCenterCast implements Comparator<BandagedCubitFace>
106
    {
107
    public int compare(BandagedCubitFace a, BandagedCubitFace b)
108
      {
109
      float diff = a.centerCast - b.centerCast;
110
      return diff>0 ? 1: diff==0 ? 0: -1;
111
      }
112
    }
113

  
29 114
  private ArrayList<float[]> mTmpArray;
30 115
  private float[] mDist3D;
31 116
  private int[][] mFaceBelongsBitmap;
......
63 148
  abstract float[] getDist3D();
64 149
  abstract float[][] getBands(boolean iconMode);
65 150
  abstract float[][] getCuts(int[] numLayers);
66
  abstract float[] elementVertices(int ax, boolean left, int element);
67
  abstract boolean elementFaceNotNull(int ax, boolean left, int element);
68 151
  abstract int getElementVariant(float x, float y, float z);
69 152
  abstract int diameterMap(float diameter);
153
  abstract float[][] getVertices(int variant);
154
  abstract int[][] getIndices(int variant);
70 155

  
71 156
///////////////////////////////////////////////////////////////////////////////////////////////////
72 157

  
......
335 420
      }
336 421
    }
337 422

  
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

  
340
  boolean elementDoesntExist(int[] p)
341
    {
342
    boolean res;
343

  
344
    for(int i=0; i<mNumElements; i++)
345
      {
346
      int[] row = mElements[i].getRotRow();
347
      res = true;
348

  
349
      for(int j=0; j<mNumAxis; j++)
350
        if( row[j]!=p[j] )
351
          {
352
          res = false;
353
          break;
354
          }
355

  
356
      if( res ) return false;
357
      }
358

  
359
    return true;
360
    }
361

  
362 423
///////////////////////////////////////////////////////////////////////////////////////////////////
363 424

  
364 425
  static boolean vertInFace(float[] vertex, float[] move, Static3D faceAxis, float dist)
......
505 566

  
506 567
///////////////////////////////////////////////////////////////////////////////////////////////////
507 568

  
508
  private boolean elementsFormSection(int e1, int e2, int ax)
569
  private float[] buildFaceVertices(float[][] vertices, int[] indices, float[] pos)
509 570
    {
510
    int[] r1 = mElements[e1].getRotRow();
511
    int[] r2 = mElements[e2].getRotRow();
571
    int num = indices.length;
572
    float[] ret = new float[3*num];
512 573

  
513
    if( r1[ax]==r2[ax] )
574
    for(int i=0; i<num; i++)
514 575
      {
515
      int dist=0;
576
      float[] v = vertices[indices[i]];
577
      ret[3*i  ] = v[0] + pos[0];
578
      ret[3*i+1] = v[1] + pos[1];
579
      ret[3*i+2] = v[2] + pos[2];
580
      }
581

  
582
    return ret;
583
    }
584

  
585
///////////////////////////////////////////////////////////////////////////////////////////////////
516 586

  
517
      for(int i=0; i<mNumAxis; i++)
587
  private void removeInternalWalls(ArrayList<BandagedCubitFace> list)
588
    {
589
    Collections.sort(list,new SortByCenterCast());
590

  
591
    int numElements = list.size();
592
    final float MAXDIFF = 0.01f;
593

  
594
    for(int e=0; e<numElements; e++)
595
      {
596
      int ne = e+1;
597
      BandagedCubitFace f1 = list.get(e);
598
      float[] center = f1.center;
599

  
600
      while( ne<numElements )
518 601
        {
519
        int d=r1[i]-r2[i];
520
        dist+=d*d;
521
        }
602
        BandagedCubitFace f2 = list.get(ne);
603
        float diff = f2.centerCast-f1.centerCast;
522 604

  
523
      return dist==1;
605
        if( diff>-MAXDIFF && diff<MAXDIFF )
606
          {
607
          float[] c = f2.center;
608
          float dx = c[0]-center[0];
609
          float dy = c[1]-center[1];
610
          float dz = c[2]-center[2];
611

  
612
          float d = dx*dx + dy*dy + dz*dz;
613

  
614
          if( d>-MAXDIFF && d<MAXDIFF )
615
            {
616
            list.remove(ne);
617
            list.remove(e);
618
            numElements -= 2;
619
            e--;
620
            break;
621
            }
622
          }
623
        else break;
624

  
625
        ne++;
626
        }
524 627
      }
525
    return false;
526 628
    }
527 629

  
528 630
///////////////////////////////////////////////////////////////////////////////////////////////////
529 631

  
530
  private int computeConnectedSection(int element, int ax, boolean[] walls, int[] output, int index)
632
  private float[][] getNextSection(ArrayList<BandagedCubitFace> list)
531 633
    {
532
    int found = index;
634
    int numElements = list.size();
635
    if( numElements==0 ) return null;
533 636

  
534
    for(int e=0; e<mNumElements; e++)
535
      if( walls[e] && elementsFormSection(element,e,ax) )
637
    final float MAXDIFF = 0.01f;
638
    float[][] ret = new float[numElements][];
639
    BandagedCubitFace bcf = list.remove(0);
640
    float[] normal = bcf.normal;
641
    int removed = 1;
642

  
643
    ret[0] = bcf.vertices;
644

  
645
    for(int e=0; e<numElements-1; e++)
646
      {
647
      BandagedCubitFace f = list.get(e);
648
      float[] n = f.normal;
649

  
650
      float dx = n[0]-normal[0];
651
      float dy = n[1]-normal[1];
652
      float dz = n[2]-normal[2];
653

  
654
      float diff = dx*dx + dy*dy + dz*dz;
655

  
656
      if( diff>-MAXDIFF && diff<MAXDIFF )
536 657
        {
537
        walls[e] = false;
538
        output[found++] = e;
539
        found = computeConnectedSection(e,ax,walls,output,found);
658
        list.remove(e);
659
        e--;
660
        numElements--;
661
        ret[removed++] = f.vertices;
540 662
        }
663
      }
541 664

  
542
    return found;
665
    float[][] ret2 = new float[removed][];
666
    for(int i=0; i<removed; i++) ret2[i] = ret[i];
667

  
668
    return ret2;
543 669
    }
544 670

  
545 671
///////////////////////////////////////////////////////////////////////////////////////////////////
546 672

  
547
  private void buildAllSections(int ax, boolean left, boolean[] walls, ArrayList<float[][]> list)
673
  private boolean isConnected(float[] face1, float[] face2)
548 674
    {
549
    int numElements = 0;
550
    for(int i=0; i<mNumElements; i++)
551
      if( walls[i] ) numElements++;
552

  
553
    int[] tmp = new int[numElements];
675
    float MAXDIFF = 0.01f;
676
    int l1 = face1.length/3;
677
    int l2 = face2.length/3;
554 678

  
555
    while( numElements>0 )
679
    for(int i=0; i<l1; i++)
556 680
      {
557
      int element = 0;
681
      float x = face1[3*i  ];
682
      float y = face1[3*i+1];
683
      float z = face1[3*i+2];
558 684

  
559
      for( ; element<mNumElements; element++)
560
        if( walls[element] )
685
      for(int j=0; j<l2; j++)
686
        {
687
        float dx = x-face2[3*j  ];
688
        float dy = y-face2[3*j+1];
689
        float dz = z-face2[3*j+2];
690

  
691
        if( dx*dx + dy*dy + dz*dz < MAXDIFF )
561 692
          {
562
          walls[element] = false;
563
          tmp[0] = element;
564
          break;
693
          int inext = i==l1-1 ? 0 : i+1;
694
          int jprev = j==0 ? l2-1 : j-1;
695

  
696
          dx = face1[3*inext  ] - face2[3*jprev  ];
697
          dy = face1[3*inext+1] - face2[3*jprev+1];
698
          dz = face1[3*inext+2] - face2[3*jprev+2];
699

  
700
          if( dx*dx + dy*dy + dz*dz < MAXDIFF ) return true;
701

  
702
          int iprev = i==0 ? l1-1 : i-1;
703
          int jnext = j==l2-1 ? 0 : j+1;
704

  
705
          dx = face1[3*iprev  ] - face2[3*jnext  ];
706
          dy = face1[3*iprev+1] - face2[3*jnext+1];
707
          dz = face1[3*iprev+2] - face2[3*jnext+2];
708

  
709
          return dx*dx + dy*dy + dz*dz < MAXDIFF;
565 710
          }
711
        }
712
      }
566 713

  
567
      int elementsInSection = computeConnectedSection(element, ax, walls, tmp, 1);
568
      float[][] newSection = new float[elementsInSection][];
714
    return false;
715
    }
569 716

  
570
      for(int i=0; i<elementsInSection; i++)
571
        newSection[i] = elementVertices(ax, left, tmp[i]);
717
///////////////////////////////////////////////////////////////////////////////////////////////////
572 718

  
573
      list.add(newSection);
719
  private float[][] getNextConnected(float[][] section, int nonNull)
720
    {
721
    float[][] ret = new float[nonNull][];
722
    int start,len = section.length;
723

  
724
    for(start=0; start<len; start++)
725
      if( section[start]!=null )
726
        {
727
        ret[0] = section[start];
728
        section[start] = null;
729
        break;
730
        }
731

  
732
    int current = 0;
733
    int last = start;
734

  
735
    do
736
      {
737
      start++;
574 738

  
575
      numElements -= elementsInSection;
739
      for(int i=start; i<len; i++)
740
        if( section[i]!=null && isConnected(ret[current],section[i]) )
741
          {
742
          last++;
743
          current++;
744
          ret[current] = section[i];
745
          section[i] = null;
746
          }
576 747
      }
748
    while(last>start);
749

  
750
    float[][] ret2 = new float[current+1][];
751
    for(int i=0; i<=current; i++) ret2[i] = ret[i];
752

  
753
    return ret2;
577 754
    }
578 755

  
579 756
///////////////////////////////////////////////////////////////////////////////////////////////////
580 757

  
581 758
  private void fillUpVertexArray()
582 759
    {
583
    boolean[][][] walls = new boolean[mNumAxis][2][mNumElements];
584

  
585
    int[] tmp = new int[mNumAxis];
760
    ArrayList<BandagedCubitFace> list = new ArrayList<>();
586 761

  
587 762
    for(int e=0; e<mNumElements; e++)
588 763
      {
589
      int[] row = mElements[e].getRotRow();
590
      for(int t=0; t<mNumAxis; t++) tmp[t]=row[t];
764
      int variant = mElements[e].getVariant();
765
      float[][] verts = getVertices(variant);
766
      int[][] inds = getIndices(variant);
767
      float[] pos = mElements[e].getPos();
591 768

  
592
      for(int a=0; a<mNumAxis; a++)
769
      for( int[] ind : inds)
593 770
        {
594
        tmp[a] = row[a]+1;
595
        walls[a][0][e] = (elementDoesntExist(tmp) && elementFaceNotNull(a,true ,e));
596
        tmp[a] = row[a]-1;
597
        walls[a][1][e] = (elementDoesntExist(tmp) && elementFaceNotNull(a,false,e));
598
        tmp[a] = row[a];
771
        float[] vertices = buildFaceVertices(verts,ind,pos);
772
        BandagedCubitFace face = new BandagedCubitFace(vertices);
773
        list.add(face);
599 774
        }
600 775
      }
601 776

  
602
    for(int a=0; a<mNumAxis; a++)
777
    removeInternalWalls(list);
778

  
779
    while(true)
603 780
      {
604
      buildAllSections(a, true,  walls[a][0], mVertexArray );
605
      buildAllSections(a, false, walls[a][1], mVertexArray );
781
      float[][] section = getNextSection(list);
782

  
783
      if( section!=null )
784
        {
785
        int nonNull = section.length;
786

  
787
        while(nonNull>0)
788
          {
789
          float[][] connected = getNextConnected(section,nonNull);
790
          nonNull -= connected.length;
791
          mVertexArray.add(connected);
792
          }
793
        }
794
      else break;
606 795
      }
607 796
    }
608 797

  

Also available in: Unified diff