Advertisement
Guest User

Untitled

a guest
Jul 27th, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.54 KB | None | 0 0
  1.     public class MeshDataBuilder<VT> where VT : IVertex
  2.     {
  3.         public float MergeTolerance { get; set; }
  4.  
  5.         public List<VT> Vertices { get; private set; }
  6.         public List<UInt32> Indices { get; private set; }
  7.         public bool ClockwiseOrder { get; set; }
  8.  
  9.         private int smoothingVertexStart = 0;
  10.         private int smoothingIndexStart = 0;
  11.         private bool smoothEnabled = false;
  12.  
  13.         public MeshDataBuilder()
  14.         {
  15.             this.MergeTolerance = 0.00001f;
  16.             this.Vertices = new List<VT>();
  17.             this.Indices = new List<UInt32>();
  18.             this.ClockwiseOrder = false;
  19.         }
  20.  
  21.         public void Begin()
  22.         {
  23.             this.Vertices.Clear();
  24.             this.Indices.Clear();
  25.  
  26.             smoothingVertexStart = 0;
  27.             smoothingIndexStart = 0;
  28.             smoothEnabled = false;
  29.         }
  30.  
  31.         public void End()
  32.         {
  33.             FinishSmoothingGroup();
  34.         }
  35.        
  36.         public void NewSmoothingGroup(bool smooth)
  37.         {
  38.             if (smoothingVertexStart > 0)
  39.                 FinishSmoothingGroup();
  40.  
  41.             smoothingVertexStart = Vertices.Count();
  42.             smoothingIndexStart = Indices.Count();
  43.             smoothEnabled = smooth;
  44.         }
  45.  
  46.         struct SortedVertexInfo: IComparable<SortedVertexInfo>
  47.         {
  48.             public int Index;
  49.             public int NewIndex;
  50.             public int PreviousRemoveCounter;
  51.             public float LengthSquared;
  52.             public Vector3 Position;
  53.             public bool Removed;
  54.  
  55.             public int CompareTo(SortedVertexInfo other)
  56.             {
  57.                 if (other.LengthSquared == LengthSquared) return 0;
  58.                 return other.LengthSquared < LengthSquared ? -1 : 1;
  59.             }
  60.         };
  61.  
  62.         private void RemoveDuplicateVertices()
  63.         {
  64.             int verticesCount = this.Vertices.Count - smoothingVertexStart;
  65.             int indicesCount = this.Indices.Count - smoothingIndexStart;
  66.  
  67.             SortedVertexInfo[] sortedVertices = new SortedVertexInfo[verticesCount];
  68.             for (int i = 0; i < verticesCount; ++i)
  69.             {
  70.                 Vector3 pos = this.Vertices[i].GetPosition();
  71.  
  72.                 sortedVertices[i].Index = i;
  73.                 sortedVertices[i].NewIndex = sortedVertices[i].Index;
  74.                 sortedVertices[i].Position = pos;
  75.                 sortedVertices[i].LengthSquared = pos.LengthSquared();
  76.                 sortedVertices[i].Removed = false;
  77.                 sortedVertices[i].PreviousRemoveCounter = 0;
  78.             }
  79.  
  80.             Array.Sort<SortedVertexInfo>(sortedVertices);
  81.  
  82.             int removeCounter = 0;
  83.  
  84.             int vi = 0;
  85.             while (vi < verticesCount)
  86.             {
  87.                 int newIndex = sortedVertices[vi].Index;
  88.                 Vector3 comparedPosition = sortedVertices[vi].Position;
  89.                 float comparedLength = sortedVertices[vi].LengthSquared;
  90.  
  91.                 ++vi;
  92.  
  93.                 int vj = vi;
  94.                 while (vj < verticesCount && sortedVertices[vj].LengthSquared == comparedLength)
  95.                 {
  96.                     SortedVertexInfo svi = sortedVertices[vj];
  97.  
  98.                     if (!svi.Removed && svi.Position == comparedPosition)
  99.                     {
  100.                         svi.Removed = true;
  101.                         svi.NewIndex = newIndex;
  102.                         sortedVertices[vj] = svi;
  103.  
  104.                         ++removeCounter;
  105.                     }
  106.  
  107.                     ++vj;
  108.                 }
  109.             }
  110.  
  111.             Console.WriteLine(removeCounter.ToString());
  112.  
  113.             Array.Sort<SortedVertexInfo>(sortedVertices, delegate(SortedVertexInfo v1, SortedVertexInfo v2)
  114.             {
  115.                 return v1.Index - v2.Index;
  116.             });
  117.  
  118.             int previousRemoveCounter = 0;
  119.             for (int i = 0; i < verticesCount; ++i)
  120.             {
  121.                 sortedVertices[i].PreviousRemoveCounter = previousRemoveCounter;
  122.  
  123.                 if (sortedVertices[i].Removed)
  124.                     ++previousRemoveCounter;
  125.             }
  126.  
  127.             for (int i = 0; i < indicesCount; ++i)
  128.             {
  129.                 int ind = (int)this.Indices[i] - smoothingVertexStart;
  130.  
  131.                 if (sortedVertices[ind].Removed)
  132.                     ind = sortedVertices[ind].NewIndex;
  133.  
  134.                 this.Indices[i] = (UInt32)(ind - sortedVertices[ind].PreviousRemoveCounter + smoothingVertexStart);
  135.             }
  136.  
  137.             List<VT> newVertices = new List<VT>();
  138.  
  139.             foreach (SortedVertexInfo svi in sortedVertices)
  140.             {
  141.                 if (!svi.Removed)
  142.                     newVertices.Add(this.Vertices[svi.Index + smoothingVertexStart]);
  143.             }
  144.  
  145.             this.Vertices.RemoveRange(smoothingVertexStart, verticesCount);
  146.             this.Vertices.AddRange(newVertices);
  147.         }
  148.  
  149.         private int AddVertex(VT vertex)
  150.         {
  151.             this.Vertices.Add(vertex);
  152.             return this.Vertices.Count - 1;
  153.         }
  154.  
  155.         public void AddTriangle(VT vertex1, VT vertex2, VT vertex3)
  156.         {
  157.             UInt32 i1 = (UInt32)AddVertex(vertex1);
  158.             UInt32 i2 = (UInt32)AddVertex(vertex2);
  159.             UInt32 i3 = (UInt32)AddVertex(vertex3);
  160.  
  161.             if (this.ClockwiseOrder)
  162.             {
  163.                 this.Indices.Add(i1);
  164.                 this.Indices.Add(i2);
  165.                 this.Indices.Add(i3);
  166.             }
  167.             else
  168.             {
  169.                 this.Indices.Add(i1);
  170.                 this.Indices.Add(i3);
  171.                 this.Indices.Add(i2);
  172.             }
  173.         }
  174.  
  175.         public void AddQuad(VT vertex1, VT vertex2, VT vertex3, VT vertex4)
  176.         {
  177.             UInt32 i1 = (UInt32)AddVertex(vertex1);
  178.             UInt32 i2 = (UInt32)AddVertex(vertex2);
  179.             UInt32 i3 = (UInt32)AddVertex(vertex3);
  180.             UInt32 i4 = (UInt32)AddVertex(vertex4);
  181.  
  182.             if (this.ClockwiseOrder)
  183.             {
  184.                 this.Indices.Add(i1);
  185.                 this.Indices.Add(i2);
  186.                 this.Indices.Add(i4);
  187.  
  188.                 this.Indices.Add(i2);
  189.                 this.Indices.Add(i3);
  190.                 this.Indices.Add(i4);
  191.             }
  192.             else
  193.             {
  194.                 this.Indices.Add(i1);
  195.                 this.Indices.Add(i4);
  196.                 this.Indices.Add(i2);
  197.  
  198.                 this.Indices.Add(i2);
  199.                 this.Indices.Add(i4);
  200.                 this.Indices.Add(i3);
  201.             }
  202.         }
  203.  
  204.         private void FinishSmoothingGroup()
  205.         {
  206.             if (smoothEnabled)
  207.             {
  208.                 RemoveDuplicateVertices();
  209.  
  210.                 for (int i = smoothingIndexStart; i < this.Indices.Count; i += 3)
  211.                 {
  212.                     Vector3 p1 = this.Vertices[(int)this.Indices[i]].GetPosition();
  213.                     Vector3 p2 = this.Vertices[(int)this.Indices[i + 1]].GetPosition();
  214.                     Vector3 p3 = this.Vertices[(int)this.Indices[i + 2]].GetPosition();
  215.  
  216.                     Vector3 faceNormal = Vector3.Cross(p3 - p1, p2 - p1);
  217.                     faceNormal.Normalize();
  218.  
  219.                     for (int j = 0; j < 3; ++j)
  220.                     {
  221.                         VT vertex = this.Vertices[(int)this.Indices[i + j]];
  222.                         vertex.SetNormal(vertex.GetNormal() + faceNormal);
  223.                         this.Vertices[(int)this.Indices[i + j]] = vertex;
  224.                     }
  225.                 }
  226.  
  227.                 for (int i = smoothingVertexStart; i < this.Vertices.Count; ++i)
  228.                 {
  229.                     VT vertex = this.Vertices[i];
  230.                     Vector3 normal = vertex.GetNormal();
  231.                     normal.Normalize();
  232.                     vertex.SetNormal(normal);
  233.                     this.Vertices[i] = vertex;
  234.                 }
  235.             }
  236.             else
  237.             {
  238.                 for (int i = smoothingIndexStart; i < this.Indices.Count; i += 3)
  239.                 {
  240.                     Vector3 p1 = this.Vertices[(int)this.Indices[i]].GetPosition();
  241.                     Vector3 p2 = this.Vertices[(int)this.Indices[i + 1]].GetPosition();
  242.                     Vector3 p3 = this.Vertices[(int)this.Indices[i + 2]].GetPosition();
  243.  
  244.                     Vector3 faceNormal = Vector3.Cross(p3 - p1, p2 - p1);
  245.                     faceNormal.Normalize();
  246.  
  247.                     for (int j = 0; j < 3; ++j)
  248.                     {
  249.                         VT vertex = this.Vertices[(int)this.Indices[i + j]];
  250.                         vertex.SetNormal(faceNormal);
  251.                         this.Vertices[(int)this.Indices[i + j]] = vertex;
  252.                     }
  253.                 }
  254.             }
  255.         }
  256.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement