using System; using System.Collections.Generic; using ProBuilder2.Common; using UnityEngine; namespace ProBuilder2.MeshOperations { // Token: 0x0200000F RID: 15 public static class pb_Extrude { // Token: 0x0600008E RID: 142 RVA: 0x0000BAB2 File Offset: 0x00009EB2 public static bool Extrude(this pb_Object pb, pb_Face[] faces, ExtrudeMethod method, float distance) { if (method != ExtrudeMethod.IndividualFaces) { return pb_Extrude.ExtrudeAsGroups(pb, faces, method == ExtrudeMethod.FaceNormal, distance); } return pb_Extrude.ExtrudePerFace(pb, faces, distance); } // Token: 0x0600008F RID: 143 RVA: 0x0000BAD4 File Offset: 0x00009ED4 private static bool ExtrudePerFace(pb_Object pb, pb_Face[] faces, float distance) { if (faces == null || faces.Length < 1) { return false; } List list = new List(pb_Vertex.GetVertices(pb, null)); int num = pb.sharedIndices.Length; int num2 = 0; Dictionary dictionary = pb.sharedIndices.ToDictionary(); Dictionary dictionary2 = pb.sharedIndicesUV.ToDictionary(); List list2 = new List(pb.faces); Dictionary dictionary3 = new Dictionary(); foreach (pb_Face pb_Face in faces) { pb_Face.smoothingGroup = -1; pb_Face.textureGroup = -1; Vector3 vector = pb_Math.Normal(pb, pb_Face) * distance; pb_Edge[] edges = pb_Face.edges; dictionary3.Clear(); for (int j = 0; j < edges.Length; j++) { int count = list.Count; int x = edges[j].x; int y = edges[j].y; if (!dictionary3.ContainsKey(x)) { dictionary3.Add(x, dictionary[x]); dictionary[x] = num + num2++; } if (!dictionary3.ContainsKey(y)) { dictionary3.Add(y, dictionary[y]); dictionary[y] = num + num2++; } dictionary.Add(count, dictionary3[x]); dictionary.Add(count + 1, dictionary3[y]); dictionary.Add(count + 2, dictionary[x]); dictionary.Add(count + 3, dictionary[y]); pb_Vertex pb_Vertex = new pb_Vertex(list[x]); pb_Vertex pb_Vertex2 = new pb_Vertex(list[y]); pb_Vertex.position += vector; pb_Vertex2.position += vector; list.Add(new pb_Vertex(list[x])); list.Add(new pb_Vertex(list[y])); list.Add(pb_Vertex); list.Add(pb_Vertex2); pb_Face pb_Face2 = new pb_Face(new int[] { count, count + 1, count + 2, count + 1, count + 3, count + 2 }, pb_Face.material, new pb_UV(pb_Face.uv), pb_Face.smoothingGroup, -1, -1, false); list2.Add(pb_Face2); } for (int k = 0; k < pb_Face.distinctIndices.Length; k++) { pb_Vertex pb_Vertex3 = list[pb_Face.distinctIndices[k]]; pb_Vertex3.position.x = pb_Vertex3.position.x + vector.x; pb_Vertex pb_Vertex4 = list[pb_Face.distinctIndices[k]]; pb_Vertex4.position.y = pb_Vertex4.position.y + vector.y; pb_Vertex pb_Vertex5 = list[pb_Face.distinctIndices[k]]; pb_Vertex5.position.z = pb_Vertex5.position.z + vector.z; if (dictionary2 != null && dictionary2.ContainsKey(pb_Face.distinctIndices[k])) { dictionary2.Remove(pb_Face.distinctIndices[k]); } } } pb.SetVertices(list, false); pb.SetFaces(list2.ToArray()); pb.SetSharedIndices(dictionary); pb.SetSharedIndicesUV(dictionary2); return true; } // Token: 0x06000090 RID: 144 RVA: 0x0000BE28 File Offset: 0x0000A228 private static bool ExtrudeAsGroups(pb_Object pb, pb_Face[] faces, bool compensateAngleVertexDistance, float distance) { if (faces == null || faces.Length < 1) { return false; } List list = new List(pb_Vertex.GetVertices(pb, null)); int num = pb.sharedIndices.Length; int num2 = 0; Dictionary dictionary = pb.sharedIndices.ToDictionary(); Dictionary dictionary2 = pb.sharedIndicesUV.ToDictionary(); List list2 = new List(pb.faces); Dictionary dictionary3 = new Dictionary(); Dictionary dictionary4 = new Dictionary(); Dictionary dictionary5 = new Dictionary(); Dictionary>> dictionary6 = new Dictionary>>(); List wingedEdges = pb_WingedEdge.GetWingedEdges(pb, faces, true, dictionary); List> faceGroups = pb_Extrude.GetFaceGroups(wingedEdges); foreach (HashSet hashSet in faceGroups) { Dictionary perimeterEdges = pb_Extrude.GetPerimeterEdges(hashSet, dictionary); dictionary4.Clear(); dictionary3.Clear(); foreach (KeyValuePair keyValuePair in perimeterEdges) { pb_EdgeLookup key = keyValuePair.Key; pb_Face value = keyValuePair.Value; int count = list.Count; int x = key.local.x; int y = key.local.y; if (!dictionary3.ContainsKey(x)) { dictionary3.Add(x, dictionary[x]); int num3 = -1; if (dictionary4.TryGetValue(dictionary[x], out num3)) { dictionary[x] = num3; } else { num3 = num + num2++; dictionary4.Add(dictionary[x], num3); dictionary[x] = num3; } } if (!dictionary3.ContainsKey(y)) { dictionary3.Add(y, dictionary[y]); int num4 = -1; if (dictionary4.TryGetValue(dictionary[y], out num4)) { dictionary[y] = num4; } else { num4 = num + num2++; dictionary4.Add(dictionary[y], num4); dictionary[y] = num4; } } dictionary.Add(count, dictionary3[x]); dictionary.Add(count + 1, dictionary3[y]); dictionary.Add(count + 2, dictionary[x]); dictionary.Add(count + 3, dictionary[y]); dictionary5.Add(count + 2, x); dictionary5.Add(count + 3, y); list.Add(new pb_Vertex(list[x])); list.Add(new pb_Vertex(list[y])); list.Add(null); list.Add(null); pb_Face pb_Face = new pb_Face(new int[] { count, count + 1, count + 2, count + 1, count + 3, count + 2 }, value.material, new pb_UV(value.uv), value.smoothingGroup, -1, -1, false); list2.Add(pb_Face); } foreach (pb_Face pb_Face2 in hashSet) { pb_Face2.textureGroup = -1; Vector3 vector = pb_Math.Normal(pb, pb_Face2); for (int i = 0; i < pb_Face2.distinctIndices.Length; i++) { int num5 = pb_Face2.distinctIndices[i]; if (!dictionary3.ContainsKey(num5) && dictionary4.ContainsKey(dictionary[num5])) { dictionary[num5] = dictionary4[dictionary[num5]]; } int num6 = dictionary[num5]; if (dictionary2 != null && dictionary2.ContainsKey(pb_Face2.distinctIndices[i])) { dictionary2.Remove(pb_Face2.distinctIndices[i]); } pb_Tuple> pb_Tuple = null; if (dictionary6.TryGetValue(num6, out pb_Tuple)) { pb_Tuple> pb_Tuple2 = pb_Tuple; pb_Tuple2.Item1.x = pb_Tuple2.Item1.x + vector.x; pb_Tuple> pb_Tuple3 = pb_Tuple; pb_Tuple3.Item1.y = pb_Tuple3.Item1.y + vector.y; pb_Tuple> pb_Tuple4 = pb_Tuple; pb_Tuple4.Item1.z = pb_Tuple4.Item1.z + vector.z; pb_Tuple.Item3.Add(num5); } else { dictionary6.Add(num6, new pb_Tuple>(vector, vector, new List { num5 })); } } } } foreach (KeyValuePair>> keyValuePair2 in dictionary6) { Vector3 vector2 = keyValuePair2.Value.Item1 / (float)keyValuePair2.Value.Item3.Count; vector2.Normalize(); float num7 = ((!compensateAngleVertexDistance) ? 1f : pb_Math.Secant(Vector3.Angle(vector2, keyValuePair2.Value.Item2) * 0.017453292f)); vector2.x *= distance * num7; vector2.y *= distance * num7; vector2.z *= distance * num7; foreach (int num8 in keyValuePair2.Value.Item3) { pb_Vertex pb_Vertex = list[num8]; pb_Vertex.position.x = pb_Vertex.position.x + vector2.x; pb_Vertex pb_Vertex2 = list[num8]; pb_Vertex2.position.y = pb_Vertex2.position.y + vector2.y; pb_Vertex pb_Vertex3 = list[num8]; pb_Vertex3.position.z = pb_Vertex3.position.z + vector2.z; } } foreach (KeyValuePair keyValuePair3 in dictionary5) { list[keyValuePair3.Key] = new pb_Vertex(list[keyValuePair3.Value]); } pb.SetVertices(list, false); pb.SetFaces(list2.ToArray()); pb.SetSharedIndices(dictionary); pb.SetSharedIndicesUV(dictionary2); return true; } // Token: 0x06000091 RID: 145 RVA: 0x0000C528 File Offset: 0x0000A928 private static List> GetFaceGroups(List wings) { HashSet hashSet = new HashSet(); List> list = new List>(); foreach (pb_WingedEdge pb_WingedEdge in wings) { if (hashSet.Add(pb_WingedEdge.face)) { HashSet hashSet2 = new HashSet { pb_WingedEdge.face }; pb_GrowShrink.Flood(pb_WingedEdge, hashSet2); foreach (pb_Face pb_Face in hashSet2) { hashSet.Add(pb_Face); } list.Add(hashSet2); } } return list; } // Token: 0x06000092 RID: 146 RVA: 0x0000C60C File Offset: 0x0000AA0C private static Dictionary GetPerimeterEdges(HashSet faces, Dictionary lookup) { Dictionary dictionary = new Dictionary(); HashSet hashSet = new HashSet(); foreach (pb_Face pb_Face in faces) { foreach (pb_Edge pb_Edge in pb_Face.edges) { pb_EdgeLookup pb_EdgeLookup = new pb_EdgeLookup(lookup[pb_Edge.x], lookup[pb_Edge.y], pb_Edge.x, pb_Edge.y); if (!hashSet.Add(pb_EdgeLookup)) { if (dictionary.ContainsKey(pb_EdgeLookup)) { dictionary.Remove(pb_EdgeLookup); } } else { dictionary.Add(pb_EdgeLookup, pb_Face); } } } return dictionary; } } }