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 dictionary = pb.sharedIndices.ToDictionary(); pb_IntArray[] sharedIndices = pb.sharedIndices; List list = new List(); List list2 = new List(); 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 indices) { Dictionary dictionary = pb.sharedIndices.ToDictionary(); int num = dictionary.Count>(); 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 list = pb_Vertex.GetVertices(pb, null).ToList(); List list2 = new List(pb.faces); Dictionary dictionary = pb.sharedIndices.ToDictionary(); Dictionary dictionary2 = ((pb.sharedIndicesUV != null) ? pb.sharedIndicesUV.ToDictionary() : null); List list3 = pb_WingedEdge.SortEdgesByAdjacency(face); List list4 = new List(); List list5 = new List(); List list6 = ((dictionary2 == null) ? null : new List()); 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 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 }, 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 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 edges, int count, out List newEdges) { newEdges = new List(); if (count < 1 || count > 512) { return new pb_ActionResult(Status.Failure, "New edge vertex count is less than 1 or greater than 512."); } List list = new List(pb_Vertex.GetVertices(pb, null)); Dictionary dictionary = pb.sharedIndices.ToDictionary(); Dictionary dictionary2 = pb.sharedIndicesUV.ToDictionary(); List list2 = new List(); pb_Edge[] universalEdges = pb_Edge.GetUniversalEdges(edges.ToArray(), dictionary); List list3 = universalEdges.Distinct().ToList(); Dictionary dictionary3 = new Dictionary(); int num = dictionary.Count>(); int num2 = num; foreach (pb_Edge pb_Edge in list3) { pb_Edge localEdgeFast = pb_Edge.GetLocalEdgeFast(pb_Edge, pb.sharedIndices); List list4 = new List(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> neighborFaces = pbMeshUtils.GetNeighborFaces(pb, localEdgeFast, null); foreach (pb_Tuple 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(list.ValuesWithIndices(item.distinctIndices)); pb_FaceRebuildData.sharedIndices = new List(); pb_FaceRebuildData.sharedIndicesUV = new List(); 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 list5 = dictionary3.Keys.ToList(); List list6 = dictionary3.Values.ToList(); List list7 = new List(); 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(), vector); int count2 = list.Count; List 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().ToList(); int delCount = list2.Count; newEdges = (from x in list7.Distinct() select x.local - delCount).ToList(); 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 vertices, IList> edgeAndCommonIndex, float distance, out Dictionary> appendedVertices) { pb_Face face = edgeAndCommonIndex.FirstOrDefault>().Item1.face; List list = pb_WingedEdge.SortEdgesByAdjacency(face); appendedVertices = new Dictionary>(); Vector3 vector = pb_Math.Normal(vertices, face.indices); Dictionary dictionary = new Dictionary(); foreach (pb_Tuple 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 list2 = new List(); 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 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 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)); } } } }