Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/MTAssets/UltimateLODSystem/MeshSimplifier/MeshUtils.cs
2026-03-04 10:03:45 +08:00

334 lines
8.4 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
namespace MTAssets.UltimateLODSystem.MeshSimplifier
{
public static class MeshUtils
{
public static readonly int UVChannelCount = 8;
public static Mesh CreateMesh(Vector3[] vertices, int[][] indices, Vector3[] normals, Vector4[] tangents, Color[] colors, BoneWeight[] boneWeights, List<Vector2>[] uvs, Matrix4x4[] bindposes, BlendShape[] blendShapes)
{
return CreateMesh(vertices, indices, normals, tangents, colors, boneWeights, uvs, null, null, bindposes, blendShapes);
}
public static Mesh CreateMesh(Vector3[] vertices, int[][] indices, Vector3[] normals, Vector4[] tangents, Color[] colors, BoneWeight[] boneWeights, List<Vector4>[] uvs, Matrix4x4[] bindposes, BlendShape[] blendShapes)
{
return CreateMesh(vertices, indices, normals, tangents, colors, boneWeights, null, null, uvs, bindposes, blendShapes);
}
public static Mesh CreateMesh(Vector3[] vertices, int[][] indices, Vector3[] normals, Vector4[] tangents, Color[] colors, BoneWeight[] boneWeights, List<Vector2>[] uvs2D, List<Vector3>[] uvs3D, List<Vector4>[] uvs4D, Matrix4x4[] bindposes, BlendShape[] blendShapes)
{
if (vertices == null)
{
throw new ArgumentNullException("vertices");
}
if (indices == null)
{
throw new ArgumentNullException("indices");
}
Mesh mesh = new Mesh();
int num = indices.Length;
IndexFormat indexFormat;
Vector2Int[] subMeshIndexMinMax = GetSubMeshIndexMinMax(indices, out indexFormat);
mesh.indexFormat = indexFormat;
if (bindposes != null && bindposes.Length != 0)
{
mesh.bindposes = bindposes;
}
mesh.subMeshCount = num;
mesh.vertices = vertices;
if (normals != null && normals.Length != 0)
{
mesh.normals = normals;
}
if (tangents != null && tangents.Length != 0)
{
mesh.tangents = tangents;
}
if (colors != null && colors.Length != 0)
{
mesh.colors = colors;
}
if (boneWeights != null && boneWeights.Length != 0)
{
mesh.boneWeights = boneWeights;
}
if (uvs2D != null)
{
for (int i = 0; i < uvs2D.Length; i++)
{
if (uvs2D[i] != null && uvs2D[i].Count > 0)
{
mesh.SetUVs(i, uvs2D[i]);
}
}
}
if (uvs3D != null)
{
for (int j = 0; j < uvs3D.Length; j++)
{
if (uvs3D[j] != null && uvs3D[j].Count > 0)
{
mesh.SetUVs(j, uvs3D[j]);
}
}
}
if (uvs4D != null)
{
for (int k = 0; k < uvs4D.Length; k++)
{
if (uvs4D[k] != null && uvs4D[k].Count > 0)
{
mesh.SetUVs(k, uvs4D[k]);
}
}
}
if (blendShapes != null)
{
ApplyMeshBlendShapes(mesh, blendShapes);
}
for (int l = 0; l < num; l++)
{
int[] array = indices[l];
Vector2Int vector2Int = subMeshIndexMinMax[l];
if (indexFormat == IndexFormat.UInt16 && vector2Int.y > 65535)
{
int x = vector2Int.x;
for (int m = 0; m < array.Length; m++)
{
array[m] -= x;
}
mesh.SetTriangles(array, l, calculateBounds: false, x);
}
else
{
mesh.SetTriangles(array, l, calculateBounds: false, 0);
}
}
mesh.RecalculateBounds();
return mesh;
}
public static BlendShape[] GetMeshBlendShapes(Mesh mesh)
{
if (mesh == null)
{
throw new ArgumentNullException("mesh");
}
int vertexCount = mesh.vertexCount;
int blendShapeCount = mesh.blendShapeCount;
if (blendShapeCount == 0)
{
return null;
}
BlendShape[] array = new BlendShape[blendShapeCount];
for (int i = 0; i < blendShapeCount; i++)
{
string blendShapeName = mesh.GetBlendShapeName(i);
int blendShapeFrameCount = mesh.GetBlendShapeFrameCount(i);
BlendShapeFrame[] array2 = new BlendShapeFrame[blendShapeFrameCount];
for (int j = 0; j < blendShapeFrameCount; j++)
{
float blendShapeFrameWeight = mesh.GetBlendShapeFrameWeight(i, j);
Vector3[] deltaVertices = new Vector3[vertexCount];
Vector3[] deltaNormals = new Vector3[vertexCount];
Vector3[] deltaTangents = new Vector3[vertexCount];
mesh.GetBlendShapeFrameVertices(i, j, deltaVertices, deltaNormals, deltaTangents);
array2[j] = new BlendShapeFrame(blendShapeFrameWeight, deltaVertices, deltaNormals, deltaTangents);
}
array[i] = new BlendShape(blendShapeName, array2);
}
return array;
}
public static void ApplyMeshBlendShapes(Mesh mesh, BlendShape[] blendShapes)
{
if (mesh == null)
{
throw new ArgumentNullException("mesh");
}
mesh.ClearBlendShapes();
if (blendShapes == null || blendShapes.Length == 0)
{
return;
}
for (int i = 0; i < blendShapes.Length; i++)
{
string shapeName = blendShapes[i].ShapeName;
BlendShapeFrame[] frames = blendShapes[i].Frames;
if (frames != null)
{
for (int j = 0; j < frames.Length; j++)
{
mesh.AddBlendShapeFrame(shapeName, frames[j].FrameWeight, frames[j].DeltaVertices, frames[j].DeltaNormals, frames[j].DeltaTangents);
}
}
}
}
public static IList<Vector4>[] GetMeshUVs(Mesh mesh)
{
if (mesh == null)
{
throw new ArgumentNullException("mesh");
}
IList<Vector4>[] array = new IList<Vector4>[UVChannelCount];
for (int i = 0; i < UVChannelCount; i++)
{
array[i] = GetMeshUVs(mesh, i);
}
return array;
}
public static IList<Vector2> GetMeshUVs2D(Mesh mesh, int channel)
{
if (mesh == null)
{
throw new ArgumentNullException("mesh");
}
if (channel < 0 || channel >= UVChannelCount)
{
throw new ArgumentOutOfRangeException("channel");
}
List<Vector2> list = new List<Vector2>(mesh.vertexCount);
mesh.GetUVs(channel, list);
return list;
}
public static IList<Vector3> GetMeshUVs3D(Mesh mesh, int channel)
{
if (mesh == null)
{
throw new ArgumentNullException("mesh");
}
if (channel < 0 || channel >= UVChannelCount)
{
throw new ArgumentOutOfRangeException("channel");
}
List<Vector3> list = new List<Vector3>(mesh.vertexCount);
mesh.GetUVs(channel, list);
return list;
}
public static IList<Vector4> GetMeshUVs(Mesh mesh, int channel)
{
if (mesh == null)
{
throw new ArgumentNullException("mesh");
}
if (channel < 0 || channel >= UVChannelCount)
{
throw new ArgumentOutOfRangeException("channel");
}
List<Vector4> list = new List<Vector4>(mesh.vertexCount);
mesh.GetUVs(channel, list);
return list;
}
public static int GetUsedUVComponents(IList<Vector4> uvs)
{
if (uvs == null || uvs.Count == 0)
{
return 0;
}
int num = 0;
foreach (Vector4 uv in uvs)
{
if (num < 1 && uv.x != 0f)
{
num = 1;
}
if (num < 2 && uv.y != 0f)
{
num = 2;
}
if (num < 3 && uv.z != 0f)
{
num = 3;
}
if (num < 4 && uv.w != 0f)
{
num = 4;
break;
}
}
return num;
}
public static Vector2[] ConvertUVsTo2D(IList<Vector4> uvs)
{
if (uvs == null)
{
return null;
}
Vector2[] array = new Vector2[uvs.Count];
for (int i = 0; i < array.Length; i++)
{
Vector4 vector = uvs[i];
array[i] = new Vector2(vector.x, vector.y);
}
return array;
}
public static Vector3[] ConvertUVsTo3D(IList<Vector4> uvs)
{
if (uvs == null)
{
return null;
}
Vector3[] array = new Vector3[uvs.Count];
for (int i = 0; i < array.Length; i++)
{
Vector4 vector = uvs[i];
array[i] = new Vector3(vector.x, vector.y, vector.z);
}
return array;
}
public static Vector2Int[] GetSubMeshIndexMinMax(int[][] indices, out IndexFormat indexFormat)
{
if (indices == null)
{
throw new ArgumentNullException("indices");
}
Vector2Int[] array = new Vector2Int[indices.Length];
indexFormat = IndexFormat.UInt16;
for (int i = 0; i < indices.Length; i++)
{
GetIndexMinMax(indices[i], out var minIndex, out var maxIndex);
array[i] = new Vector2Int(minIndex, maxIndex);
if (maxIndex - minIndex > 65535)
{
indexFormat = IndexFormat.UInt32;
}
}
return array;
}
private static void GetIndexMinMax(int[] indices, out int minIndex, out int maxIndex)
{
if (indices == null || indices.Length == 0)
{
minIndex = (maxIndex = 0);
return;
}
minIndex = int.MaxValue;
maxIndex = int.MinValue;
for (int i = 0; i < indices.Length; i++)
{
if (indices[i] < minIndex)
{
minIndex = indices[i];
}
if (indices[i] > maxIndex)
{
maxIndex = indices[i];
}
}
}
}
}