Ejemplo n.º 1
0
    GameObject combineMesh(bool exportAssets)
    {
        GameObject returnObject = new GameObject(m_parentObject.name);

        returnObject.transform.position = m_parentObject.transform.position;
        returnObject.transform.rotation = m_parentObject.transform.rotation;


        MeshFilter[] filters     = m_parentObject.GetComponentsInChildren <MeshFilter>();
        Matrix4x4    myTransform = m_parentObject.transform.worldToLocalMatrix;

        Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > allMeshesAndMaterials = new Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > >();

        for (int i = 0; i < filters.Length; i++)
        {
            Renderer curRenderer = filters[i].renderer;
            MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance();

            instance.mesh = filters[i].sharedMesh;

            if (curRenderer != null && curRenderer.enabled && instance.mesh != null)
            {
                instance.transform = myTransform * filters[i].transform.localToWorldMatrix;

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

                    if (!allMeshesAndMaterials.ContainsKey(materials[m].shader.ToString()))
                    {
                        allMeshesAndMaterials.Add(materials[m].shader.ToString(), new Dictionary <Material, List <MeshCombineUtility.MeshInstance> >());
                    }

                    if (!allMeshesAndMaterials[materials[m].shader.ToString()].ContainsKey(materials[m]))
                    {
                        allMeshesAndMaterials[materials[m].shader.ToString()].Add(materials[m], new List <MeshCombineUtility.MeshInstance>());
                    }

                    allMeshesAndMaterials[materials[m].shader.ToString()][materials[m]].Add(instance);
                }
            }
        }

        foreach (KeyValuePair <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > firstPass in allMeshesAndMaterials)
        {
            Material[] allMaterialTextures = new Material[firstPass.Value.Keys.Count];
            int        index = 0;

            foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value)
            {
                allMaterialTextures[index] = kv.Key;
                index++;
            }

            TextureCombineUtility.TexturePosition[] textureUVPositions;
            Material combined = TextureCombineUtility.combine(allMaterialTextures, out textureUVPositions, m_textureAtlasInfo);
            List <MeshCombineUtility.MeshInstance> meshes = new List <MeshCombineUtility.MeshInstance>();

            foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value)
            {
                List <MeshCombineUtility.MeshInstance> meshIntermediates = new List <MeshCombineUtility.MeshInstance>();
                Mesh[] firstCombineStep = MeshCombineUtility.Combine(kv.Value.ToArray());

                for (int i = 0; i < firstCombineStep.Length; i++)
                {
                    MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance();
                    instance.mesh         = firstCombineStep[i];
                    instance.subMeshIndex = 0;
                    instance.transform    = Matrix4x4.identity;
                    meshIntermediates.Add(instance);
                }

                TextureCombineUtility.TexturePosition refTexture = textureUVPositions[0];

                for (int j = 0; j < textureUVPositions.Length; j++)
                {
                    if (kv.Key.mainTexture.name == textureUVPositions[j].textures[0].name)
                    {
                        refTexture = textureUVPositions[j];
                        break;
                    }
                }

                for (int j = 0; j < meshIntermediates.Count; j++)
                {
                    Vector2[] uvCopy = meshIntermediates[j].mesh.uv;
                    for (int k = 0; k < uvCopy.Length; k++)
                    {
                        uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width;
                        uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height;
                    }

                    meshIntermediates[j].mesh.uv = uvCopy;

                    uvCopy = meshIntermediates[j].mesh.uv1;
                    for (int k = 0; k < uvCopy.Length; k++)
                    {
                        uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width;
                        uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height;
                    }

                    meshIntermediates[j].mesh.uv1 = uvCopy;

                    uvCopy = meshIntermediates[j].mesh.uv2;
                    for (int k = 0; k < uvCopy.Length; k++)
                    {
                        uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width;
                        uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height;
                    }

                    meshIntermediates[j].mesh.uv2 = uvCopy;

                    meshes.Add(meshIntermediates[j]);
                }
            }

            Material mat = combined;

            Mesh[] combinedMeshes = MeshCombineUtility.Combine(meshes.ToArray());

            GameObject parent = new GameObject("Combined " + m_parentObject.name + " " + firstPass.Key + " Mesh Parent");
            parent.transform.position = m_parentObject.transform.position;
            parent.transform.rotation = m_parentObject.transform.rotation;
            parent.transform.parent   = returnObject.transform;

            for (int i = 0; i < combinedMeshes.Length; i++)
            {
                GameObject go = new GameObject("Combined " + m_parentObject.name + " Mesh");
                go.transform.parent = parent.transform;
                go.tag   = m_parentObject.tag;
                go.layer = m_parentObject.layer;
                go.transform.localScale    = Vector3.one;
                go.transform.localRotation = Quaternion.identity;
                go.transform.localPosition = Vector3.zero;
                MeshFilter filter = go.AddComponent <MeshFilter>();
                go.AddComponent <MeshRenderer>();
                go.renderer.sharedMaterial = mat;

                filter.mesh = combinedMeshes[i];

                if (exportAssets == true)
                {
                    checkAndCreateFolder();

                    //(go.GetComponent<MeshRenderer>().material.mainTexture as Texture2D).format = TextureFormat.RGBA32;
                    Debug.Log((go.GetComponent <MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format);
                    if ((go.GetComponent <MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format != TextureFormat.ARGB32 &&
                        (go.GetComponent <MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format != TextureFormat.RGB24 &&
                        (go.GetComponent <MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format != TextureFormat.RGBA32)
                    {
                        Debug.LogError("Textures assigned to objects must be either RGBA32 or RGB 24 to be exported");
                        return(null);
                    }

                    byte[] texture = (go.GetComponent <MeshRenderer>().material.mainTexture as Texture2D).EncodeToPNG();
                    System.IO.File.WriteAllBytes(m_pathToAssets + mat.shader.ToString().Remove(mat.shader.ToString().IndexOf("(")) + i + ".png", texture);
                    exportMesh(combinedMeshes[i], mat.shader.ToString().Remove(mat.shader.ToString().IndexOf("(")) + i);
                }
            }
        }

        //if(developmentBake == true)
        //{
        foreach (Renderer r in m_parentObject.GetComponentsInChildren <Renderer>())
        {
            r.enabled = false;
        }
        //}

        return(returnObject);
    }
Ejemplo n.º 2
0
    public TextureAtlasInfo textureAtlasProperties;    // = new TextureCombineUtility.TextureAtlasInfo();

    /// This option has a far longer preprocessing time at startup but leads to better runtime performance.
    void Start()
    {
        MeshFilter[] filters     = GetComponentsInChildren <MeshFilter>();
        Matrix4x4    myTransform = transform.worldToLocalMatrix;

        Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > allMeshesAndMaterials = new Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > >();

        for (int i = 0; i < filters.Length; i++)
        {
            Renderer curRenderer = filters[i].GetComponent <Renderer>();
            MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance();

            instance.mesh = filters[i].mesh;

            if (curRenderer != null && curRenderer.enabled && instance.mesh != null)
            {
                instance.transform = myTransform * filters[i].transform.localToWorldMatrix;

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

                    if (!allMeshesAndMaterials.ContainsKey(materials[m].shader.ToString()))
                    {
                        allMeshesAndMaterials.Add(materials[m].shader.ToString(), new Dictionary <Material, List <MeshCombineUtility.MeshInstance> >());
                    }

                    if (!allMeshesAndMaterials[materials[m].shader.ToString()].ContainsKey(materials[m]))
                    {
                        allMeshesAndMaterials[materials[m].shader.ToString()].Add(materials[m], new List <MeshCombineUtility.MeshInstance>());
                    }

                    allMeshesAndMaterials[materials[m].shader.ToString()][materials[m]].Add(instance);
                }
            }
        }

        foreach (KeyValuePair <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > firstPass in allMeshesAndMaterials)
        {
            Material[] allMaterialTextures = new Material[firstPass.Value.Keys.Count];
            int        index = 0;

            foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value)
            {
                allMaterialTextures[index] = kv.Key;
                index++;
            }

            TextureCombineUtility.TexturePosition[] textureUVPositions;
            Material combined = TextureCombineUtility.combine(allMaterialTextures, out textureUVPositions, textureAtlasProperties);

            if (textureUVPositions != null)
            {
                List <MeshCombineUtility.MeshInstance> meshIntermediates = new List <MeshCombineUtility.MeshInstance>();
                foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value)
                {
                    TextureCombineUtility.TexturePosition refTexture = textureUVPositions[0];

                    for (int i = 0; i < textureUVPositions.Length; i++)
                    {
                        if (kv.Key.mainTexture.name == textureUVPositions[i].textures[0].name)
                        {
                            refTexture = textureUVPositions[i];
                            break;
                        }
                    }

                    for (int i = 0; i < kv.Value.Count; i++)
                    {
                        Vector2[] uvCopy = kv.Value[i].mesh.uv;

                        for (int j = 0; j < uvCopy.Length; j++)
                        {
                            uvCopy[j].x = refTexture.position.x + uvCopy[j].x * refTexture.position.width;
                            uvCopy[j].y = refTexture.position.y + uvCopy[j].y * refTexture.position.height;
                        }

                        kv.Value[i].mesh.uv = uvCopy;


                        uvCopy = kv.Value[i].mesh.uv2;
                        for (int j = 0; j < uvCopy.Length; j++)
                        {
                            uvCopy[j].x = refTexture.position.x + uvCopy[j].x * refTexture.position.width;
                            uvCopy[j].y = refTexture.position.y + uvCopy[j].y * refTexture.position.height;
                        }

                        kv.Value[i].mesh.uv2 = uvCopy;



                        uvCopy = kv.Value[i].mesh.uv2;
                        for (int j = 0; j < uvCopy.Length; j++)
                        {
                            uvCopy[j].x = refTexture.position.x + uvCopy[j].x * refTexture.position.width;
                            uvCopy[j].y = refTexture.position.y + uvCopy[j].y * refTexture.position.height;
                        }

                        kv.Value[i].mesh.uv2 = uvCopy;


                        meshIntermediates.Add(kv.Value[i]);
                    }
                }

                Material mat = combined;

                Mesh[] combinedMeshes = MeshCombineUtility.Combine(meshIntermediates.ToArray());

                GameObject parent = new GameObject("Combined " + gameObject.name + " " + firstPass.Key + " Mesh Parent");
                parent.transform.position = transform.position;
                parent.transform.rotation = transform.rotation;

                for (int i = 0; i < combinedMeshes.Length; i++)
                {
                    GameObject go = new GameObject("Combined " + gameObject.name + " Mesh");
                    go.transform.parent = parent.transform;
                    go.tag   = gameObject.tag;
                    go.layer = gameObject.layer;
                    go.transform.localScale    = Vector3.one;
                    go.transform.localRotation = Quaternion.identity;
                    go.transform.localPosition = Vector3.zero;
                    MeshFilter filter = go.AddComponent <MeshFilter>();
                    go.AddComponent <MeshRenderer>();
                    go.GetComponent <Renderer>().sharedMaterial = mat;

                    filter.mesh = combinedMeshes[i];
                }
            }
        }
        Destroy(gameObject);
    }
    GameObject combineMesh(bool exportAssets, bool genCollider = true, bool doSetParent = true, bool doSetLayer = true, bool doSetTag = true)
    {
//		GameObject returnObject = new GameObject(m_parentObject.name);
//		returnObject.transform.position = m_parentObject.transform.position;
//		returnObject.transform.rotation = m_parentObject.transform.rotation;


        MeshFilter[] filters     = m_parentObject.GetComponentsInChildren <MeshFilter>();
        Matrix4x4    myTransform = m_parentObject.transform.worldToLocalMatrix;

        this.checkAndCreateFolder();

        Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > allMeshesAndMaterials = new Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > >();

        for (int i = 0; i < filters.Length; i++)
        {
            Renderer curRenderer = filters[i].GetComponent <Renderer>();
            MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance();

            instance.mesh = filters[i].sharedMesh;

            if (curRenderer != null && curRenderer.enabled && instance.mesh != null)
            {
                instance.transform = myTransform * filters[i].transform.localToWorldMatrix;

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

                    if (!allMeshesAndMaterials.ContainsKey(materials[m].shader.ToString()))
                    {
                        allMeshesAndMaterials.Add(materials[m].shader.ToString(), new Dictionary <Material, List <MeshCombineUtility.MeshInstance> >());
                    }

                    if (!allMeshesAndMaterials[materials[m].shader.ToString()].ContainsKey(materials[m]))
                    {
                        allMeshesAndMaterials[materials[m].shader.ToString()].Add(materials[m], new List <MeshCombineUtility.MeshInstance>());
                    }

                    allMeshesAndMaterials[materials[m].shader.ToString()][materials[m]].Add(instance);
                }
            }
        }

        foreach (KeyValuePair <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > firstPass in allMeshesAndMaterials)
        {
            Material[] allMaterialTextures = new Material[firstPass.Value.Keys.Count];
            int        index = 0;

            foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value)
            {
                allMaterialTextures[index] = kv.Key;
                index++;
            }

            TextureCombineUtility.TexturePosition[] textureUVPositions;
            Material combined = TextureCombineUtility.combine(allMaterialTextures, out textureUVPositions, m_textureAtlasInfo);
            List <MeshCombineUtility.MeshInstance> meshes = new List <MeshCombineUtility.MeshInstance>();

            foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value)
            {
                List <MeshCombineUtility.MeshInstance> meshIntermediates = new List <MeshCombineUtility.MeshInstance>();
                Mesh[] firstCombineStep = MeshCombineUtility.Combine(kv.Value.ToArray());

                for (int i = 0; i < firstCombineStep.Length; i++)
                {
                    MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance();
                    instance.mesh         = firstCombineStep[i];
                    instance.subMeshIndex = 0;
                    instance.transform    = Matrix4x4.identity;
                    meshIntermediates.Add(instance);
                }
                if (textureUVPositions != null)
                {
                    TextureCombineUtility.TexturePosition refTexture = textureUVPositions[0];

                    for (int j = 0; j < textureUVPositions.Length; j++)
                    {
                        if (kv.Key.mainTexture.name == textureUVPositions[j].textures[0].name)
                        {
                            refTexture = textureUVPositions[j];
                            break;
                        }
                    }


                    for (int j = 0; j < meshIntermediates.Count; j++)
                    {
                        Vector2[] uvCopy = meshIntermediates[j].mesh.uv;
                        for (int k = 0; k < uvCopy.Length; k++)
                        {
                            uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width;
                            uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height;
                        }

                        meshIntermediates[j].mesh.uv = uvCopy;

                        uvCopy = meshIntermediates[j].mesh.uv2;
                        for (int k = 0; k < uvCopy.Length; k++)
                        {
                            uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width;
                            uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height;
                        }

                        meshIntermediates[j].mesh.uv2 = uvCopy;

                        uvCopy = meshIntermediates[j].mesh.uv2;
                        for (int k = 0; k < uvCopy.Length; k++)
                        {
                            uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width;
                            uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height;
                        }

                        meshIntermediates[j].mesh.uv2 = uvCopy;

                        meshes.Add(meshIntermediates[j]);
                    }
                }
            }

            Material mat = combined;

            if (exportAssets)            //combined exportMaterial and combined Textures
            {
                checkAndCreateFolder();

                Debug.Log((mat.mainTexture as Texture2D).format);
                if ((mat.mainTexture as Texture2D).format != TextureFormat.ARGB32 &&
                    (mat.mainTexture as Texture2D).format != TextureFormat.RGB24 &&
                    (mat.mainTexture as Texture2D).format != TextureFormat.RGBA32)
                {
                    Debug.LogError("Textures assigned to objects must be either RGBA32 or RGB 24 to be exported");
                    return(null);
                }

                byte[] textureByte   = (mat.mainTexture as Texture2D).EncodeToPNG();
                string texturefolder = m_pathToAssets.Substring(m_pathToAssets.LastIndexOf("Assets/")) + "Textures/";
                checkAndCreateFolder(texturefolder);
                System.IO.File.WriteAllBytes(texturefolder + m_parentObject.name + ".png", textureByte);
                Material outMat         = new Material(mat);
                string   materialfolder = m_pathToAssets.Substring(m_pathToAssets.LastIndexOf("Assets/")) + "Materials/";
                checkAndCreateFolder(materialfolder);
                string assetPathFile = materialfolder + m_parentObject.name + ".mat";
                AssetDatabase.CreateAsset(outMat, assetPathFile);
                outMat.CopyPropertiesFromMaterial(mat);
                outMat.mainTexture = AssetDatabase.LoadAssetAtPath(texturefolder + m_parentObject.name + ".png", typeof(Texture)) as Texture;
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
                mat = outMat;
            }

            Mesh[] combinedMeshes = MeshCombineUtility.Combine(meshes.ToArray());

            GameObject parent = new GameObject(m_parentObject.name + "_Combined " + firstPass.Key + " Mesh Parent");
            parent.transform.position = m_parentObject.transform.position;
            parent.transform.rotation = m_parentObject.transform.rotation;
            parent.transform.parent   = m_parentObject.transform;

            if (doSetLayer)
            {
                parent.layer = m_parentObject.layer;
            }

            if (doSetTag)
            {
                parent.tag = m_parentObject.tag;
            }

            if (doSetParent)
            {
                parent.transform.parent = m_parentObject.transform.parent;
            }

            parent.isStatic = m_parentObject.isStatic;

            for (int i = 0; i < combinedMeshes.Length; i++)
            {
                GameObject go = new GameObject(m_parentObject.name + "_Combined_Meshs");
                go.transform.parent = parent.transform;
                go.tag   = m_parentObject.tag;
                go.layer = m_parentObject.layer;
                go.transform.localScale    = Vector3.one;
                go.transform.localRotation = Quaternion.identity;
                go.transform.localPosition = Vector3.zero;
                MeshFilter filter = go.AddComponent <MeshFilter>();
                go.AddComponent <MeshRenderer>();
                go.GetComponent <Renderer>().sharedMaterial = mat;

                filter.mesh = combinedMeshes[i];

                if (exportAssets == true)
                {
                    exportMeshFilter(filter, m_parentObject.name + i);
//					exportMesh(combinedMeshes[i], m_parentObject.name + i,mat);
                }
                if (genCollider)
                {
                    if (go.GetComponent <MeshCollider>() == null)
                    {
                        go.gameObject.AddComponent <MeshCollider>();
                    }
                }

                if (doSetLayer)
                {
                    go.layer = m_parentObject.layer;
                }

                if (doSetTag)
                {
                    go.tag = m_parentObject.tag;
                }

                go.isStatic = m_parentObject.isStatic;
            }
        }

        //if(developmentBake == true)
        //{
        foreach (Renderer r in m_parentObject.GetComponentsInChildren <Renderer>())
        {
            r.enabled = false;
        }
        //}

        return(m_parentObject);
    }