using System; using System.Collections.Generic; using System.Linq; using ProBuilder2.Common; using UnityEngine; namespace ProBuilder2.MeshOperations { // Token: 0x02000005 RID: 5 public static class pbUVOps { // Token: 0x0600003A RID: 58 RVA: 0x000063C8 File Offset: 0x000047C8 public static bool SewUVs(this pb_Object pb, int[] indices, float delta) { int[] array = new int[indices.Length]; Vector2[] array2 = pb.uv; if (array2 == null || array2.Length != pb.vertexCount) { array2 = new Vector2[pb.vertexCount]; } for (int i = 0; i < indices.Length; i++) { array[i] = -(i + 1); } pb_IntArray[] sharedIndicesUV = pb.sharedIndicesUV; for (int j = 0; j < indices.Length - 1; j++) { for (int k = j + 1; k < indices.Length; k++) { if (array[j] != array[k]) { if (Vector2.Distance(array2[indices[j]], array2[indices[k]]) < delta) { Vector3 vector = (array2[indices[j]] + array2[indices[k]]) / 2f; array2[indices[j]] = vector; array2[indices[k]] = vector; int num = pb_IntArrayUtility.MergeSharedIndices(ref sharedIndicesUV, new int[] { indices[j], indices[k] }); array[j] = num; array[k] = num; } } } } pb.SetUV(array2); pb.SetSharedIndicesUV(sharedIndicesUV); return true; } // Token: 0x0600003B RID: 59 RVA: 0x00006530 File Offset: 0x00004930 public static void CollapseUVs(this pb_Object pb, int[] indices) { Vector2[] uv = pb.uv; Vector2 vector = pb_Math.Average(uv.ValuesWithIndices(indices), null); foreach (int num in indices) { uv[num] = vector; } pb_IntArray[] sharedIndicesUV = pb.sharedIndicesUV; pb_IntArrayUtility.MergeSharedIndices(ref sharedIndicesUV, indices); pb.SetUV(uv); pb.SetSharedIndicesUV(sharedIndicesUV); } // Token: 0x0600003C RID: 60 RVA: 0x000065A0 File Offset: 0x000049A0 public static bool SplitUVs(this pb_Object pb, int[] indices) { pb_IntArray[] sharedIndicesUV = pb.sharedIndicesUV; if (sharedIndicesUV == null) { return false; } List list = indices.Distinct().ToList(); for (int i = 0; i < list.Count; i++) { int num = sharedIndicesUV.IndexOf(list[i]); if (num >= 0) { sharedIndicesUV[num].array = sharedIndicesUV[num].array.Remove(list[i]); } } foreach (int num2 in list) { pb_IntArrayUtility.AddValueAtIndex(ref sharedIndicesUV, -1, num2); } pb.SetSharedIndicesUV(sharedIndicesUV); return true; } // Token: 0x0600003D RID: 61 RVA: 0x00006670 File Offset: 0x00004A70 public static void ProjectFacesAuto(pb_Object pb, pb_Face[] faces) { int[] array = pb_Face.AllTrianglesDistinct(faces); Vector3 vector = Vector3.zero; foreach (pb_Face pb_Face in faces) { vector += pb_Math.Normal(pb, pb_Face); } vector /= (float)faces.Length; Vector2[] array2 = pb_Projection.PlanarProject(pb.vertices.ValuesWithIndices(array), vector); Vector2[] uv = pb.uv; for (int j = 0; j < array.Length; j++) { uv[array[j]] = array2[j]; } pb.SetUV(uv); pb.msh.uv = uv; foreach (pb_Face pb_Face2 in faces) { pb_Face2.elementGroup = -1; pb.SplitUVs(pb_Face2.distinctIndices); } pb.SewUVs(pb_Face.AllTrianglesDistinct(faces), 0.001f); } // Token: 0x0600003E RID: 62 RVA: 0x00006774 File Offset: 0x00004B74 public static void ProjectFacesBox(pb_Object pb, pb_Face[] faces) { Vector2[] uv = pb.uv; Dictionary> dictionary = new Dictionary>(); for (int i = 0; i < faces.Length; i++) { Vector3 vector = pb_Math.Normal(pb, faces[i]); ProjectionAxis projectionAxis = pb_Projection.VectorToProjectionAxis(vector); if (dictionary.ContainsKey(projectionAxis)) { dictionary[projectionAxis].Add(faces[i]); } else { dictionary.Add(projectionAxis, new List { faces[i] }); } faces[i].elementGroup = -1; faces[i].manualUV = true; } foreach (KeyValuePair> keyValuePair in dictionary) { int[] array = pb_Face.AllTrianglesDistinct(keyValuePair.Value.ToArray()); Vector2[] array2 = pb_Projection.PlanarProject(pb.vertices.ValuesWithIndices(array), pb_Projection.ProjectionAxisToVector(keyValuePair.Key), keyValuePair.Key, null); for (int j = 0; j < array.Length; j++) { uv[array[j]] = array2[j]; } pb.SplitUVs(array); } pb.SetUV(uv); } // Token: 0x0600003F RID: 63 RVA: 0x000068CC File Offset: 0x00004CCC public static void ProjectFacesSphere(pb_Object pb, int[] indices) { foreach (pb_Face pb_Face in pb.faces) { if (pb_Face.distinctIndices.ContainsMatch(indices)) { pb_Face.elementGroup = -1; pb_Face.manualUV = true; } } pb.SplitUVs(indices); Vector2[] array = pb_Projection.SphericalProject(pb.vertices, indices); Vector2[] uv = pb.uv; for (int j = 0; j < indices.Length; j++) { uv[indices[j]] = array[j]; } pb.SetUV(uv); } // Token: 0x06000040 RID: 64 RVA: 0x00006974 File Offset: 0x00004D74 public static Vector2[] FitUVs(Vector2[] uvs) { Vector2 vector = pb_Math.SmallestVector2(uvs); for (int i = 0; i < uvs.Length; i++) { uvs[i] -= vector; } float num = pb_Math.LargestValue(pb_Math.LargestVector2(uvs)); for (int i = 0; i < uvs.Length; i++) { uvs[i] /= num; } return uvs; } // Token: 0x06000041 RID: 65 RVA: 0x000069F0 File Offset: 0x00004DF0 public static bool AutoStitch(pb_Object pb, pb_Face f1, pb_Face f2) { Dictionary dictionary = pb.sharedIndices.ToDictionary(); for (int i = 0; i < f1.edges.Length; i++) { int num = f2.edges.IndexOf(f1.edges[i], dictionary); if (num > -1) { pbUVOps.ProjectFacesAuto(pb, new pb_Face[] { f2 }); f1.manualUV = true; f2.manualUV = true; f1.textureGroup = -1; f2.textureGroup = -1; pbUVOps.AlignEdges(pb, f1, f2, f1.edges[i], f2.edges[num]); return true; } } return false; } // Token: 0x06000042 RID: 66 RVA: 0x00006A88 File Offset: 0x00004E88 private static bool AlignEdges(pb_Object pb, pb_Face f1, pb_Face f2, pb_Edge edge1, pb_Edge edge2) { Vector2[] uv = pb.uv; pb_IntArray[] sharedIndices = pb.sharedIndices; pb_IntArray[] sharedIndicesUV = pb.sharedIndicesUV; int[] array = new int[] { edge1.x, -1 }; int[] array2 = new int[] { edge1.y, -1 }; int num = sharedIndices.IndexOf(edge1.x); if (num < 0) { return false; } if (sharedIndices[num].array.Contains(edge2.x)) { array[1] = edge2.x; array2[1] = edge2.y; } else { array[1] = edge2.y; array2[1] = edge2.x; } float num2 = Vector2.Distance(uv[edge1.x], uv[edge1.y]); float num3 = Vector2.Distance(uv[edge2.x], uv[edge2.y]); float num4 = num2 / num3; foreach (int num5 in f2.distinctIndices) { uv[num5] = uv[num5].ScaleAroundPoint(Vector2.zero, Vector2.one * num4); } Vector2 vector = (uv[edge1.x] + uv[edge1.y]) / 2f; Vector2 vector2 = (uv[edge2.x] + uv[edge2.y]) / 2f; Vector2 vector3 = vector - vector2; foreach (int num6 in f2.distinctIndices) { uv[num6] += vector3; } Vector2 vector4 = uv[array2[0]] - uv[array[0]]; Vector2 vector5 = uv[array2[1]] - uv[array[1]]; float num7 = Vector2.Angle(vector4, vector5); if (Vector3.Cross(vector4, vector5).z < 0f) { num7 = 360f - num7; } foreach (int num8 in f2.distinctIndices) { uv[num8] = uv[num8].RotateAroundPoint(vector, num7); } float num9 = Mathf.Abs(Vector2.Distance(uv[array[0]], uv[array[1]])) + Mathf.Abs(Vector2.Distance(uv[array2[0]], uv[array2[1]])); if (num9 > 0.02f) { foreach (int num10 in f2.distinctIndices) { uv[num10] = uv[num10].RotateAroundPoint(vector, 180f); } float num11 = Mathf.Abs(Vector2.Distance(uv[array[0]], uv[array[1]])) + Mathf.Abs(Vector2.Distance(uv[array2[0]], uv[array2[1]])); if (num11 >= num9) { foreach (int num12 in f2.distinctIndices) { uv[num12] = uv[num12].RotateAroundPoint(vector, 180f); } } } pb.SplitUVs(f2.distinctIndices); pb_IntArrayUtility.MergeSharedIndices(ref sharedIndicesUV, array); pb_IntArrayUtility.MergeSharedIndices(ref sharedIndicesUV, array2); pb_IntArray.RemoveEmptyOrNull(ref sharedIndicesUV); pb.SetSharedIndicesUV(sharedIndicesUV); pb.SetUV(uv); return true; } // Token: 0x06000043 RID: 67 RVA: 0x00006EFC File Offset: 0x000052FC public static pb_Transform2D MatchCoordinates(Vector2[] points, Vector2[] target) { int num = ((points.Length >= target.Length) ? target.Length : points.Length); pb_Bounds2D pb_Bounds2D = new pb_Bounds2D(target, num); Vector2 vector = pb_Bounds2D.center - pb_Bounds2D.Center(points, num); Vector2[] array = new Vector2[points.Length]; for (int i = 0; i < points.Length; i++) { array[i] = points[i] + vector; } Vector2 vector2 = target[1] - target[0]; Vector2 vector3 = array[1] - array[0]; float num2 = Vector2.Angle(vector2, vector3); float num3 = Vector2.Dot(pb_Math.Perpendicular(vector2), vector3); if (num3 < 0f) { num2 = 360f - num2; } for (int j = 0; j < points.Length; j++) { array[j] = array[j].RotateAroundPoint(pb_Bounds2D.center, num2); } pb_Bounds2D pb_Bounds2D2 = new pb_Bounds2D(array, num); Vector2 vector4 = pb_Bounds2D.size.DivideBy(pb_Bounds2D2.size); return new pb_Transform2D(vector, num2, vector4); } // Token: 0x06000044 RID: 68 RVA: 0x00007054 File Offset: 0x00005454 public static void SetAutoUV(pb_Object pb, pb_Face[] faces, bool auto) { if (auto) { faces = Array.FindAll(faces, (pb_Face x) => x.manualUV).ToArray(); pb.SplitUVs(pb_Face.AllTriangles(faces)); Vector2[][] array = new Vector2[faces.Length][]; for (int i = 0; i < faces.Length; i++) { array[i] = pb.uv.ValuesWithIndices(faces[i].distinctIndices); } for (int j = 0; j < faces.Length; j++) { faces[j].uv.Reset(); faces[j].manualUV = !auto; faces[j].elementGroup = -1; } pb.RefreshUV(faces); for (int k = 0; k < faces.Length; k++) { pb_Transform2D pb_Transform2D = pbUVOps.MatchCoordinates(pb.uv.ValuesWithIndices(faces[k].distinctIndices), array[k]); faces[k].uv.offset = -pb_Transform2D.position; faces[k].uv.rotation = pb_Transform2D.rotation; if (Mathf.Abs(pb_Transform2D.scale.sqrMagnitude - 2f) > 0.1f) { faces[k].uv.scale = pb_Transform2D.scale; } } } else { foreach (pb_Face pb_Face in faces) { pb_Face.textureGroup = -1; pb_Face.manualUV = !auto; } } } // Token: 0x06000045 RID: 69 RVA: 0x000071DC File Offset: 0x000055DC public static Vector2 NearestVector2(Vector2 pos, Vector2[] uvs) { if (uvs.Length < 1) { return pos; } Vector2 vector = uvs[0]; float num = Vector2.Distance(pos, vector); for (int i = 1; i < uvs.Length; i++) { float num2 = Vector2.Distance(pos, uvs[i]); if (num2 < num) { num = num2; vector = uvs[i]; } } return vector; } } }