首页 > 其他 > 详细

一个网格合并(weld)小工具

时间:2021-03-28 11:27:19      阅读:27      评论:0      收藏:0      [点我收藏+]

在日常开发中会有需求合并多个Mesh网格,并且它们重合处的顶点也要合并,而并非合并成两个subMesh。

而近期刚好在学习Geomipmap的细分,需要把多个mesh块进行合并,于是写了这个脚本。

 

见下图,多对象合并前后对比:

技术分享图片

 

 

使用时传入多个MeshFilter,会返回对应Mesh,但是没做UV、顶点色这些,需要自己扩展:

namespace Hont
{
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public static class MeshCombinerUtil
    {
        public static Mesh Combine(MeshFilter[] meshFilterArary, float weldDistance = 0.01f)
        {
            const int MESH_VERT_GAP = 10_0000;

            Dictionary<int, int> newTrianglesDict = new Dictionary<int, int>();
            List<int> newTrianglesList = new List<int>();
            List<Vector3> newVerticesList = new List<Vector3>();
            List<KeyValuePair<Vector3, int>> meshSlotList = new List<KeyValuePair<Vector3, int>>();

            int counter = 0;
            for (int i = 0; i < meshFilterArary.Length; i++)
            {
                MeshFilter meshFilter = meshFilterArary[i];
                Mesh mesh = meshFilter.sharedMesh;

                Vector3[] verticesArray = mesh.vertices;
                int[] trianglesArray = mesh.triangles;

                for (int j = 0; j < trianglesArray.Length; j++)
                {
                    int triangleIndex = trianglesArray[j];
                    int triangleIndexContainOffset = triangleIndex + i * MESH_VERT_GAP;
                    Vector3 vertex = verticesArray[triangleIndex];
                    vertex = meshFilter.transform.localToWorldMatrix.MultiplyPoint3x4(vertex);

                    if (!newTrianglesDict.ContainsKey(triangleIndexContainOffset))
                    {
                        KeyValuePair<Vector3, int> slotInfo = new KeyValuePair<Vector3, int>(Vector3.zero, -1);
                        for (int k = 0; k < meshSlotList.Count; k++)
                        {
                            KeyValuePair<Vector3, int> meshSlot = meshSlotList[k];

                            if (Vector3.Distance(meshSlot.Key, vertex) <= weldDistance)
                            {
                                slotInfo = meshSlot;
                                break;
                            }
                        } //检索网格交错列表

                        if (slotInfo.Value > -1) //如果网格交错列表里有
                        {
                            newTrianglesDict.Add(triangleIndexContainOffset, slotInfo.Value);
                        }
                        else //如果网格交错列表里没有
                        {
                            meshSlotList.Add(new KeyValuePair<Vector3, int>(vertex, counter));
                            newTrianglesDict.Add(triangleIndexContainOffset, counter);

                            ++counter;
                            newVerticesList.Add(vertex);
                        }
                    } //如果这个原始三角形索引字典里没有则初始化

                    newTrianglesList.Add(newTrianglesDict[triangleIndexContainOffset]);
                }
            }

            Mesh newMesh = new Mesh();
            newMesh.SetVertices(newVerticesList);
            newMesh.SetTriangles(newTrianglesList, 0);

            return newMesh;
        }
    }
}

 

一个网格合并(weld)小工具

原文:https://www.cnblogs.com/hont/p/14587775.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!