/// Usually rendering with triangle strips is faster.
	/// However when combining objects with very low triangle counts, it can be faster to use triangles.
	/// Best is to try out which value is faster in practice.

	/// This option has a far longer preprocessing time at startup but leads to better runtime performance.
	public static void CombineMeshFilters(MeshFilter[] mf, Transform t, bool generateTriangleStrips) {

		MeshFilter[] filters  = mf;
		Matrix4x4 myTransform = t.worldToLocalMatrix;
		Hashtable materialToMesh= new Hashtable();

		for (int i=0;i<filters.Length;i++) {
			MeshFilter filter = (MeshFilter)filters[i];
			Renderer curRenderer  = filters[i].GetComponent<Renderer>();
			pb_MeshCombineUtility.MeshInstance instance = new pb_MeshCombineUtility.MeshInstance ();
			instance.mesh = filter.sharedMesh;
			if (curRenderer != null && curRenderer.enabled && instance.mesh != null) {
				instance.transform = myTransform * filter.transform.localToWorldMatrix;
				
				Material[] materials = curRenderer.sharedMaterials;
				for (int m=0;m<materials.Length;m++) {
					instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1);
	
					ArrayList objects = (ArrayList)materialToMesh[materials[m]];
					if (objects != null) {
						objects.Add(instance);
					}
					else
					{
						objects = new ArrayList ();
						objects.Add(instance);
						materialToMesh.Add(materials[m], objects);
					}
				}
				
				curRenderer.enabled = false;
			}
		}
	
		foreach (DictionaryEntry de  in materialToMesh) {
			ArrayList elements = (ArrayList)de.Value;
			pb_MeshCombineUtility.MeshInstance[] instances = (pb_MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(pb_MeshCombineUtility.MeshInstance));

			// We have a maximum of one material, so just attach the mesh to our own game object
			if (materialToMesh.Count == 1)
			{
				// Make sure we have a mesh filter & renderer
				if (t.GetComponent(typeof(MeshFilter)) == null)
					t.gameObject.AddComponent(typeof(MeshFilter));
				if (!t.GetComponent("MeshRenderer"))
					t.gameObject.AddComponent<MeshRenderer>();
	
				MeshFilter filter = (MeshFilter)t.GetComponent(typeof(MeshFilter));
				filter.mesh = pb_MeshCombineUtility.Combine(instances, generateTriangleStrips);
				t.GetComponent<Renderer>().material = (Material)de.Key;
				t.GetComponent<Renderer>().enabled = true;
			}
			// We have multiple materials to take care of, build one mesh / gameobject for each material
			// and parent it to this object
			else
			{
				GameObject go = new GameObject("Combined mesh");
				go.transform.parent = t.transform;
				go.transform.localScale = Vector3.one;
				go.transform.localRotation = Quaternion.identity;
				go.transform.localPosition = Vector3.zero;
				go.AddComponent(typeof(MeshFilter));
				go.AddComponent<MeshRenderer>();
				go.GetComponent<Renderer>().material = (Material)de.Key;
				MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter));
				filter.mesh = pb_MeshCombineUtility.Combine(instances, generateTriangleStrips);
			}
		}	
	}	
Exemplo n.º 2
0
    /// Usually rendering with triangle strips is faster.
    /// However when combining objects with very low triangle counts, it can be faster to use triangles.
    /// Best is to try out which value is faster in practice.

    /// This option has a far longer preprocessing time at startup but leads to better runtime performance.
    public static void CombineMeshFilters(MeshFilter[] mf, Transform t, bool generateTriangleStrips)
    {
        MeshFilter[] filters        = mf;
        Matrix4x4    myTransform    = t.worldToLocalMatrix;
        Hashtable    materialToMesh = new Hashtable();

        for (int i = 0; i < filters.Length; i++)
        {
            MeshFilter filter      = (MeshFilter)filters[i];
            Renderer   curRenderer = filters[i].GetComponent <Renderer>();
            pb_MeshCombineUtility.MeshInstance instance = new pb_MeshCombineUtility.MeshInstance();
            instance.mesh = filter.sharedMesh;
            if (curRenderer != null && curRenderer.enabled && instance.mesh != null)
            {
                instance.transform = myTransform * filter.transform.localToWorldMatrix;

                Material[] materials = curRenderer.sharedMaterials;
                for (int m = 0; m < materials.Length; m++)
                {
                    instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1);

                    ArrayList objects = (ArrayList)materialToMesh[materials[m]];
                    if (objects != null)
                    {
                        objects.Add(instance);
                    }
                    else
                    {
                        objects = new ArrayList();
                        objects.Add(instance);
                        materialToMesh.Add(materials[m], objects);
                    }
                }

                curRenderer.enabled = false;
            }
        }

        foreach (DictionaryEntry de  in materialToMesh)
        {
            ArrayList elements = (ArrayList)de.Value;
            pb_MeshCombineUtility.MeshInstance[] instances = (pb_MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(pb_MeshCombineUtility.MeshInstance));

            // We have a maximum of one material, so just attach the mesh to our own game object
            if (materialToMesh.Count == 1)
            {
                // Make sure we have a mesh filter & renderer
                if (t.GetComponent(typeof(MeshFilter)) == null)
                {
                    t.gameObject.AddComponent(typeof(MeshFilter));
                }
                if (!t.GetComponent("MeshRenderer"))
                {
                    t.gameObject.AddComponent <MeshRenderer>();
                }

                MeshFilter filter = (MeshFilter)t.GetComponent(typeof(MeshFilter));
                filter.mesh = pb_MeshCombineUtility.Combine(instances, generateTriangleStrips);
                t.GetComponent <Renderer>().material = (Material)de.Key;
                t.GetComponent <Renderer>().enabled  = true;
            }
            // We have multiple materials to take care of, build one mesh / gameobject for each material
            // and parent it to this object
            else
            {
                GameObject go = new GameObject("Combined mesh");
                go.transform.parent        = t.transform;
                go.transform.localScale    = Vector3.one;
                go.transform.localRotation = Quaternion.identity;
                go.transform.localPosition = Vector3.zero;
                go.AddComponent(typeof(MeshFilter));
                go.AddComponent <MeshRenderer>();
                go.GetComponent <Renderer>().material = (Material)de.Key;
                MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter));
                filter.mesh = pb_MeshCombineUtility.Combine(instances, generateTriangleStrips);
            }
        }
    }