388 lines
14 KiB
C#
388 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ProBuilder2.Common;
|
|
using UnityEngine;
|
|
|
|
namespace ProBuilder2.MeshOperations
|
|
{
|
|
// Token: 0x02000006 RID: 6
|
|
public static class pbVertexOps
|
|
{
|
|
// Token: 0x06000047 RID: 71 RVA: 0x00007250 File Offset: 0x00005650
|
|
public static bool MergeVertices(this pb_Object pb, int[] indices, out int collapsedIndex, bool collapseToFirst = false)
|
|
{
|
|
pb_Vertex[] vertices = pb_Vertex.GetVertices(pb, null);
|
|
pb_Vertex pb_Vertex = ((!collapseToFirst) ? pb_Vertex.Average(vertices, indices) : vertices[indices[0]]);
|
|
pb_IntArray[] sharedIndices = pb.sharedIndices;
|
|
pb_IntArray[] sharedIndicesUV = pb.sharedIndicesUV;
|
|
int num = pb_IntArrayUtility.MergeSharedIndices(ref sharedIndices, indices);
|
|
pb_IntArrayUtility.MergeSharedIndices(ref sharedIndicesUV, indices);
|
|
pb.SetSharedIndices(sharedIndices);
|
|
pb.SetSharedIndicesUV(sharedIndicesUV);
|
|
pb.SetSharedVertexValues(num, pb_Vertex);
|
|
int[] array = pb.GetSharedIndices()[num].array;
|
|
int[] array2;
|
|
pb.RemoveDegenerateTriangles(out array2);
|
|
int num2 = -1;
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (!array2.Contains(array[i]))
|
|
{
|
|
num2 = array[i];
|
|
}
|
|
}
|
|
int num3 = num2;
|
|
for (int j = 0; j < array2.Length; j++)
|
|
{
|
|
if (num2 > array2[j])
|
|
{
|
|
num3--;
|
|
}
|
|
}
|
|
if (num3 > -1)
|
|
{
|
|
collapsedIndex = num3;
|
|
return true;
|
|
}
|
|
collapsedIndex = -1;
|
|
return false;
|
|
}
|
|
|
|
// Token: 0x06000048 RID: 72 RVA: 0x00007344 File Offset: 0x00005744
|
|
public static bool SplitCommonVertices(this pb_Object pb, int[] indices)
|
|
{
|
|
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
|
|
pb_IntArray[] sharedIndices = pb.sharedIndices;
|
|
List<int> list = new List<int>();
|
|
List<int> list2 = new List<int>();
|
|
for (int i = 0; i < indices.Length; i++)
|
|
{
|
|
int num = dictionary[indices[i]];
|
|
if (!list.Contains(num))
|
|
{
|
|
list.Add(num);
|
|
list2.AddRange(sharedIndices[num].array);
|
|
}
|
|
}
|
|
pb_IntArrayUtility.RemoveValues(ref sharedIndices, list2.ToArray());
|
|
foreach (int num2 in list2)
|
|
{
|
|
pb_IntArrayUtility.AddValueAtIndex(ref sharedIndices, -1, num2);
|
|
}
|
|
pb.SetSharedIndices(sharedIndices);
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x06000049 RID: 73 RVA: 0x00007420 File Offset: 0x00005820
|
|
public static void SplitVertices(this pb_Object pb, pb_Edge edge)
|
|
{
|
|
pb.SplitVertices(new int[] { edge.x, edge.y });
|
|
}
|
|
|
|
// Token: 0x0600004A RID: 74 RVA: 0x00007440 File Offset: 0x00005840
|
|
public static void SplitVertices(this pb_Object pb, IEnumerable<int> indices)
|
|
{
|
|
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
|
|
int num = dictionary.Count<KeyValuePair<int, int>>();
|
|
foreach (int num2 in indices)
|
|
{
|
|
num = (dictionary[num2] = num + 1);
|
|
}
|
|
pb.SetSharedIndices(dictionary);
|
|
}
|
|
|
|
// Token: 0x0600004B RID: 75 RVA: 0x000074B4 File Offset: 0x000058B4
|
|
public static bool AppendVerticesToFace(this pb_Object pb, pb_Face face, Vector3[] points, Color[] addColors, out pb_Face newFace)
|
|
{
|
|
if (!face.IsValid())
|
|
{
|
|
newFace = face;
|
|
return false;
|
|
}
|
|
List<pb_Vertex> list = pb_Vertex.GetVertices(pb, null).ToList<pb_Vertex>();
|
|
List<pb_Face> list2 = new List<pb_Face>(pb.faces);
|
|
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
|
|
Dictionary<int, int> dictionary2 = ((pb.sharedIndicesUV != null) ? pb.sharedIndicesUV.ToDictionary() : null);
|
|
List<pb_Edge> list3 = pb_WingedEdge.SortEdgesByAdjacency(face);
|
|
List<pb_Vertex> list4 = new List<pb_Vertex>();
|
|
List<int> list5 = new List<int>();
|
|
List<int> list6 = ((dictionary2 == null) ? null : new List<int>());
|
|
for (int i = 0; i < list3.Count; i++)
|
|
{
|
|
list4.Add(list[list3[i].x]);
|
|
list5.Add(dictionary[list3[i].x]);
|
|
if (dictionary2 != null)
|
|
{
|
|
int num;
|
|
if (dictionary2.TryGetValue(list3[i].x, out num))
|
|
{
|
|
list6.Add(num);
|
|
}
|
|
else
|
|
{
|
|
list6.Add(-1);
|
|
}
|
|
}
|
|
}
|
|
for (int j = 0; j < points.Length; j++)
|
|
{
|
|
int num2 = -1;
|
|
float num3 = float.PositiveInfinity;
|
|
Vector3 vector = points[j];
|
|
int count = list4.Count;
|
|
for (int k = 0; k < count; k++)
|
|
{
|
|
Vector3 position = list4[k].position;
|
|
Vector3 position2 = list4[(k + 1) % count].position;
|
|
float num4 = pb_Math.DistancePointLineSegment(vector, position, position2);
|
|
if (num4 < num3)
|
|
{
|
|
num3 = num4;
|
|
num2 = k;
|
|
}
|
|
}
|
|
pb_Vertex pb_Vertex = list4[num2];
|
|
pb_Vertex pb_Vertex2 = list4[(num2 + 1) % count];
|
|
float sqrMagnitude = (vector - pb_Vertex.position).sqrMagnitude;
|
|
float sqrMagnitude2 = (vector - pb_Vertex2.position).sqrMagnitude;
|
|
pb_Vertex pb_Vertex3 = pb_Vertex.Mix(pb_Vertex, pb_Vertex2, sqrMagnitude / (sqrMagnitude + sqrMagnitude2));
|
|
list4.Insert((num2 + 1) % count, pb_Vertex3);
|
|
list5.Insert((num2 + 1) % count, -1);
|
|
if (list6 != null)
|
|
{
|
|
list6.Insert((num2 + 1) % count, -1);
|
|
}
|
|
}
|
|
List<int> list7;
|
|
try
|
|
{
|
|
pb_Triangulation.TriangulateVertices(list4, out list7, false, false);
|
|
}
|
|
catch
|
|
{
|
|
Debug.Log("Failed triangulating face after appending vertices.");
|
|
newFace = null;
|
|
return false;
|
|
}
|
|
pb_FaceRebuildData pb_FaceRebuildData = new pb_FaceRebuildData();
|
|
pb_FaceRebuildData.face = new pb_Face(list7.ToArray(), face.material, new pb_UV(face.uv), face.smoothingGroup, face.textureGroup, -1, face.manualUV);
|
|
pb_FaceRebuildData.vertices = list4;
|
|
pb_FaceRebuildData.sharedIndices = list5;
|
|
pb_FaceRebuildData.sharedIndicesUV = list6;
|
|
pb_FaceRebuildData.Apply(new List<pb_FaceRebuildData> { pb_FaceRebuildData }, list, list2, dictionary, dictionary2);
|
|
newFace = pb_FaceRebuildData.face;
|
|
pb.SetVertices(list, false);
|
|
pb.SetFaces(list2.ToArray());
|
|
pb.SetSharedIndices(dictionary);
|
|
pb.SetSharedIndicesUV(dictionary2);
|
|
Vector3 vector2 = pb_Math.Normal(pb, face);
|
|
Vector3 vector3 = pb_Math.Normal(pb, newFace);
|
|
if (Vector3.Dot(vector2, vector3) < 0f)
|
|
{
|
|
newFace.ReverseIndices();
|
|
}
|
|
pb.DeleteFace(face);
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x0600004C RID: 76 RVA: 0x00007804 File Offset: 0x00005C04
|
|
public static pb_ActionResult AppendVerticesToEdge(this pb_Object pb, pb_Edge edge, int count, out List<pb_Edge> newEdges)
|
|
{
|
|
return pb.AppendVerticesToEdge(new pb_Edge[] { edge }, count, out newEdges);
|
|
}
|
|
|
|
// Token: 0x0600004D RID: 77 RVA: 0x00007818 File Offset: 0x00005C18
|
|
public static pb_ActionResult AppendVerticesToEdge(this pb_Object pb, IList<pb_Edge> edges, int count, out List<pb_Edge> newEdges)
|
|
{
|
|
newEdges = new List<pb_Edge>();
|
|
if (count < 1 || count > 512)
|
|
{
|
|
return new pb_ActionResult(Status.Failure, "New edge vertex count is less than 1 or greater than 512.");
|
|
}
|
|
List<pb_Vertex> list = new List<pb_Vertex>(pb_Vertex.GetVertices(pb, null));
|
|
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
|
|
Dictionary<int, int> dictionary2 = pb.sharedIndicesUV.ToDictionary();
|
|
List<int> list2 = new List<int>();
|
|
pb_Edge[] universalEdges = pb_Edge.GetUniversalEdges(edges.ToArray<pb_Edge>(), dictionary);
|
|
List<pb_Edge> list3 = universalEdges.Distinct<pb_Edge>().ToList<pb_Edge>();
|
|
Dictionary<pb_Face, pb_FaceRebuildData> dictionary3 = new Dictionary<pb_Face, pb_FaceRebuildData>();
|
|
int num = dictionary.Count<KeyValuePair<int, int>>();
|
|
int num2 = num;
|
|
foreach (pb_Edge pb_Edge in list3)
|
|
{
|
|
pb_Edge localEdgeFast = pb_Edge.GetLocalEdgeFast(pb_Edge, pb.sharedIndices);
|
|
List<pb_Vertex> list4 = new List<pb_Vertex>(count);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
list4.Add(pb_Vertex.Mix(list[localEdgeFast.x], list[localEdgeFast.y], (float)(i + 1) / ((float)count + 1f)));
|
|
}
|
|
List<pb_Tuple<pb_Face, pb_Edge>> neighborFaces = pbMeshUtils.GetNeighborFaces(pb, localEdgeFast, null);
|
|
foreach (pb_Tuple<pb_Face, pb_Edge> pb_Tuple in neighborFaces)
|
|
{
|
|
pb_Face item = pb_Tuple.Item1;
|
|
pb_FaceRebuildData pb_FaceRebuildData;
|
|
if (!dictionary3.TryGetValue(item, out pb_FaceRebuildData))
|
|
{
|
|
pb_FaceRebuildData = new pb_FaceRebuildData();
|
|
pb_FaceRebuildData.face = new pb_Face(null, item.material, new pb_UV(item.uv), item.smoothingGroup, item.textureGroup, -1, item.manualUV);
|
|
pb_FaceRebuildData.vertices = new List<pb_Vertex>(list.ValuesWithIndices(item.distinctIndices));
|
|
pb_FaceRebuildData.sharedIndices = new List<int>();
|
|
pb_FaceRebuildData.sharedIndicesUV = new List<int>();
|
|
foreach (int num3 in item.distinctIndices)
|
|
{
|
|
int num4;
|
|
if (dictionary.TryGetValue(num3, out num4))
|
|
{
|
|
pb_FaceRebuildData.sharedIndices.Add(num4);
|
|
}
|
|
if (dictionary2.TryGetValue(num3, out num4))
|
|
{
|
|
pb_FaceRebuildData.sharedIndicesUV.Add(num4);
|
|
}
|
|
}
|
|
list2.AddRange(item.distinctIndices);
|
|
dictionary3.Add(item, pb_FaceRebuildData);
|
|
}
|
|
pb_FaceRebuildData.vertices.AddRange(list4);
|
|
for (int k = 0; k < count; k++)
|
|
{
|
|
pb_FaceRebuildData.sharedIndices.Add(num2 + k);
|
|
pb_FaceRebuildData.sharedIndicesUV.Add(-1);
|
|
}
|
|
}
|
|
num2 += count;
|
|
}
|
|
List<pb_Face> list5 = dictionary3.Keys.ToList<pb_Face>();
|
|
List<pb_FaceRebuildData> list6 = dictionary3.Values.ToList<pb_FaceRebuildData>();
|
|
List<pb_EdgeLookup> list7 = new List<pb_EdgeLookup>();
|
|
for (int l = 0; l < list5.Count; l++)
|
|
{
|
|
pb_Face pb_Face = list5[l];
|
|
pb_FaceRebuildData pb_FaceRebuildData2 = list6[l];
|
|
Vector3 vector = pb_Math.Normal(pb, pb_Face);
|
|
Vector2[] array = pb_Projection.PlanarProject(pb_FaceRebuildData2.vertices.Select((pb_Vertex x) => x.position).ToArray<Vector3>(), vector);
|
|
int count2 = list.Count;
|
|
List<int> list8;
|
|
if (pb_Triangulation.SortAndTriangulate(array, out list8, false))
|
|
{
|
|
pb_FaceRebuildData2.face.SetIndices(list8.ToArray());
|
|
pb_FaceRebuildData2.face.ShiftIndices(count2);
|
|
pb_Face.CopyFrom(pb_FaceRebuildData2.face);
|
|
for (int m = 0; m < pb_FaceRebuildData2.vertices.Count; m++)
|
|
{
|
|
dictionary.Add(count2 + m, pb_FaceRebuildData2.sharedIndices[m]);
|
|
}
|
|
if (pb_FaceRebuildData2.sharedIndicesUV.Count == pb_FaceRebuildData2.vertices.Count)
|
|
{
|
|
for (int n = 0; n < pb_FaceRebuildData2.vertices.Count; n++)
|
|
{
|
|
dictionary2.Add(count2 + n, pb_FaceRebuildData2.sharedIndicesUV[n]);
|
|
}
|
|
}
|
|
list.AddRange(pb_FaceRebuildData2.vertices);
|
|
foreach (pb_Edge pb_Edge2 in pb_Face.edges)
|
|
{
|
|
pb_EdgeLookup pb_EdgeLookup = new pb_EdgeLookup(new pb_Edge(dictionary[pb_Edge2.x], dictionary[pb_Edge2.y]), pb_Edge2);
|
|
if (pb_EdgeLookup.common.x >= num || pb_EdgeLookup.common.y >= num)
|
|
{
|
|
list7.Add(pb_EdgeLookup);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
list2 = list2.Distinct<int>().ToList<int>();
|
|
int delCount = list2.Count;
|
|
newEdges = (from x in list7.Distinct<pb_EdgeLookup>()
|
|
select x.local - delCount).ToList<pb_Edge>();
|
|
pb.SetVertices(list, false);
|
|
pb.SetSharedIndices(dictionary.ToSharedIndices());
|
|
pb.SetSharedIndicesUV(dictionary2.ToSharedIndices());
|
|
pb.DeleteVerticesWithIndices(list2);
|
|
return new pb_ActionResult(Status.Success, "Subdivide Edges");
|
|
}
|
|
|
|
// Token: 0x0600004E RID: 78 RVA: 0x00007D74 File Offset: 0x00006174
|
|
public static pb_FaceRebuildData ExplodeVertex(IList<pb_Vertex> vertices, IList<pb_Tuple<pb_WingedEdge, int>> edgeAndCommonIndex, float distance, out Dictionary<int, List<int>> appendedVertices)
|
|
{
|
|
pb_Face face = edgeAndCommonIndex.FirstOrDefault<pb_Tuple<pb_WingedEdge, int>>().Item1.face;
|
|
List<pb_Edge> list = pb_WingedEdge.SortEdgesByAdjacency(face);
|
|
appendedVertices = new Dictionary<int, List<int>>();
|
|
Vector3 vector = pb_Math.Normal(vertices, face.indices);
|
|
Dictionary<int, int> dictionary = new Dictionary<int, int>();
|
|
foreach (pb_Tuple<pb_WingedEdge, int> pb_Tuple in edgeAndCommonIndex)
|
|
{
|
|
if (pb_Tuple.Item2 == pb_Tuple.Item1.edge.common.x)
|
|
{
|
|
dictionary.Add(pb_Tuple.Item1.edge.local.x, pb_Tuple.Item2);
|
|
}
|
|
else
|
|
{
|
|
dictionary.Add(pb_Tuple.Item1.edge.local.y, pb_Tuple.Item2);
|
|
}
|
|
}
|
|
int count = list.Count;
|
|
List<pb_Vertex> list2 = new List<pb_Vertex>();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
int y = list[i].y;
|
|
if (dictionary.ContainsKey(y))
|
|
{
|
|
pb_Vertex pb_Vertex = vertices[list[i].x];
|
|
pb_Vertex pb_Vertex2 = vertices[list[i].y];
|
|
pb_Vertex pb_Vertex3 = vertices[list[(i + 1) % count].y];
|
|
pb_Vertex pb_Vertex4 = pb_Vertex - pb_Vertex2;
|
|
pb_Vertex pb_Vertex5 = pb_Vertex3 - pb_Vertex2;
|
|
pb_Vertex4.Normalize();
|
|
pb_Vertex5.Normalize();
|
|
pb_Vertex pb_Vertex6 = vertices[y] + pb_Vertex4 * distance;
|
|
pb_Vertex pb_Vertex7 = vertices[y] + pb_Vertex5 * distance;
|
|
appendedVertices.AddOrAppend(dictionary[y], list2.Count);
|
|
list2.Add(pb_Vertex6);
|
|
appendedVertices.AddOrAppend(dictionary[y], list2.Count);
|
|
list2.Add(pb_Vertex7);
|
|
}
|
|
else
|
|
{
|
|
list2.Add(vertices[y]);
|
|
}
|
|
}
|
|
List<int> list3;
|
|
if (pb_Triangulation.TriangulateVertices(list2, out list3, false, false))
|
|
{
|
|
pb_FaceRebuildData pb_FaceRebuildData = new pb_FaceRebuildData();
|
|
pb_FaceRebuildData.vertices = list2;
|
|
pb_FaceRebuildData.face = new pb_Face(face);
|
|
Vector3 vector2 = pb_Math.Normal(list2, list3);
|
|
if (Vector3.Dot(vector, vector2) < 0f)
|
|
{
|
|
list3.Reverse();
|
|
}
|
|
pb_FaceRebuildData.face.SetIndices(list3.ToArray());
|
|
return pb_FaceRebuildData;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Token: 0x0600004F RID: 79 RVA: 0x00007FF8 File Offset: 0x000063F8
|
|
private static pb_Edge AlignEdgeWithDirection(pb_EdgeLookup edge, int commonIndex)
|
|
{
|
|
if (edge.common.x == commonIndex)
|
|
{
|
|
return new pb_Edge(edge.local.x, edge.local.y);
|
|
}
|
|
return new pb_Edge(edge.local.y, edge.local.x);
|
|
}
|
|
|
|
// Token: 0x06000050 RID: 80 RVA: 0x00008050 File Offset: 0x00006450
|
|
public static void Quantize(pb_Object pb, IList<int> indices, Vector3 snap)
|
|
{
|
|
Vector3[] vertices = pb.vertices;
|
|
for (int i = 0; i < indices.Count; i++)
|
|
{
|
|
vertices[indices[i]] = pb.transform.InverseTransformPoint(pb_Snap.SnapValue(pb.transform.TransformPoint(vertices[indices[i]]), snap));
|
|
}
|
|
}
|
|
}
|
|
}
|