add floorplan 2.0 package
This commit is contained in:
+298
@@ -0,0 +1,298 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.UI;
|
||||
|
||||
public class MeshCombiner : MonoBehaviour
|
||||
{
|
||||
GameObject wallMesh;
|
||||
GameObject floorMesh;
|
||||
public void Awake()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
wallMesh = new GameObject("WallMesh", typeof(MeshFilter), typeof(Renderer));
|
||||
floorMesh = new GameObject("FloorMesh", typeof(MeshFilter), typeof(Renderer));
|
||||
print(transform.childCount);
|
||||
for (int i = transform.childCount - 1; i >= 0; --i)
|
||||
{
|
||||
Transform child = transform.GetChild(i);
|
||||
if (child.name == "Floor")
|
||||
child.SetParent(floorMesh.transform, true);
|
||||
else if (child.name == "Walls")
|
||||
child.SetParent(wallMesh.transform, true);
|
||||
}
|
||||
wallMesh.transform.parent = transform;
|
||||
floorMesh.transform.parent = transform;
|
||||
|
||||
CombineWalls();
|
||||
CombineFloor();
|
||||
ClearChildren(floorMesh.transform);
|
||||
ClearChildren(wallMesh.transform);
|
||||
SplitMesh(floorMesh.GetComponent<MeshFilter>());
|
||||
SplitMesh(wallMesh.GetComponent<MeshFilter>());
|
||||
|
||||
for (int i = 0; i < floorMesh.transform.childCount; i++)
|
||||
{
|
||||
Simplify(floorMesh.transform.GetChild(i).GetComponent<MeshFilter>());
|
||||
}
|
||||
for (int i = 0; i < wallMesh.transform.childCount; i++)
|
||||
{
|
||||
Simplify(wallMesh.transform.GetChild(i).GetComponent<MeshFilter>());
|
||||
}
|
||||
}
|
||||
|
||||
void ClearChildren(Transform t)
|
||||
{
|
||||
for(int i=0; i<t.childCount; i++)
|
||||
{
|
||||
Destroy(t.GetChild(i).gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void Simplify(MeshFilter mf)
|
||||
{
|
||||
if (mf != null)
|
||||
{
|
||||
mf.mesh.Weld(0.00000328f, 1f);
|
||||
mf.mesh.Simplify();
|
||||
}
|
||||
}
|
||||
|
||||
void SplitMesh(MeshFilter mf)
|
||||
{
|
||||
for (int i = 0; i < mf.mesh.subMeshCount; i++)
|
||||
{
|
||||
GameObject gO = new GameObject();
|
||||
gO.name = mf.gameObject.name + " submesh " + (i+1).ToString();
|
||||
gO.transform.parent = mf.gameObject.transform;
|
||||
MeshFilter filter = gO.AddComponent<MeshFilter>();
|
||||
filter.mesh=mf.mesh.GetSubmesh(i);
|
||||
Renderer r = gO.AddComponent<MeshRenderer>();
|
||||
r.material = mf.gameObject.GetComponent<Renderer>().materials[i];
|
||||
MeshCollider c = gO.AddComponent<MeshCollider>();
|
||||
c.sharedMesh = filter.mesh;
|
||||
}
|
||||
Destroy(mf.gameObject.GetComponent<Renderer>());
|
||||
Destroy(mf.gameObject.GetComponent<MeshCollider>());
|
||||
}
|
||||
|
||||
private void CombineWalls()
|
||||
{
|
||||
Vector3 basePosition = transform.position;
|
||||
Quaternion baseRotation = transform.rotation;
|
||||
transform.position = Vector3.zero;
|
||||
transform.rotation = Quaternion.identity;
|
||||
|
||||
|
||||
|
||||
ArrayList materials = new ArrayList();
|
||||
ArrayList combineInstanceArrays = new ArrayList();
|
||||
MeshFilter[] meshFilters = wallMesh.GetComponentsInChildren<MeshFilter>();
|
||||
|
||||
//Linq solution to make sure we don't combine any of the doors(a door is easily identifiable by it's rigidbody component, so we look for that).
|
||||
meshFilters = meshFilters.Where((source, index) => !(source.transform.name == "FloorMesh" || source.transform.name == "WallMesh" || source.transform.GetComponent<Rigidbody>() || source.transform.GetComponentInParent<Rigidbody>())).ToArray();
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
MeshRenderer meshRenderer = meshFilter.GetComponent<MeshRenderer>();
|
||||
if (!meshRenderer ||
|
||||
!meshFilter.sharedMesh ||
|
||||
meshRenderer.sharedMaterials.Length != meshFilter.sharedMesh.subMeshCount)
|
||||
{
|
||||
print(meshFilter.gameObject.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
|
||||
{
|
||||
if (meshRenderer.sharedMaterials[s]){
|
||||
int materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials[s].name);
|
||||
if (materialArrayIndex == -1)
|
||||
{
|
||||
materials.Add(meshRenderer.sharedMaterials[s]);
|
||||
materialArrayIndex = materials.Count - 1;
|
||||
}
|
||||
combineInstanceArrays.Add(new ArrayList());
|
||||
|
||||
CombineInstance combineInstance = new CombineInstance();
|
||||
combineInstance.transform = meshRenderer.transform.localToWorldMatrix;
|
||||
combineInstance.subMeshIndex = s;
|
||||
combineInstance.mesh = meshFilter.sharedMesh;
|
||||
(combineInstanceArrays[materialArrayIndex] as ArrayList).Add(combineInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get / Create mesh filter & renderer
|
||||
MeshFilter meshFilterCombine = wallMesh.GetComponent<MeshFilter>();
|
||||
if (meshFilterCombine == null)
|
||||
{
|
||||
meshFilterCombine = wallMesh.AddComponent<MeshFilter>();
|
||||
}
|
||||
MeshRenderer meshRendererCombine = gameObject.GetComponent<MeshRenderer>();
|
||||
if (meshRendererCombine == null)
|
||||
{
|
||||
meshRendererCombine = wallMesh.AddComponent<MeshRenderer>();
|
||||
}
|
||||
|
||||
// Combine by material index into per-material meshes
|
||||
// also, Create CombineInstance array for next step
|
||||
Mesh[] meshes = new Mesh[materials.Count];
|
||||
CombineInstance[] combineInstances = new CombineInstance[materials.Count];
|
||||
|
||||
for (int m = 0; m < materials.Count; m++)
|
||||
{
|
||||
CombineInstance[] combineInstanceArray = (combineInstanceArrays[m] as ArrayList).ToArray(typeof(CombineInstance)) as CombineInstance[];
|
||||
meshes[m] = new Mesh();
|
||||
meshes[m].CombineMeshes(combineInstanceArray, true, true);
|
||||
|
||||
combineInstances[m] = new CombineInstance();
|
||||
combineInstances[m].mesh = meshes[m];
|
||||
combineInstances[m].subMeshIndex = 0;
|
||||
|
||||
}
|
||||
|
||||
// Combine into one
|
||||
meshFilterCombine.sharedMesh = new Mesh();
|
||||
meshFilterCombine.sharedMesh.CombineMeshes(combineInstances, false, false);
|
||||
|
||||
// Destroy other meshes
|
||||
foreach (Mesh oldMesh in meshes)
|
||||
{
|
||||
oldMesh.Clear();
|
||||
DestroyImmediate(oldMesh);
|
||||
}
|
||||
|
||||
// Assign materials
|
||||
Material[] materialsArray = materials.ToArray(typeof(Material)) as Material[];
|
||||
meshRendererCombine.materials = materialsArray;
|
||||
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
|
||||
if (!meshFilter || meshFilter.transform.GetComponent<Rigidbody>() || meshFilter.transform.GetComponentInParent<Rigidbody>() || meshFilter.transform.GetComponentInChildren<Rigidbody>())
|
||||
continue;
|
||||
print(meshFilter.gameObject.transform.parent.name);
|
||||
DestroyImmediate(meshFilter.gameObject.transform.parent.gameObject);
|
||||
}
|
||||
wallMesh.transform.position = basePosition;
|
||||
wallMesh.transform.rotation = baseRotation;
|
||||
wallMesh.AddComponent<MeshCollider>().sharedMesh = wallMesh.GetComponent<MeshFilter>().sharedMesh;
|
||||
}
|
||||
private void CombineFloor()
|
||||
{
|
||||
Vector3 basePosition = transform.position;
|
||||
Quaternion baseRotation = transform.rotation;
|
||||
transform.position = Vector3.zero;
|
||||
transform.rotation = Quaternion.identity;
|
||||
|
||||
|
||||
|
||||
ArrayList materials = new ArrayList();
|
||||
ArrayList combineInstanceArrays = new ArrayList();
|
||||
MeshFilter[] meshFilters = floorMesh.GetComponentsInChildren<MeshFilter>();
|
||||
|
||||
//Linq solution to make sure we don't combine any of the doors(a door is easily identifiable by it's rigidbody component, so we look for that).
|
||||
meshFilters = meshFilters.Where((source, index) => !(source.transform.name=="FloorMesh" || source.transform.name=="WallMesh" || source.transform.GetComponent<Rigidbody>() || source.transform.GetComponentInParent<Rigidbody>())).ToArray();
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
MeshRenderer meshRenderer = meshFilter.GetComponent<MeshRenderer>();
|
||||
if (!meshRenderer ||
|
||||
!meshFilter.sharedMesh ||
|
||||
meshRenderer.sharedMaterials.Length != meshFilter.sharedMesh.subMeshCount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
|
||||
{
|
||||
if (meshRenderer.sharedMaterials[s])
|
||||
{
|
||||
int materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials[s].name);
|
||||
if (materialArrayIndex == -1)
|
||||
{
|
||||
materials.Add(meshRenderer.sharedMaterials[s]);
|
||||
materialArrayIndex = materials.Count - 1;
|
||||
}
|
||||
combineInstanceArrays.Add(new ArrayList());
|
||||
|
||||
CombineInstance combineInstance = new CombineInstance();
|
||||
combineInstance.transform = meshRenderer.transform.localToWorldMatrix;
|
||||
combineInstance.subMeshIndex = s;
|
||||
combineInstance.mesh = meshFilter.sharedMesh;
|
||||
(combineInstanceArrays[materialArrayIndex] as ArrayList).Add(combineInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get / Create mesh filter & renderer
|
||||
MeshFilter meshFilterCombine = floorMesh.GetComponent<MeshFilter>();
|
||||
if (meshFilterCombine == null)
|
||||
{
|
||||
meshFilterCombine = floorMesh.AddComponent<MeshFilter>();
|
||||
}
|
||||
MeshRenderer meshRendererCombine = gameObject.GetComponent<MeshRenderer>();
|
||||
if (meshRendererCombine == null)
|
||||
{
|
||||
meshRendererCombine = floorMesh.AddComponent<MeshRenderer>();
|
||||
}
|
||||
|
||||
// Combine by material index into per-material meshes
|
||||
// also, Create CombineInstance array for next step
|
||||
Mesh[] meshes = new Mesh[materials.Count];
|
||||
CombineInstance[] combineInstances = new CombineInstance[materials.Count];
|
||||
|
||||
for (int m = 0; m < materials.Count; m++)
|
||||
{
|
||||
CombineInstance[] combineInstanceArray = (combineInstanceArrays[m] as ArrayList).ToArray(typeof(CombineInstance)) as CombineInstance[];
|
||||
meshes[m] = new Mesh();
|
||||
meshes[m].CombineMeshes(combineInstanceArray, true, true);
|
||||
|
||||
combineInstances[m] = new CombineInstance();
|
||||
combineInstances[m].mesh = meshes[m];
|
||||
combineInstances[m].subMeshIndex = 0;
|
||||
}
|
||||
|
||||
// Combine into one
|
||||
meshFilterCombine.sharedMesh = new Mesh();
|
||||
meshFilterCombine.sharedMesh.CombineMeshes(combineInstances, false, false);
|
||||
|
||||
// Destroy other meshes
|
||||
foreach (Mesh oldMesh in meshes)
|
||||
{
|
||||
oldMesh.Clear();
|
||||
DestroyImmediate(oldMesh);
|
||||
}
|
||||
|
||||
// Assign materials
|
||||
Material[] materialsArray = materials.ToArray(typeof(Material)) as Material[];
|
||||
meshRendererCombine.materials = materialsArray;
|
||||
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
|
||||
if (!meshFilter || meshFilter.transform.GetComponent<Rigidbody>() || meshFilter.transform.GetComponentInParent<Rigidbody>() || meshFilter.transform.GetComponentInChildren<Rigidbody>())
|
||||
continue;
|
||||
DestroyImmediate(meshFilter.gameObject.transform.parent.gameObject);
|
||||
}
|
||||
floorMesh.transform.position = basePosition;
|
||||
floorMesh.transform.rotation = baseRotation;
|
||||
floorMesh.AddComponent<MeshCollider>().sharedMesh = floorMesh.GetComponent<MeshFilter>().sharedMesh;
|
||||
}
|
||||
|
||||
private int Contains(ArrayList searchList, string searchName)
|
||||
{
|
||||
for (int i = 0; i < searchList.Count; i++)
|
||||
{
|
||||
if (((Material)searchList[i]).name == searchName)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user