Files
2026-05-23 14:12:25 +02:00

291 lines
6.7 KiB
C#

using UnityEngine;
public class MeshCombineUtility
{
public struct MeshInstance
{
public Mesh mesh;
public int subMeshIndex;
public Matrix4x4 transform;
}
public static Mesh Combine(MeshInstance[] combines, bool generateStrips)
{
// Triangle strips are obsolete in modern Unity
generateStrips = false;
int vertexCount = 0;
int triangleCount = 0;
for (int i = 0; i < combines.Length; i++)
{
MeshInstance instance = combines[i];
if (instance.mesh == null)
continue;
vertexCount += instance.mesh.vertexCount;
triangleCount += instance.mesh.GetTriangles(instance.subMeshIndex).Length;
}
Vector3[] vertices = new Vector3[vertexCount];
Vector3[] normals = new Vector3[vertexCount];
Vector4[] tangents = new Vector4[vertexCount];
Vector2[] uv = new Vector2[vertexCount];
Vector2[] uv2 = new Vector2[vertexCount];
Color[] colors = new Color[vertexCount];
int[] triangles = new int[triangleCount];
int offset = 0;
// Vertices
for (int i = 0; i < combines.Length; i++)
{
MeshInstance instance = combines[i];
if (instance.mesh != null)
{
Copy(
instance.mesh.vertexCount,
instance.mesh.vertices,
vertices,
ref offset,
instance.transform
);
}
}
// Normals
offset = 0;
for (int i = 0; i < combines.Length; i++)
{
MeshInstance instance = combines[i];
if (instance.mesh != null)
{
Matrix4x4 matrix = instance.transform.inverse.transpose;
CopyNormal(
instance.mesh.vertexCount,
instance.mesh.normals,
normals,
ref offset,
matrix
);
}
}
// Tangents
offset = 0;
for (int i = 0; i < combines.Length; i++)
{
MeshInstance instance = combines[i];
if (instance.mesh != null)
{
Matrix4x4 matrix = instance.transform.inverse.transpose;
CopyTangents(
instance.mesh.vertexCount,
instance.mesh.tangents,
tangents,
ref offset,
matrix
);
}
}
// UV
offset = 0;
for (int i = 0; i < combines.Length; i++)
{
MeshInstance instance = combines[i];
if (instance.mesh != null)
{
Copy(
instance.mesh.vertexCount,
instance.mesh.uv,
uv,
ref offset
);
}
}
// UV2
offset = 0;
for (int i = 0; i < combines.Length; i++)
{
MeshInstance instance = combines[i];
if (instance.mesh != null)
{
Copy(
instance.mesh.vertexCount,
instance.mesh.uv2,
uv2,
ref offset
);
}
}
// Colors
offset = 0;
for (int i = 0; i < combines.Length; i++)
{
MeshInstance instance = combines[i];
if (instance.mesh != null)
{
CopyColors(
instance.mesh.vertexCount,
instance.mesh.colors,
colors,
ref offset
);
}
}
// Triangles
int triangleOffset = 0;
int vertexOffset = 0;
for (int i = 0; i < combines.Length; i++)
{
MeshInstance instance = combines[i];
if (instance.mesh == null)
continue;
int[] meshTriangles = instance.mesh.GetTriangles(instance.subMeshIndex);
for (int j = 0; j < meshTriangles.Length; j++)
{
triangles[triangleOffset + j] =
meshTriangles[j] + vertexOffset;
}
triangleOffset += meshTriangles.Length;
vertexOffset += instance.mesh.vertexCount;
}
Mesh mesh = new Mesh();
mesh.name = "Combined Mesh";
mesh.vertices = vertices;
mesh.normals = normals;
mesh.colors = colors;
mesh.uv = uv;
mesh.uv2 = uv2;
mesh.tangents = tangents;
mesh.triangles = triangles;
return mesh;
}
private static void Copy(
int vertexCount,
Vector3[] src,
Vector3[] dst,
ref int offset,
Matrix4x4 transform)
{
if (src == null)
return;
for (int i = 0; i < src.Length; i++)
{
dst[i + offset] = transform.MultiplyPoint(src[i]);
}
offset += vertexCount;
}
private static void CopyNormal(
int vertexCount,
Vector3[] src,
Vector3[] dst,
ref int offset,
Matrix4x4 transform)
{
if (src == null)
return;
for (int i = 0; i < src.Length; i++)
{
dst[i + offset] =
transform.MultiplyVector(src[i]).normalized;
}
offset += vertexCount;
}
private static void Copy(
int vertexCount,
Vector2[] src,
Vector2[] dst,
ref int offset)
{
if (src == null)
return;
for (int i = 0; i < src.Length; i++)
{
dst[i + offset] = src[i];
}
offset += vertexCount;
}
private static void CopyColors(
int vertexCount,
Color[] src,
Color[] dst,
ref int offset)
{
if (src == null)
return;
for (int i = 0; i < src.Length; i++)
{
dst[i + offset] = src[i];
}
offset += vertexCount;
}
private static void CopyTangents(
int vertexCount,
Vector4[] src,
Vector4[] dst,
ref int offset,
Matrix4x4 transform)
{
if (src == null)
return;
for (int i = 0; i < src.Length; i++)
{
Vector4 tangent = src[i];
Vector3 v = new Vector3(
tangent.x,
tangent.y,
tangent.z
);
v = transform.MultiplyVector(v).normalized;
dst[i + offset] =
new Vector4(v.x, v.y, v.z, tangent.w);
}
offset += vertexCount;
}
}