431 lines
14 KiB
C#
431 lines
14 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
|
|
namespace ProBuilder2.Common
|
|
{
|
|
// Token: 0x02000032 RID: 50
|
|
public class pb_MeshUtility
|
|
{
|
|
// Token: 0x0600014A RID: 330 RVA: 0x00013E6C File Offset: 0x0001226C
|
|
public static string Print(Mesh m)
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
stringBuilder.AppendLine(string.Format("vertices: {0}\ntriangles: {1}\nsubmeshes: {2}", m.vertexCount, m.triangles.Length, m.subMeshCount));
|
|
stringBuilder.AppendLine(string.Format(" {0,-28}{7,-16}{1,-28}{2,-28}{3,-28}{4,-28}{5,-28}{6,-28}", new object[] { "Positions", "Colors", "Tangents", "UV0", "UV2", "UV3", "UV4", "Position Hash" }));
|
|
Vector3[] array = m.vertices;
|
|
Color[] array2 = m.colors;
|
|
Vector4[] array3 = m.tangents;
|
|
List<Vector4> list = new List<Vector4>();
|
|
Vector2[] array4 = m.uv2;
|
|
List<Vector4> list2 = new List<Vector4>();
|
|
List<Vector4> list3 = new List<Vector4>();
|
|
m.GetUVs(0, list);
|
|
m.GetUVs(2, list2);
|
|
m.GetUVs(3, list3);
|
|
if (array != null && array.Count<Vector3>() != m.vertexCount)
|
|
{
|
|
array = null;
|
|
}
|
|
if (array2 != null && array2.Count<Color>() != m.vertexCount)
|
|
{
|
|
array2 = null;
|
|
}
|
|
if (array3 != null && array3.Count<Vector4>() != m.vertexCount)
|
|
{
|
|
array3 = null;
|
|
}
|
|
if (list != null && list.Count<Vector4>() != m.vertexCount)
|
|
{
|
|
list = null;
|
|
}
|
|
if (array4 != null && array4.Count<Vector2>() != m.vertexCount)
|
|
{
|
|
array4 = null;
|
|
}
|
|
if (list2 != null && list2.Count<Vector4>() != m.vertexCount)
|
|
{
|
|
list2 = null;
|
|
}
|
|
if (list3 != null && list3.Count<Vector4>() != m.vertexCount)
|
|
{
|
|
list3 = null;
|
|
}
|
|
for (int i = 0; i < m.vertexCount; i++)
|
|
{
|
|
stringBuilder.AppendLine(string.Format("{7,-5}{0,-28}{8,-16}{1,-28}{2,-28}{3,-28}{4,-28}{5,-28}{6,-28}", new object[]
|
|
{
|
|
(array != null) ? string.Format("{0:F3}, {1:F3}, {2:F3}", array[i].x, array[i].y, array[i].z) : "null",
|
|
(array2 != null) ? string.Format("{0:F2}, {1:F2}, {2:F2}, {3:F2}", new object[]
|
|
{
|
|
array2[i].r,
|
|
array2[i].g,
|
|
array2[i].b,
|
|
array2[i].a
|
|
}) : "null",
|
|
(array3 != null) ? string.Format("{0:F2}, {1:F2}, {2:F2}, {3:F2}", new object[]
|
|
{
|
|
array3[i].x,
|
|
array3[i].y,
|
|
array3[i].z,
|
|
array3[i].w
|
|
}) : "null",
|
|
(list != null) ? string.Format("{0:F2}, {1:F2}, {2:F2}, {3:F2}", new object[]
|
|
{
|
|
list[i].x,
|
|
list[i].y,
|
|
list[i].z,
|
|
list[i].w
|
|
}) : "null",
|
|
(array4 != null) ? string.Format("{0:F2}, {1:F2}", array4[i].x, array4[i].y) : "null",
|
|
(list2 != null) ? string.Format("{0:F2}, {1:F2}, {2:F2}, {3:F2}", new object[]
|
|
{
|
|
list2[i].x,
|
|
list2[i].y,
|
|
list2[i].z,
|
|
list2[i].w
|
|
}) : "null",
|
|
(list3 != null) ? string.Format("{0:F2}, {1:F2}, {2:F2}, {3:F2}", new object[]
|
|
{
|
|
list3[i].x,
|
|
list3[i].y,
|
|
list3[i].z,
|
|
list3[i].w
|
|
}) : "null",
|
|
i,
|
|
pb_Vector.GetHashCode(array[i])
|
|
}));
|
|
}
|
|
for (int j = 0; j < m.triangles.Length; j += 3)
|
|
{
|
|
stringBuilder.AppendLine(string.Format("{0}, {1}, {2}", m.triangles[j], m.triangles[j + 1], m.triangles[j + 2]));
|
|
}
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
// Token: 0x0600014B RID: 331 RVA: 0x000143F4 File Offset: 0x000127F4
|
|
public static pb_Vertex[] GeneratePerTriangleMesh(Mesh m)
|
|
{
|
|
pb_Vertex[] vertices = pb_Vertex.GetVertices(m);
|
|
int subMeshCount = m.subMeshCount;
|
|
pb_Vertex[] array = new pb_Vertex[m.triangles.Length];
|
|
int[][] array2 = new int[subMeshCount][];
|
|
int num = 0;
|
|
for (int i = 0; i < subMeshCount; i++)
|
|
{
|
|
array2[i] = m.GetTriangles(i);
|
|
int num2 = array2[i].Length;
|
|
for (int j = 0; j < num2; j++)
|
|
{
|
|
array[num++] = new pb_Vertex(vertices[array2[i][j]]);
|
|
array2[i][j] = num - 1;
|
|
}
|
|
}
|
|
pb_Vertex.SetMesh(m, array);
|
|
m.subMeshCount = subMeshCount;
|
|
for (int k = 0; k < subMeshCount; k++)
|
|
{
|
|
m.SetTriangles(array2[k], k);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
// Token: 0x0600014C RID: 332 RVA: 0x000144BC File Offset: 0x000128BC
|
|
public static void CollapseSharedVertices(Mesh m, pb_Vertex[] vertices = null)
|
|
{
|
|
if (vertices == null)
|
|
{
|
|
vertices = pb_Vertex.GetVertices(m);
|
|
}
|
|
int subMeshCount = m.subMeshCount;
|
|
List<Dictionary<pb_Vertex, int>> list = new List<Dictionary<pb_Vertex, int>>();
|
|
int[][] array = new int[subMeshCount][];
|
|
int num = 0;
|
|
for (int i = 0; i < subMeshCount; i++)
|
|
{
|
|
array[i] = m.GetTriangles(i);
|
|
Dictionary<pb_Vertex, int> dictionary = new Dictionary<pb_Vertex, int>();
|
|
for (int j = 0; j < array[i].Length; j++)
|
|
{
|
|
pb_Vertex pb_Vertex = vertices[array[i][j]];
|
|
int num2;
|
|
if (dictionary.TryGetValue(pb_Vertex, out num2))
|
|
{
|
|
array[i][j] = num2;
|
|
}
|
|
else
|
|
{
|
|
array[i][j] = num;
|
|
dictionary.Add(pb_Vertex, num);
|
|
num++;
|
|
}
|
|
}
|
|
list.Add(dictionary);
|
|
}
|
|
pb_Vertex[] array2 = list.SelectMany((Dictionary<pb_Vertex, int> x) => x.Keys).ToArray<pb_Vertex>();
|
|
pb_Vertex.SetMesh(m, array2);
|
|
m.subMeshCount = subMeshCount;
|
|
for (int k = 0; k < subMeshCount; k++)
|
|
{
|
|
m.SetTriangles(array[k], k);
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600014D RID: 333 RVA: 0x000145D4 File Offset: 0x000129D4
|
|
public static void GenerateTangent(ref Mesh InMesh)
|
|
{
|
|
int[] triangles = InMesh.triangles;
|
|
Vector3[] vertices = InMesh.vertices;
|
|
Vector2[] uv = InMesh.uv;
|
|
Vector3[] normals = InMesh.normals;
|
|
int num = triangles.Length;
|
|
int num2 = vertices.Length;
|
|
Vector3[] array = new Vector3[num2];
|
|
Vector3[] array2 = new Vector3[num2];
|
|
Vector4[] array3 = new Vector4[num2];
|
|
for (long num3 = 0L; num3 < (long)num; num3 += 3L)
|
|
{
|
|
long num4 = (long)triangles[(int)(checked((IntPtr)num3))];
|
|
long num5 = (long)triangles[(int)(checked((IntPtr)(unchecked(num3 + 1L))))];
|
|
long num6 = (long)triangles[(int)(checked((IntPtr)(unchecked(num3 + 2L))))];
|
|
Vector3 vector;
|
|
Vector3 vector2;
|
|
Vector3 vector3;
|
|
Vector2 vector4;
|
|
Vector2 vector5;
|
|
Vector2 vector6;
|
|
checked
|
|
{
|
|
vector = vertices[(int)((IntPtr)num4)];
|
|
vector2 = vertices[(int)((IntPtr)num5)];
|
|
vector3 = vertices[(int)((IntPtr)num6)];
|
|
vector4 = uv[(int)((IntPtr)num4)];
|
|
vector5 = uv[(int)((IntPtr)num5)];
|
|
vector6 = uv[(int)((IntPtr)num6)];
|
|
}
|
|
float num7 = vector2.x - vector.x;
|
|
float num8 = vector3.x - vector.x;
|
|
float num9 = vector2.y - vector.y;
|
|
float num10 = vector3.y - vector.y;
|
|
float num11 = vector2.z - vector.z;
|
|
float num12 = vector3.z - vector.z;
|
|
float num13 = vector5.x - vector4.x;
|
|
float num14 = vector6.x - vector4.x;
|
|
float num15 = vector5.y - vector4.y;
|
|
float num16 = vector6.y - vector4.y;
|
|
float num17 = 1f / (num13 * num16 - num14 * num15);
|
|
Vector3 vector7 = new Vector3((num16 * num7 - num15 * num8) * num17, (num16 * num9 - num15 * num10) * num17, (num16 * num11 - num15 * num12) * num17);
|
|
Vector3 vector8 = new Vector3((num13 * num8 - num14 * num7) * num17, (num13 * num10 - num14 * num9) * num17, (num13 * num12 - num14 * num11) * num17);
|
|
checked
|
|
{
|
|
array[(int)((IntPtr)num4)] += vector7;
|
|
array[(int)((IntPtr)num5)] += vector7;
|
|
array[(int)((IntPtr)num6)] += vector7;
|
|
array2[(int)((IntPtr)num4)] += vector8;
|
|
array2[(int)((IntPtr)num5)] += vector8;
|
|
array2[(int)((IntPtr)num6)] += vector8;
|
|
}
|
|
}
|
|
for (long num18 = 0L; num18 < (long)num2; num18 += 1L)
|
|
{
|
|
checked
|
|
{
|
|
Vector3 vector9 = normals[(int)((IntPtr)num18)];
|
|
Vector3 vector10 = array[(int)((IntPtr)num18)];
|
|
Vector3.OrthoNormalize(ref vector9, ref vector10);
|
|
array3[(int)((IntPtr)num18)].x = vector10.x;
|
|
array3[(int)((IntPtr)num18)].y = vector10.y;
|
|
array3[(int)((IntPtr)num18)].z = vector10.z;
|
|
array3[(int)((IntPtr)num18)].w = ((Vector3.Dot(Vector3.Cross(vector9, vector10), array2[(int)((IntPtr)num18)]) >= 0f) ? 1f : (-1f));
|
|
}
|
|
}
|
|
InMesh.tangents = array3;
|
|
}
|
|
|
|
// Token: 0x0600014E RID: 334 RVA: 0x0001495C File Offset: 0x00012D5C
|
|
public static Mesh DeepCopy(Mesh mesh)
|
|
{
|
|
Mesh mesh2 = new Mesh();
|
|
pb_MeshUtility.CopyTo(mesh, mesh2);
|
|
return mesh2;
|
|
}
|
|
|
|
// Token: 0x0600014F RID: 335 RVA: 0x00014978 File Offset: 0x00012D78
|
|
public static void CopyTo(Mesh source, Mesh destination)
|
|
{
|
|
Vector3[] array = new Vector3[source.vertices.Length];
|
|
int[][] array2 = new int[source.subMeshCount][];
|
|
Vector2[] array3 = new Vector2[source.uv.Length];
|
|
Vector2[] array4 = new Vector2[source.uv2.Length];
|
|
Vector4[] array5 = new Vector4[source.tangents.Length];
|
|
Vector3[] array6 = new Vector3[source.normals.Length];
|
|
Color32[] array7 = new Color32[source.colors32.Length];
|
|
Array.Copy(source.vertices, array, array.Length);
|
|
for (int i = 0; i < array2.Length; i++)
|
|
{
|
|
array2[i] = source.GetTriangles(i);
|
|
}
|
|
Array.Copy(source.uv, array3, array3.Length);
|
|
Array.Copy(source.uv2, array4, array4.Length);
|
|
Array.Copy(source.normals, array6, array6.Length);
|
|
Array.Copy(source.tangents, array5, array5.Length);
|
|
Array.Copy(source.colors32, array7, array7.Length);
|
|
destination.Clear();
|
|
destination.name = source.name;
|
|
destination.vertices = array;
|
|
destination.subMeshCount = array2.Length;
|
|
for (int j = 0; j < array2.Length; j++)
|
|
{
|
|
destination.SetTriangles(array2[j], j);
|
|
}
|
|
destination.uv = array3;
|
|
destination.uv2 = array4;
|
|
destination.tangents = array5;
|
|
destination.normals = array6;
|
|
destination.colors32 = array7;
|
|
}
|
|
|
|
// Token: 0x06000150 RID: 336 RVA: 0x00014AD8 File Offset: 0x00012ED8
|
|
public static Vector3[] GenerateNormals(pb_Object pb)
|
|
{
|
|
int vertexCount = pb.vertexCount;
|
|
Vector3[] array = new Vector3[vertexCount];
|
|
Vector3[] vertices = pb.vertices;
|
|
Vector3[] array2 = new Vector3[vertexCount];
|
|
int[] array3 = new int[vertexCount];
|
|
pb_Face[] faces = pb.faces;
|
|
for (int i = 0; i < faces.Length; i++)
|
|
{
|
|
int[] indices = faces[i].indices;
|
|
for (int j = 0; j < indices.Length; j += 3)
|
|
{
|
|
int num = indices[j];
|
|
int num2 = indices[j + 1];
|
|
int num3 = indices[j + 2];
|
|
Vector3 vector = pb_Math.Normal(vertices[num], vertices[num2], vertices[num3]);
|
|
Vector3[] array4 = array;
|
|
int num4 = num;
|
|
array4[num4].x = array4[num4].x + vector.x;
|
|
Vector3[] array5 = array;
|
|
int num5 = num2;
|
|
array5[num5].x = array5[num5].x + vector.x;
|
|
Vector3[] array6 = array;
|
|
int num6 = num3;
|
|
array6[num6].x = array6[num6].x + vector.x;
|
|
Vector3[] array7 = array;
|
|
int num7 = num;
|
|
array7[num7].y = array7[num7].y + vector.y;
|
|
Vector3[] array8 = array;
|
|
int num8 = num2;
|
|
array8[num8].y = array8[num8].y + vector.y;
|
|
Vector3[] array9 = array;
|
|
int num9 = num3;
|
|
array9[num9].y = array9[num9].y + vector.y;
|
|
Vector3[] array10 = array;
|
|
int num10 = num;
|
|
array10[num10].z = array10[num10].z + vector.z;
|
|
Vector3[] array11 = array;
|
|
int num11 = num2;
|
|
array11[num11].z = array11[num11].z + vector.z;
|
|
Vector3[] array12 = array;
|
|
int num12 = num3;
|
|
array12[num12].z = array12[num12].z + vector.z;
|
|
array3[num]++;
|
|
array3[num2]++;
|
|
array3[num3]++;
|
|
}
|
|
}
|
|
for (int k = 0; k < vertexCount; k++)
|
|
{
|
|
array2[k].x = array[k].x * (float)array3[k];
|
|
array2[k].y = array[k].y * (float)array3[k];
|
|
array2[k].z = array[k].z * (float)array3[k];
|
|
}
|
|
return array2;
|
|
}
|
|
|
|
// Token: 0x06000151 RID: 337 RVA: 0x00014D30 File Offset: 0x00013130
|
|
public static void SmoothNormals(pb_Object pb, ref Vector3[] normals)
|
|
{
|
|
int vertexCount = pb.vertexCount;
|
|
Vector3[] array = new Vector3[24];
|
|
float[] array2 = new float[24];
|
|
int[] array3 = new int[vertexCount];
|
|
pb_IntArray[] sharedIndices = pb.sharedIndices;
|
|
pb_Face[] faces = pb.faces;
|
|
foreach (pb_Face pb_Face in faces)
|
|
{
|
|
foreach (int num in pb_Face.distinctIndices)
|
|
{
|
|
array3[num] = pb_Face.smoothingGroup;
|
|
}
|
|
}
|
|
for (int k = 0; k < sharedIndices.Length; k++)
|
|
{
|
|
for (int l = 0; l < 24; l++)
|
|
{
|
|
array[l].x = 0f;
|
|
array[l].y = 0f;
|
|
array[l].z = 0f;
|
|
array2[l] = 0f;
|
|
}
|
|
for (int m = 0; m < sharedIndices[k].array.Length; m++)
|
|
{
|
|
int num2 = sharedIndices[k].array[m];
|
|
if (array3[num2] >= 1 && array3[num2] <= 24)
|
|
{
|
|
Vector3[] array5 = array;
|
|
int num3 = array3[num2];
|
|
array5[num3].x = array5[num3].x + normals[num2].x;
|
|
Vector3[] array6 = array;
|
|
int num4 = array3[num2];
|
|
array6[num4].y = array6[num4].y + normals[num2].y;
|
|
Vector3[] array7 = array;
|
|
int num5 = array3[num2];
|
|
array7[num5].z = array7[num5].z + normals[num2].z;
|
|
array2[array3[num2]] += 1f;
|
|
}
|
|
}
|
|
for (int n = 0; n < sharedIndices[k].array.Length; n++)
|
|
{
|
|
int num6 = sharedIndices[k].array[n];
|
|
if (array3[num6] >= 1 && array3[num6] <= 24)
|
|
{
|
|
normals[num6].x = array[array3[num6]].x / array2[array3[num6]];
|
|
normals[num6].y = array[array3[num6]].y / array2[array3[num6]];
|
|
normals[num6].z = array[array3[num6]].z / array2[array3[num6]];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000152 RID: 338 RVA: 0x00014FB4 File Offset: 0x000133B4
|
|
public static T GetMeshAttribute<T>(GameObject go, Func<Mesh, T> attributeGetter) where T : IList
|
|
{
|
|
MeshFilter component = go.GetComponent<MeshFilter>();
|
|
Mesh mesh = ((!(component != null)) ? null : component.sharedMesh);
|
|
T t = default(T);
|
|
if (mesh == null)
|
|
{
|
|
return t;
|
|
}
|
|
int vertexCount = mesh.vertexCount;
|
|
MeshRenderer component2 = go.GetComponent<MeshRenderer>();
|
|
Mesh mesh2 = ((!(component2 != null)) ? null : component2.additionalVertexStreams);
|
|
if (mesh2 != null)
|
|
{
|
|
t = attributeGetter(mesh2);
|
|
if (t != null && t.Count == vertexCount)
|
|
{
|
|
return t;
|
|
}
|
|
}
|
|
t = attributeGetter(mesh);
|
|
return (t == null || t.Count != vertexCount) ? default(T) : t;
|
|
}
|
|
}
|
|
}
|