zoukankan      html  css  js  c++  java
  • 一个网格合并(weld)小工具

    在日常开发中会有需求合并多个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;
            }
        }
    }
  • 相关阅读:
    常见makefile写法
    CMake入门指南
    CMAKE的使用
    Google NewSQL之Spanner
    Google Spanner (中文版)
    全球级的分布式数据库 Google Spanner原理
    idea刷新项目、清除项目缓存
    彻底理解Java的Future模式
    Elasticsearch 三种分页方式
    ElasticSearch 深度分页解决方案
  • 原文地址:https://www.cnblogs.com/hont/p/14587775.html
Copyright © 2011-2022 走看看