//合并网格
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CombineMesh : MonoBehaviour {

    Mesh m_Mesh;
    public Material mat;

    List<Vector3> m_Verts = new List<Vector3>();
    List<Vector2> m_Uvs = new List<Vector2>();
    List<int>  m_Tris = new List<int>();
    List<Vector3> m_Normals = new List<Vector3>();

    void Awake()
    {
        /*if (this.enabled)
        {
            Init();
        }*/
    }

    private void Update()
    {
        if (this.enabled)
            DrawMesh();
    }

    public void Init()
    {
        if (this.m_Mesh == null)
        {
            this.m_Mesh = new Mesh();
        }

        Combine();
    }

    public void Clear()
    {
        m_Mesh = null;
    }

    void Combine()
    {
        Transform tileParent = transform;

        MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
        if (meshFilter == null)
            meshFilter = transform.gameObject.AddComponent<MeshFilter>();

        meshFilter.mesh = this.m_Mesh;

        this.m_Mesh.Clear();
        m_Verts.Clear();
        m_Uvs.Clear();
        m_Tris.Clear();
        m_Normals.Clear();

        MeshFilter[] mfArray = this.GetComponentsInChildren<MeshFilter>();
        GameDebug.Log($"mesh count:{mfArray.Length}");
        foreach (MeshFilter mf in mfArray)
        {
            if (mf == meshFilter)
            {
                continue;
            }
            GameDebug.Log($"AddMesh:{mf.gameObject.name}");

            this.AddMesh(mf);
            mf.gameObject.SetActive(false);
        }

        this.m_Mesh.vertices = m_Verts.ToArray();
        this.m_Mesh.uv = m_Uvs.ToArray();
        this.m_Mesh.triangles = m_Tris.ToArray();
        this.m_Mesh.normals = m_Normals.ToArray();
		this.m_Mesh.RecalculateNormals();
		this.m_Mesh.RecalculateTangents();
		this.m_Mesh.RecalculateBounds();
    }

    void AddMesh(MeshFilter meshFilter)
    {
        Matrix4x4 thisMatrix = this.transform.worldToLocalMatrix;
        
        Mesh mesh = meshFilter.mesh;

        Matrix4x4 meshFilterMatrix = meshFilter.transform.localToWorldMatrix;

        Vector3[] vets = mesh.vertices;
        Vector2[] uvs = mesh.uv;
        int[] tris = mesh.triangles;

        int count = m_Verts.Count;

        Matrix4x4 m = thisMatrix * meshFilterMatrix;

        for (int i = 0; i < vets.Length; ++i)
        {
            m_Verts.Add(m.MultiplyPoint3x4(vets[i]));
        }
        for (int i = 0; i < tris.Length; ++i)
        {
            m_Tris.Add(count + tris[i]);
        }

        m_Uvs.AddRange(uvs);
        m_Normals.AddRange(mesh.normals);
    }

    void DrawMesh()
    {
        if (this.mat != null && m_Mesh != null)
            Graphics.DrawMesh(this.m_Mesh, this.transform.localToWorldMatrix, this.mat, this.gameObject.layer);
    }

#if UNITY_EDITOR
    //保存网格
    public void SaveMeshPref()
    {
        SaveMesh(transform);
    }

    void SaveMesh(Transform tran)
    {
        string path = "Assets/Terrain/Resources/GenAsset/";
        string dirName = System.IO.Path.GetDirectoryName(path);
        if (!System.IO.Directory.Exists(dirName))
        {
            System.IO.Directory.CreateDirectory(dirName);
        }
        UnityEditor.AssetDatabase.CreateAsset(this.m_Mesh, string.Format("{0}{1}网格.mesh", path , transform.gameObject.name));
        GameObject newGo = new GameObject("NewGo",typeof(MeshFilter),typeof(MeshRenderer));
        newGo.GetComponent<MeshFilter>().mesh = m_Mesh;
        newGo.GetComponent<MeshRenderer>().material = mat;
        newGo.transform.SetParent(tran.parent);
        newGo.transform.localPosition = tran.localPosition;
        newGo.transform.localRotation = tran.localRotation;
        newGo.transform.localScale = tran.localScale;
        UnityEditor.PrefabUtility.CreatePrefab(string.Format("{0}{1}.prefab", path, transform.gameObject.name), newGo);
        GameObject.Destroy(newGo);

        UnityEditor.AssetDatabase.Refresh();
        
        GameDebug.Log($"输出路径：{path}");
    }
#endif
}
