Example #1
0
        public static bool combineMeshes(GameObject parent, Vector3 parentPosition, Quaternion parentRotation)
        {
            //bool showCompileReady = true;
            //double timeStart = EditorApplication.timeSinceStartup;
            List <CustomMesh>       meshes           = new List <CustomMesh> ();
            List <MeshesByMaterial> meshesByMaterial = new List <MeshesByMaterial> ();

            int             numChildren = parent.transform.childCount;
            int             childIdx    = 0;
            List <Material> materials   = new List <Material> ();

            Bounds gridBounds  = new Bounds();
            bool   foundBounds = false;

            //Build custom meshes
            foreach (Transform child in parent.transform)
            {
                // Get bounds
                Renderer[]      renderers = child.GetComponentsInChildren <Renderer> ();
                List <Renderer> rds       = new List <Renderer> (renderers);

                if (rds.Count == 0)
                {
                    continue;
                }
                for (int i = 0; i < rds.Count; i++)
                {
                    Renderer r        = rds [i];
                    Material material = r.sharedMaterial;
                    if (material)
                    {
                        if (!materials.Contains(material))
                        {
                            materials.Add(material);
                        }
                    }

                    if (!foundBounds)
                    {
                        foundBounds = true;
                        gridBounds  = new Bounds(r.bounds.center, r.bounds.size);
                    }
                    else
                    {
                        gridBounds.Encapsulate(r.bounds);
                    }
                }

                MeshFilter[]      ccmfs = child.GetComponentsInChildren <MeshFilter> ();
                List <MeshFilter> mfs   = new List <MeshFilter> (ccmfs);

                for (int i = 0; i < mfs.Count; i++)
                {
                    MeshFilter mf = mfs [i];
                    Renderer   r  = mf.gameObject.GetComponent <Renderer> ();
                    if (!r)
                    {
                        continue;
                    }
                    Material material = r.sharedMaterial;
                    if (!material || !materials.Contains(material))
                    {
                        continue;
                    }

                    int materialIndex = materials.IndexOf(material);

                    bool cancel = false;

                    Mesh   mesh = mf.sharedMesh;
                    string name = child.name;
                    if (mesh == null)
                    {
                        continue;
                    }

                    float percent = ((float)childIdx) / ((float)numChildren);
                    cancel = EditorUtility.DisplayCancelableProgressBar("Creating custom meshes...", "(" + childIdx + "/" + numChildren + ")  " + name, percent);
                    if (cancel)
                    {
                        return(true);
                    }

                    // Keeps this mesh but compares to others. No subdivision is performed.
                    bool keep = (child.tag == "keep");
                    // Keeps this mesh without comparing to others. No subdivision is performed.
                    bool noCompare = (child.tag == "nocompare");

                    CustomMesh cm = buildTriangles(mesh, name, mf.transform, keep, noCompare, materialIndex);
                    meshes.Add(cm);

                    if (meshesByMaterial.Count <= materialIndex)
                    {
                        MeshesByMaterial mbm = new MeshesByMaterial();
                        meshesByMaterial.Add(mbm);
                    }

                    meshesByMaterial [materialIndex].addMesh(cm);
                }
                childIdx++;
            }

            // Create mesh grid
            int gridSize = (int)Mathf.Ceil(gridBounds.size.x);

            if (Mathf.Ceil(gridBounds.size.y) > gridSize)
            {
                gridSize = (int)Mathf.Ceil(gridBounds.size.y);
            }
            if (Mathf.Ceil(gridBounds.size.z) > gridSize)
            {
                gridSize = (int)Mathf.Ceil(gridBounds.size.z);
            }
            MeshGrid meshGrid = new MeshGrid(gridSize, gridBounds.center);

            foreach (CustomMesh m in meshes)
            {
                if (!m.noCompare)
                {
                    meshGrid.addMesh(m);
                }
            }

            int triangleCount = 0;
            int vertexCount   = 0;

            // Remove obsolete triangles
            for (int i = 0; i < meshes.Count; i++)
            {
                CustomMesh m = meshes [i];
                if (!m.noCompare)
                {
                    float  percent = ((float)i) / ((float)meshes.Count);
                    string name    = m.name + "";
                    bool   cancel  = false;

                    cancel = EditorUtility.DisplayCancelableProgressBar("Checking triangles...", "  (" + i + "/" + meshes.Count + ")  " + name, percent);

                    if (cancel)
                    {
                        return(true);
                    }
                    for (int j = 0; j < m.gridItems.Count; j++)
                    {
                        m.gridItems [j].checkMesh(m);
                    }
                }

                int tCount = 0;
                int vCount = 0;
                m.getVertexAndTriangleCount(ref vCount, ref tCount);
                //Debug.Log ("Mesh " + m.name + " has " + tCount / 3 + " triangles.");
                triangleCount += tCount;
                vertexCount   += vCount;

                EditorApplication.Step();
            }

            buildQuadsFromTriangles(meshes);

            triangleCount = 0;
            vertexCount   = 0;

            for (int i = 0; i < meshes.Count; i++)
            {
                CustomMesh m = meshes [i];
                if (!m.noCompare)
                {
                    float  percent = ((float)i) / ((float)meshes.Count);
                    string name    = m.name + "";
                    bool   cancel  = false;

                    cancel = EditorUtility.DisplayCancelableProgressBar("Checking quads...", "  (" + i + "/" + meshes.Count + ")  " + name, percent);

                    if (cancel)
                    {
                        return(true);
                    }

                    for (int j = 0; j < m.gridItems.Count; j++)
                    {
                        m.gridItems [j].checkMesh(m);
                    }
                }
                int tCount = 0;
                int vCount = 0;
                m.getVertexAndTriangleCount(ref vCount, ref tCount);
                //Debug.Log ("Mesh " + m.name + " has " + tCount / 3 + " triangles.");
                triangleCount += tCount;
                vertexCount   += vCount;

                EditorApplication.Step();
            }

            EditorUtility.ClearProgressBar();

            int currentMaterial = 0;

            foreach (MeshesByMaterial mbm in meshesByMaterial)
            {
                triangleCount = 0;
                vertexCount   = 0;
                for (int i = 0; i < mbm.meshes.Count; i++)
                {
                    int vCount = 0;
                    int tCount = 0;
                    mbm.meshes [i].getVertexAndTriangleCount(ref vCount, ref tCount);
                    triangleCount += tCount;
                    vertexCount   += vCount;
                }
                if (vertexCount == 0 || triangleCount == 0)
                {
                    continue;
                }
                // Combine all quads/triangles to one big mesh
                GameObject go = new GameObject("_Combined_" + parent.name + "_material_" + materials [currentMaterial].name);
                go.transform.position   = parentPosition;
                go.transform.rotation   = parentRotation;
                go.transform.localScale = Vector3.one;
                if (parent.transform && parent.transform.parent && parent.transform.parent.gameObject)
                {
                    go.transform.parent = parent.transform.parent;
                }
                GameObjectUtility.SetStaticEditorFlags(go, StaticEditorFlags.LightmapStatic);

                MeshRenderer renderer = go.AddComponent <MeshRenderer> ();
                if (materials [currentMaterial] != null)
                {
                    renderer.material = materials [currentMaterial];
                }
                currentMaterial++;
                MeshFilter newFilter = go.AddComponent <MeshFilter> ();
                Mesh       newMesh   = new Mesh();


                Vector3[] newVertices  = new Vector3[vertexCount];
                Vector2[] newUV        = new Vector2[newVertices.Length];
                Vector3[] newNormals   = new Vector3[newVertices.Length];
                int[]     newTriangles = new int[triangleCount];

                int triangleIndex = 0;
                int vertexIndex   = 0;
                for (int i = 0; i < mbm.meshes.Count; i++)
                {
                    mbm.meshes [i].getTrianglesAndVertices(ref newTriangles, ref newVertices, ref newUV, ref newNormals, ref triangleIndex, ref vertexIndex);
                }


                newMesh.vertices  = newVertices;
                newMesh.normals   = newNormals;
                newMesh.uv        = newUV;
                newMesh.uv2       = newUV;
                newMesh.triangles = newTriangles;

                ;
                newMesh.RecalculateBounds();

                newFilter.mesh = newMesh;
                Unwrapping.GenerateSecondaryUVSet(newFilter.sharedMesh);
            }

            //Debug.Log ("Combine meshes finished! Elapsed time: " + (EditorApplication.timeSinceStartup - timeStart));

            return(false);
        }
Example #2
0
		public static bool combineMeshes (GameObject parent, Vector3 parentPosition, Quaternion parentRotation)
		{
			//bool showCompileReady = true;
			//double timeStart = EditorApplication.timeSinceStartup;
			List<CustomMesh> meshes = new List<CustomMesh> ();
			List<MeshesByMaterial> meshesByMaterial = new List<MeshesByMaterial> ();

			int numChildren = parent.transform.childCount;
			int childIdx = 0;
			List<Material> materials = new List<Material> ();

			Bounds gridBounds = new Bounds ();
			bool foundBounds = false;

			//Build custom meshes
			foreach (Transform child in parent.transform) {
				// Get bounds
				Renderer[] renderers = child.GetComponentsInChildren<Renderer> ();
				List<Renderer> rds = new List<Renderer> (renderers);

				if (rds.Count == 0) {
					continue;
				}
				for (int i=0; i<rds.Count; i++) {
					Renderer r = rds [i];
					Material material = r.sharedMaterial;
					if (material) {
						if (!materials.Contains (material)) {
							materials.Add (material);
						}
					}

					if (!foundBounds) {
						foundBounds = true;
						gridBounds = new Bounds (r.bounds.center, r.bounds.size);
					} else {
						gridBounds.Encapsulate (r.bounds);
					}
				}

				MeshFilter[] ccmfs = child.GetComponentsInChildren<MeshFilter> ();
				List<MeshFilter> mfs = new List<MeshFilter> (ccmfs);

				for (int i=0; i<mfs.Count; i++) {
					MeshFilter mf = mfs [i];
					Renderer r = mf.gameObject.GetComponent<Renderer> ();
					if(!r){
						continue;
					}
					Material material = r.sharedMaterial;
					if (!material || !materials.Contains (material)) {
						continue;
					}

					int materialIndex = materials.IndexOf (material);

					bool cancel = false;

					Mesh mesh = mf.sharedMesh;
					string name = child.name;
					if (mesh == null) {
						continue;
					}

					float percent = ((float)childIdx) / ((float)numChildren);
					cancel = EditorUtility.DisplayCancelableProgressBar ("Creating custom meshes...", "(" + childIdx + "/" + numChildren + ")  " + name, percent);
					if (cancel) {
						return true;
					}

					// Keeps this mesh but compares to others. No subdivision is performed.
					bool keep = (child.tag == "keep");
					// Keeps this mesh without comparing to others. No subdivision is performed.
					bool noCompare = (child.tag == "nocompare");

					CustomMesh cm = buildTriangles (mesh, name, mf.transform, keep, noCompare, materialIndex);
					meshes.Add (cm);

					if (meshesByMaterial.Count <= materialIndex) {
						MeshesByMaterial mbm = new MeshesByMaterial ();
						meshesByMaterial.Add (mbm);
					}
					
					meshesByMaterial [materialIndex].addMesh (cm);
				}
				childIdx ++;
			}

			// Create mesh grid
			int gridSize = (int)Mathf.Ceil (gridBounds.size.x);
			if (Mathf.Ceil (gridBounds.size.y) > gridSize) {
				gridSize = (int)Mathf.Ceil (gridBounds.size.y);
			}
			if (Mathf.Ceil (gridBounds.size.z) > gridSize) {
				gridSize = (int)Mathf.Ceil (gridBounds.size.z);
			}
			MeshGrid meshGrid = new MeshGrid (gridSize, gridBounds.center);

			foreach (CustomMesh m in meshes) {
				if (!m.noCompare) {
					meshGrid.addMesh (m);
				}
			}

			int triangleCount = 0;
			int vertexCount = 0;

			// Remove obsolete triangles
			for (int i=0; i<meshes.Count; i++) {
				CustomMesh m = meshes [i];
				if (!m.noCompare) {
					float percent = ((float)i) / ((float)meshes.Count);
					string name = m.name + "";
					bool cancel = false;

					cancel = EditorUtility.DisplayCancelableProgressBar ("Checking triangles...", "  (" + i + "/" + meshes.Count + ")  " + name, percent);

					if (cancel) {
						return true;
					}
					for (int j=0; j<m.gridItems.Count; j++) {
						m.gridItems [j].checkMesh (m);
					}
				}

				int tCount = 0;
				int vCount = 0;
				m.getVertexAndTriangleCount (ref vCount, ref tCount);
				//Debug.Log ("Mesh " + m.name + " has " + tCount / 3 + " triangles.");
				triangleCount += tCount;
				vertexCount += vCount;

				EditorApplication.Step ();
			}

			buildQuadsFromTriangles (meshes);

			triangleCount = 0;
			vertexCount = 0;

			for (int i=0; i<meshes.Count; i++) {
				CustomMesh m = meshes [i];
				if (!m.noCompare) {
					float percent = ((float)i) / ((float)meshes.Count);
					string name = m.name + "";
					bool cancel = false;
					
					cancel = EditorUtility.DisplayCancelableProgressBar ("Checking quads...", "  (" + i + "/" + meshes.Count + ")  " + name, percent);
					
					if (cancel) {
						return true;
					}
					
					for (int j=0; j<m.gridItems.Count; j++) {
						m.gridItems [j].checkMesh (m);
					}
				}
				int tCount = 0;
				int vCount = 0;
				m.getVertexAndTriangleCount (ref vCount, ref tCount);
				//Debug.Log ("Mesh " + m.name + " has " + tCount / 3 + " triangles.");
				triangleCount += tCount;
				vertexCount += vCount;
				
				EditorApplication.Step ();
			}

			EditorUtility.ClearProgressBar ();

			int currentMaterial = 0;
			foreach (MeshesByMaterial mbm in meshesByMaterial) {
				triangleCount = 0;
				vertexCount = 0;
				for (int i=0; i < mbm.meshes.Count; i++) {
					int vCount = 0;
					int tCount = 0;
					mbm.meshes [i].getVertexAndTriangleCount (ref vCount, ref tCount);
					triangleCount += tCount;
					vertexCount += vCount;
				}
				if(vertexCount == 0 || triangleCount == 0){
					continue;
				}
				// Combine all quads/triangles to one big mesh
				GameObject go = new GameObject ("_Combined_" + parent.name + "_material_" + materials [currentMaterial].name);
				go.transform.position = parentPosition;
				go.transform.rotation = parentRotation;
				go.transform.localScale = Vector3.one;
				if (parent.transform && parent.transform.parent && parent.transform.parent.gameObject) {
					go.transform.parent = parent.transform.parent;
				}
				GameObjectUtility.SetStaticEditorFlags (go, StaticEditorFlags.LightmapStatic);

				MeshRenderer renderer = go.AddComponent<MeshRenderer> ();
				if (materials [currentMaterial] != null) {
					renderer.material = materials [currentMaterial];
				}
				currentMaterial ++;
				MeshFilter newFilter = go.AddComponent<MeshFilter> ();
				Mesh newMesh = new Mesh ();

			
				Vector3[] newVertices = new Vector3[vertexCount];
				Vector2[] newUV = new Vector2[newVertices.Length];
				Vector3[] newNormals = new Vector3[newVertices.Length];
				int[] newTriangles = new int[triangleCount];
				
				int triangleIndex = 0;
				int vertexIndex = 0;
				for (int i=0; i<mbm.meshes.Count; i++) {
					mbm.meshes [i].getTrianglesAndVertices (ref newTriangles, ref newVertices, ref newUV, ref newNormals, ref triangleIndex, ref vertexIndex);
				}
				

				newMesh.vertices = newVertices;
				newMesh.normals = newNormals;
				newMesh.uv = newUV;
				newMesh.uv2 = newUV;
				newMesh.triangles = newTriangles;
				
				newMesh.Optimize ();
				newMesh.RecalculateBounds ();
				
				newFilter.mesh = newMesh;
				Unwrapping.GenerateSecondaryUVSet (newFilter.sharedMesh);
			}

			//Debug.Log ("Combine meshes finished! Elapsed time: " + (EditorApplication.timeSinceStartup - timeStart));

			return false;
		}