using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace LunarCatsStudio.SuperCombiner
{
///
/// Submesh splitter.
/// A helper class that offers possibility to split submeshes into separate meshes
///
public class SubmeshSplitter {
///
/// Extract a specific submesh at a given index from a mesh and return it as a new Mesh
///
/// The mesh containing subMeshes
/// The index of the subMesh to extract
///
public static Mesh ExtractSubmesh(Mesh mesh, int index)
{
// Create the new mesh corresponding to the submesh at index i
Mesh extractedSubMesh = CreateMeshFromSubmesh(mesh, new int[] { index }, index);
// Return the extracted subMesh
return extractedSubMesh;
}
///
/// Extract all the submeshes at given indexes into a separate mesh in a new GameObject
///
///
/// List of ths submeshes indexes to extract
/// Only used to name the new created mesh
/// Returns a new GameObject with MeshRenderer and MeshFilter components.
public static MeshRenderer SplitSubmeshes(MeshFilter meshFilter, int[] subMeshesIndex, int index)
{
if(subMeshesIndex.Length == 0)
{
Logger.Instance.AddLog("SuperCombiner", "Could not split submeshes of mesh " + meshFilter + " because indexes is null", Logger.LogLevel.LOG_ERROR);
return null;
}
else if(meshFilter.sharedMesh == null)
{
Logger.Instance.AddLog("SuperCombiner", "Could not split submeshes of mesh " + meshFilter + " because it has no mesh", Logger.LogLevel.LOG_ERROR);
return null;
}
Mesh mesh = meshFilter.sharedMesh;
Material[] materials = meshFilter.GetComponent().sharedMaterials;
Material[] splitMaterials = new Material[subMeshesIndex.Length];
for(int i=0; i();
}
///
/// Extract all the submeshes at given indexes into a separate mesh in a new GameObject
///
///
///
///
///
public static SkinnedMeshRenderer SplitSubmeshes(SkinnedMeshRenderer skinnedMesh, int[] subMeshesIndex, int index)
{
if (subMeshesIndex.Length == 0)
{
Logger.Instance.AddLog("SuperCombiner", "Could not split submeshes of mesh " + skinnedMesh + " because indexes is null", Logger.LogLevel.LOG_ERROR);
return null;
}
else if (skinnedMesh.sharedMesh == null)
{
Logger.Instance.AddLog("SuperCombiner", "Could not split submeshes of mesh " + skinnedMesh + " because it has no mesh", Logger.LogLevel.LOG_ERROR);
return null;
}
Mesh mesh = skinnedMesh.sharedMesh;
Material[] materials = skinnedMesh.sharedMaterials;
Material[] splitMaterials = new Material[subMeshesIndex.Length];
for (int i = 0; i < subMeshesIndex.Length; i++)
{
splitMaterials[i] = materials[subMeshesIndex[0]];
}
// Create the new mesh corresponding to the submesh at index i
Mesh newMesh = CreateMeshFromSubmesh(mesh, subMeshesIndex, index);
// Generate target GameObject with MeshFilter and MeshRenderer
GameObject go = GenerateGameObject(skinnedMesh.transform, true, skinnedMesh.gameObject.name, newMesh, splitMaterials);
// Return the new meshRenderer component
return go.GetComponent();
}
///
/// Creates the mesh corresponding to a specific submesh.
///
///
///
///
///
private static Mesh CreateMeshFromSubmesh(Mesh mesh, int[] subMeshesIndex, int index)
{
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
Vector4[] tangents = mesh.tangents;
Color[] colors = mesh.colors;
Vector2[] uvs = mesh.uv;
Vector2[] uvs2 = mesh.uv2;
Mesh newMesh = new Mesh();
newMesh.name = mesh.name + "_" + index;
newMesh.vertices = vertices;
newMesh.normals = normals;
newMesh.tangents = tangents;
newMesh.colors = colors;
newMesh.uv = uvs;
newMesh.uv2 = uvs2;
newMesh.subMeshCount = subMeshesIndex.Length;
for (int i=0; i
/// Generates a new game object.
///
///
///
///
///
///
///
private static GameObject GenerateGameObject(Transform parent, bool skinnedMesh, string name_p, Mesh newMesh_p, Material[] mat)
{
GameObject go = new GameObject(name_p);
go.transform.SetParent(parent);
go.transform.localPosition = Vector3.zero;
go.transform.localRotation = Quaternion.identity;
go.transform.localScale = Vector3.one;
MeshFilter meshFilter = go.AddComponent();
meshFilter.mesh = newMesh_p;
if(skinnedMesh)
{
SkinnedMeshRenderer meshRenderer = go.AddComponent();
meshRenderer.materials = mat;
} else
{
MeshRenderer meshRenderer = go.AddComponent();
meshRenderer.materials = mat;
}
return go;
}
}
}