mirror of
https://github.com/ApfelTeeSaft/Slender.git
synced 2026-09-03 03:53:42 +00:00
291 lines
6.7 KiB
C#
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;
|
|
}
|
|
} |