using System.Collections.Generic; using UnityEngine; using System.IO; using System.Linq; #if UNITY_EDITOR using UnityEditor; #endif namespace UniGLTF.MeshUtility { public static class StaticMeshIntegrator { const string ASSET_SUFFIX = ".mesh.asset"; class Integrator { List m_positions = new List(); List m_normals = new List(); List m_uv = new List(); /* List m_uv2 = new List(); // ToDo List m_uv3 = new List(); // ToDo List m_uv4 = new List(); // ToDo List m_colors = new List(); // ToDo */ List m_subMeshes = new List(); List m_materials = new List(); public List Materials { get { return m_materials; } } public void Push(Matrix4x4 localToRoot, Mesh mesh, Material[] materials) { var offset = m_positions.Count; var hasNormal = m_normals.Count == m_positions.Count; var hasUv = m_uv.Count == m_positions.Count; // attributes m_positions.AddRange(mesh.vertices.Select(x => localToRoot.MultiplyPoint(x))); if(mesh.normals!=null && mesh.normals.Length == mesh.vertexCount) { if (!hasNormal) for (int i = m_normals.Count; i < m_positions.Count; ++i) m_normals.Add(Vector3.zero); m_normals.AddRange(mesh.normals.Select(x => localToRoot.MultiplyVector(x))); } if (mesh.uv != null && mesh.uv.Length == mesh.vertexCount) { if (!hasUv) for (int i = m_uv.Count; i < m_positions.Count; ++i) m_uv.Add(Vector2.zero); m_uv.AddRange(mesh.uv); } // indices for (int i = 0; i < mesh.subMeshCount; ++i) { m_subMeshes.Add(mesh.GetIndices(i).Select(x => offset + x).ToArray()); } // materials m_materials.AddRange(materials); } public Mesh ToMesh() { var mesh = new Mesh(); mesh.name = MeshIntegratorUtility.INTEGRATED_MESH_NAME; mesh.vertices = m_positions.ToArray(); if (m_normals.Count > 0) { if (m_normals.Count < m_positions.Count) for (int i = m_normals.Count; i < m_positions.Count; ++i) m_normals.Add(Vector3.zero); mesh.normals = m_normals.ToArray(); } if (m_uv.Count > 0) { if (m_uv.Count < m_positions.Count) for (int i = m_uv.Count; i < m_positions.Count; ++i) m_uv.Add(Vector2.zero); mesh.uv = m_uv.ToArray(); } mesh.subMeshCount = m_subMeshes.Count; for(int i=0; i(); var filter = t.GetComponent(); if (renderer != null && filter != null && filter.sharedMesh != null && renderer.sharedMaterials!=null && renderer.sharedMaterials.Length == filter.sharedMesh.subMeshCount) { integrator.Push(root.worldToLocalMatrix * t.localToWorldMatrix, filter.sharedMesh, renderer.sharedMaterials); } } return new MeshWithMaterials { Mesh = integrator.ToMesh(), Materials = integrator.Materials.ToArray(), }; } } }