Files
2026-06-04 11:42:34 +02:00

373 lines
11 KiB
C#

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<int> list = indices.Distinct<int>().ToList<int>();
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<ProjectionAxis, List<pb_Face>> dictionary = new Dictionary<ProjectionAxis, List<pb_Face>>();
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<pb_Face> { faces[i] });
}
faces[i].elementGroup = -1;
faces[i].manualUV = true;
}
foreach (KeyValuePair<ProjectionAxis, List<pb_Face>> 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<int, int> 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<pb_Face>(faces, (pb_Face x) => x.manualUV).ToArray<pb_Face>();
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;
}
}
}