225 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using UnityEngine;
 | 
						|
using System.Collections;
 | 
						|
 | 
						|
public class MeshCombineUtility
 | 
						|
{
 | 
						|
 | 
						|
    public struct MeshInstance
 | 
						|
    {
 | 
						|
        public Mesh mesh;
 | 
						|
        public int subMeshIndex;
 | 
						|
        public Matrix4x4 transform;
 | 
						|
    }
 | 
						|
 | 
						|
    public static Mesh Combine(MeshInstance[] combines, bool generateStrips)
 | 
						|
    {
 | 
						|
        int vertexCount = 0;
 | 
						|
        int triangleCount = 0;
 | 
						|
        int stripCount = 0;
 | 
						|
        foreach (MeshInstance combine in combines)
 | 
						|
        {
 | 
						|
            if (combine.mesh)
 | 
						|
            {
 | 
						|
                vertexCount += combine.mesh.vertexCount;
 | 
						|
 | 
						|
                if (generateStrips)
 | 
						|
                {
 | 
						|
                    // SUBOPTIMAL FOR PERFORMANCE
 | 
						|
                    int curStripCount = combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length;
 | 
						|
                    if (curStripCount != 0)
 | 
						|
                    {
 | 
						|
                        if (stripCount != 0)
 | 
						|
                        {
 | 
						|
                            if ((stripCount & 1) == 1)
 | 
						|
                                stripCount += 3;
 | 
						|
                            else
 | 
						|
                                stripCount += 2;
 | 
						|
                        }
 | 
						|
                        stripCount += curStripCount;
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        generateStrips = false;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // Precomputed how many triangles we need instead
 | 
						|
        if (!generateStrips)
 | 
						|
        {
 | 
						|
            foreach (MeshInstance combine in combines)
 | 
						|
            {
 | 
						|
                if (combine.mesh)
 | 
						|
                {
 | 
						|
                    triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        Vector3[] vertices = new Vector3[vertexCount];
 | 
						|
        Vector3[] normals = new Vector3[vertexCount];
 | 
						|
        Vector4[] tangents = new Vector4[vertexCount];
 | 
						|
        Vector2[] uv = new Vector2[vertexCount];
 | 
						|
        Vector2[] uv1 = new Vector2[vertexCount];
 | 
						|
        Color[] colors = new Color[vertexCount];
 | 
						|
 | 
						|
        int[] triangles = new int[triangleCount];
 | 
						|
        int[] strip = new int[stripCount];
 | 
						|
 | 
						|
        int offset;
 | 
						|
 | 
						|
        offset = 0;
 | 
						|
        foreach (MeshInstance combine in combines)
 | 
						|
        {
 | 
						|
            if (combine.mesh)
 | 
						|
                Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform);
 | 
						|
        }
 | 
						|
 | 
						|
        offset = 0;
 | 
						|
        foreach (MeshInstance combine in combines)
 | 
						|
        {
 | 
						|
            if (combine.mesh)
 | 
						|
            {
 | 
						|
                Matrix4x4 invTranspose = combine.transform;
 | 
						|
                invTranspose = invTranspose.inverse.transpose;
 | 
						|
                CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose);
 | 
						|
            }
 | 
						|
 | 
						|
        }
 | 
						|
        offset = 0;
 | 
						|
        foreach (MeshInstance combine in combines)
 | 
						|
        {
 | 
						|
            if (combine.mesh)
 | 
						|
            {
 | 
						|
                Matrix4x4 invTranspose = combine.transform;
 | 
						|
                invTranspose = invTranspose.inverse.transpose;
 | 
						|
                CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose);
 | 
						|
            }
 | 
						|
 | 
						|
        }
 | 
						|
        offset = 0;
 | 
						|
        foreach (MeshInstance combine in combines)
 | 
						|
        {
 | 
						|
            if (combine.mesh)
 | 
						|
                Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset);
 | 
						|
        }
 | 
						|
 | 
						|
        offset = 0;
 | 
						|
        foreach (MeshInstance combine in combines)
 | 
						|
        {
 | 
						|
            if (combine.mesh)
 | 
						|
                Copy(combine.mesh.vertexCount, combine.mesh.uv1, uv1, ref offset);
 | 
						|
        }
 | 
						|
 | 
						|
        offset = 0;
 | 
						|
        foreach (MeshInstance combine in combines)
 | 
						|
        {
 | 
						|
            if (combine.mesh)
 | 
						|
                CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset);
 | 
						|
        }
 | 
						|
 | 
						|
        int triangleOffset = 0;
 | 
						|
        int stripOffset = 0;
 | 
						|
        int vertexOffset = 0;
 | 
						|
        foreach (MeshInstance combine in combines)
 | 
						|
        {
 | 
						|
            if (combine.mesh)
 | 
						|
            {
 | 
						|
                if (generateStrips)
 | 
						|
                {
 | 
						|
                    int[] inputstrip = combine.mesh.GetTriangleStrip(combine.subMeshIndex);
 | 
						|
                    if (stripOffset != 0)
 | 
						|
                    {
 | 
						|
                        if ((stripOffset & 1) == 1)
 | 
						|
                        {
 | 
						|
                            strip[stripOffset + 0] = strip[stripOffset - 1];
 | 
						|
                            strip[stripOffset + 1] = inputstrip[0] + vertexOffset;
 | 
						|
                            strip[stripOffset + 2] = inputstrip[0] + vertexOffset;
 | 
						|
                            stripOffset += 3;
 | 
						|
                        }
 | 
						|
                        else
 | 
						|
                        {
 | 
						|
                            strip[stripOffset + 0] = strip[stripOffset - 1];
 | 
						|
                            strip[stripOffset + 1] = inputstrip[0] + vertexOffset;
 | 
						|
                            stripOffset += 2;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    for (int i = 0; i < inputstrip.Length; i++)
 | 
						|
                    {
 | 
						|
                        strip[i + stripOffset] = inputstrip[i] + vertexOffset;
 | 
						|
                    }
 | 
						|
                    stripOffset += inputstrip.Length;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex);
 | 
						|
                    for (int i = 0; i < inputtriangles.Length; i++)
 | 
						|
                    {
 | 
						|
                        triangles[i + triangleOffset] = inputtriangles[i] + vertexOffset;
 | 
						|
                    }
 | 
						|
                    triangleOffset += inputtriangles.Length;
 | 
						|
                }
 | 
						|
 | 
						|
                vertexOffset += combine.mesh.vertexCount;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        Mesh mesh = new Mesh();
 | 
						|
        mesh.name = "Combined Mesh";
 | 
						|
        mesh.vertices = vertices;
 | 
						|
        mesh.normals = normals;
 | 
						|
        mesh.colors = colors;
 | 
						|
        mesh.uv = uv;
 | 
						|
        mesh.uv1 = uv1;
 | 
						|
        mesh.tangents = tangents;
 | 
						|
        if (generateStrips)
 | 
						|
            mesh.SetTriangleStrip(strip, 0);
 | 
						|
        else
 | 
						|
            mesh.triangles = triangles;
 | 
						|
 | 
						|
        return mesh;
 | 
						|
    }
 | 
						|
 | 
						|
    static void Copy(int vertexcount, Vector3[] src, Vector3[] dst, ref int offset, Matrix4x4 transform)
 | 
						|
    {
 | 
						|
        for (int i = 0; i < src.Length; i++)
 | 
						|
            dst[i + offset] = transform.MultiplyPoint(src[i]);
 | 
						|
        offset += vertexcount;
 | 
						|
    }
 | 
						|
 | 
						|
    static void CopyNormal(int vertexcount, Vector3[] src, Vector3[] dst, ref int offset, Matrix4x4 transform)
 | 
						|
    {
 | 
						|
        for (int i = 0; i < src.Length; i++)
 | 
						|
            dst[i + offset] = transform.MultiplyVector(src[i]).normalized;
 | 
						|
        offset += vertexcount;
 | 
						|
    }
 | 
						|
 | 
						|
    static void Copy(int vertexcount, Vector2[] src, Vector2[] dst, ref int offset)
 | 
						|
    {
 | 
						|
        for (int i = 0; i < src.Length; i++)
 | 
						|
            dst[i + offset] = src[i];
 | 
						|
        offset += vertexcount;
 | 
						|
    }
 | 
						|
 | 
						|
    static void CopyColors(int vertexcount, Color[] src, Color[] dst, ref int offset)
 | 
						|
    {
 | 
						|
        for (int i = 0; i < src.Length; i++)
 | 
						|
            dst[i + offset] = src[i];
 | 
						|
        offset += vertexcount;
 | 
						|
    }
 | 
						|
 | 
						|
    static void CopyTangents(int vertexcount, Vector4[] src, Vector4[] dst, ref int offset, Matrix4x4 transform)
 | 
						|
    {
 | 
						|
        for (int i = 0; i < src.Length; i++)
 | 
						|
        {
 | 
						|
            Vector4 p4 = src[i];
 | 
						|
            Vector3 p = new Vector3(p4.x, p4.y, p4.z);
 | 
						|
            p = transform.MultiplyVector(p).normalized;
 | 
						|
            dst[i + offset] = new Vector4(p.x, p.y, p.z, p4.w);
 | 
						|
        }
 | 
						|
 | 
						|
        offset += vertexcount;
 | 
						|
    }
 | 
						|
} |