154 lines
5.7 KiB
C#
154 lines
5.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using NaughtyAttributes;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace Util.Mesh
|
|
{
|
|
public class MeshCombinerStart : MonoBehaviour
|
|
{
|
|
|
|
[SerializeField] private MeshCombiner meshCombiner;
|
|
private void Start()
|
|
{
|
|
meshCombiner.CombineMeshes(true);
|
|
}
|
|
|
|
private int GetTotalPolygons(Transform parent, MeshCombiner combiner)
|
|
{
|
|
MeshFilter[] meshFilters = combiner.GetMeshFiltersToCombine();
|
|
MeshRenderer[] meshRenderers = new MeshRenderer[meshFilters.Length];
|
|
meshRenderers[0] = GetComponent<MeshRenderer>(); // Our (parent) MeshRenderer.
|
|
List<Material> uniqueMaterialsList = new List<Material>();
|
|
for (int i = 0; i < meshFilters.Length - 1; i++)
|
|
{
|
|
meshRenderers[i + 1] = meshFilters[i + 1].GetComponent<MeshRenderer>();
|
|
if (meshRenderers[i + 1] != null)
|
|
{
|
|
Material[] materials = meshRenderers[i + 1].sharedMaterials; // Get all Materials from child Mesh.
|
|
for (int j = 0; j < materials.Length; j++)
|
|
{
|
|
if (!uniqueMaterialsList
|
|
.Contains(materials[j])) // If Material doesn't exists in the list then add it.
|
|
{
|
|
uniqueMaterialsList.Add(materials[j]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
List<CombineInstance> finalMeshCombineInstancesList = new List<CombineInstance>();
|
|
long verticesLength = 0;
|
|
for (int i = 0;
|
|
i < uniqueMaterialsList.Count;
|
|
i++) // Create each Mesh (submesh) from Meshes with the same Material.
|
|
{
|
|
List<CombineInstance> submeshCombineInstancesList = new List<CombineInstance>();
|
|
|
|
for (int j = 0; j < meshFilters.Length - 1; j++) // Get only childeren Meshes (skip our Mesh).
|
|
{
|
|
if (meshRenderers[j + 1] != null)
|
|
{
|
|
Material[] submeshMaterials =
|
|
meshRenderers[j + 1].sharedMaterials; // Get all Materials from child Mesh.
|
|
for (int k = 0; k < submeshMaterials.Length; k++)
|
|
{
|
|
|
|
if (uniqueMaterialsList[i] == submeshMaterials[k])
|
|
{
|
|
CombineInstance combineInstance = new CombineInstance();
|
|
combineInstance.subMeshIndex = k; // Mesh may consist of smaller parts - submeshes.
|
|
|
|
combineInstance.mesh = meshFilters[j + 1].sharedMesh;
|
|
combineInstance.transform = meshFilters[j + 1].transform.localToWorldMatrix;
|
|
submeshCombineInstancesList.Add(combineInstance);
|
|
verticesLength += combineInstance.mesh.vertices.Length;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (int)verticesLength;
|
|
}
|
|
|
|
[Button("Get Value")]
|
|
public void GetValue()
|
|
{
|
|
if (meshCombiner == null) meshCombiner = GetComponent<MeshCombiner>();
|
|
var val = GetTotalPolygons(transform,meshCombiner);
|
|
if (val <= MeshCombiner.Mesh16BitBufferVertexLimit)
|
|
Debug.Log("<color=#00cc00><b>Mesh will created with "+val+" vertices</b></color>");
|
|
else
|
|
Debug.Log("<color=#ff3300><b>Mesh will created with "+val+" over 65535 vertices.</b></color>");
|
|
|
|
}
|
|
|
|
[Button("Combine")]
|
|
public void Combine()
|
|
{
|
|
if (meshCombiner == null) meshCombiner = GetComponent<MeshCombiner>();
|
|
meshCombiner.CreateMultiMaterialMesh = true;
|
|
meshCombiner.GenerateUVMap = true;
|
|
meshCombiner.CombineMeshes(true);
|
|
}
|
|
|
|
[Button("Split all Meshes")]
|
|
public void SplitMeshes()
|
|
{
|
|
|
|
var allMeshes = GetComponentsInChildren<MeshRenderer>();
|
|
foreach (var meshes in allMeshes)
|
|
{
|
|
SplitMesh(meshes);
|
|
}
|
|
Debugger.Logger($"Splited {gameObject.name}");
|
|
}
|
|
|
|
public void SplitMesh(MeshRenderer mesh)
|
|
{
|
|
MeshFilter mf = mesh.GetComponent<MeshFilter>();
|
|
MeshRenderer mr = mesh.GetComponent<MeshRenderer>();
|
|
if (mf == null || mr == null) return;
|
|
|
|
UnityEngine.Mesh originalMesh = mf.sharedMesh;
|
|
if (originalMesh == null || originalMesh.subMeshCount < 1) return;
|
|
|
|
int subMeshCount = originalMesh.subMeshCount;
|
|
var preset = new GameObject(mesh.name,typeof(MeshFilter), typeof(MeshRenderer));
|
|
for (int i = 0; i < subMeshCount; i++)
|
|
{
|
|
UnityEngine.Mesh newMesh = new UnityEngine.Mesh
|
|
{
|
|
vertices = originalMesh.vertices,
|
|
normals = originalMesh.normals,
|
|
uv = originalMesh.uv,
|
|
triangles = originalMesh.GetTriangles(i)
|
|
};
|
|
var part = Instantiate(preset, mesh.transform);
|
|
part.GetComponent<MeshFilter>().mesh = newMesh;
|
|
part.GetComponent<MeshRenderer>().sharedMaterial = (i < mr.sharedMaterials.Length) ? mr.sharedMaterials[i] : mr.sharedMaterial;
|
|
}
|
|
DestroyImmediate(preset);
|
|
// DestroyImmediate(mesh)?;
|
|
}
|
|
[Button("Center Mesh")]
|
|
void CenterMeshPivot()
|
|
{
|
|
UnityEngine.Mesh mesh = GetComponent<UnityEngine.MeshFilter>().sharedMesh;
|
|
|
|
Vector3 center = mesh.bounds.center;
|
|
|
|
Vector3[] vertices = mesh.vertices;
|
|
for (int i = 0; i < vertices.Length; i++)
|
|
{
|
|
vertices[i] -= center;
|
|
}
|
|
|
|
mesh.vertices = vertices;
|
|
mesh.RecalculateBounds();
|
|
mesh.RecalculateNormals();
|
|
|
|
transform.position += center;
|
|
}
|
|
}
|
|
} |