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

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

(简单的情况下用Mesh.CombineMeshes也可以)。

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

使用时传入多个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;
}
}
}

2022/02/13补充,该脚本提供多个MeshFilter的合并,但并不会将硬边转软边,刚好这几天遇到一个需求要进行这一步操作。补充Mesh硬边转软边脚本,搭配使用:

public static Mesh HardEdgeCombine(Mesh mesh, float weldDistance = 0.01f)
{
int[] triangles = mesh.triangles;
Vector3[] vertices = mesh.vertices; List<int> newTriangleList = new List<int>(triangles.Length);
List<int> newVertexTriangleIndexList = new List<int>(vertices.Length);
List<Vector3> newVertexList = new List<Vector3>(vertices.Length); int trianglesCounter = 0;
for (int i = 0; i < triangles.Length; i++)
{
int triangleIndex = triangles[i];
Vector3 vertex = vertices[triangleIndex]; int dstTriangleIndex = 0; bool combineFlag = false;
for (int j = 0; j < newVertexList.Count; j++)
{
Vector3 compareVertex = newVertexList[j]; if (Vector3.Distance(vertex, compareVertex) <= weldDistance)
{
dstTriangleIndex = newVertexTriangleIndexList[j]; combineFlag = true;
break;
}
} if (!combineFlag)
{
dstTriangleIndex = trianglesCounter;
newTriangleList.Add(dstTriangleIndex);
newVertexList.Add(vertex);
newVertexTriangleIndexList.Add(dstTriangleIndex);
trianglesCounter++;
}
else
{
newTriangleList.Add(dstTriangleIndex);
}
} Mesh newMesh = new Mesh();
newMesh.SetVertices(newVertexList);
newMesh.SetTriangles(newTriangleList, 0); newMesh.RecalculateBounds();
newMesh.RecalculateNormals();
newMesh.RecalculateTangents(); return newMesh;
}

HardEdgeCombine

一个网格合并(weld)小工具的更多相关文章

  1. 开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码

    开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码. 开源地址: https://github.com/jkpang/PPRows

  2. 用 C# 写一个 Redis 数据同步小工具

    用 C# 写一个 Redis 数据同步小工具 Intro 为了实现 redis 的数据迁移而写的一个小工具,将一个实例中的 redis 数据同步到另外一个实例中.(原本打算找一个已有的工具去做,找了一 ...

  3. 自己动手写一个U盘拷贝小工具

    这是五一期间,参照知乎上一篇的文章<十行代码--用python写一个USB病毒>写成的,最初只是单纯的想写成死循环,直到文件占满硬盘为止,第一个遇到的问题是,拷贝到硬盘之后,由于要无限次拷 ...

  4. (win环境)使用Electron打造一个桌面应用翻译小工具

    初始化项目 npm init 修改package.json {"name": "trans","version": "1.0.0& ...

  5. 腾讯的一个移动端测试小工具GT

    上周末参加了Ministar北京的测试聚会.腾讯的MIG专项测试组的组长给大家介绍了他们最近开发出来的手机测试工具GT. 下面是GT的官方说明: GT(随身调)是APP的随身调测平台,它是直接运行在手 ...

  6. 一个sql盲注小工具 (Golang版)

    并发,二分法判断. 源码写的有点垃圾,有点乱,结果也存在一些缺失. 记录: sql:select distinct 中的distinct选项,这是只会获取你表中不重复数据,是表中,而不是你一次sql执 ...

  7. 好用的一个从SharePoint导出小工具

      1. 输入 Site Url(Site Collection), 然后点"load"按钮 2.选择Web后,点选需导出的文档库,然后点"Next"按钮   ...

  8. 基于百度通用翻译API的一个翻译小工具

    前几天写了一个简单的翻译小工具,是基于有道翻译的,不过那个翻译接口有访问限制,超过一定次数后会提示访问过于频繁,偶然发现百度翻译API如果月翻译字符少于200万是不收取费用的,所以就注册了一个百度开发 ...

  9. Python学习之旅:用Python制作一个打字训练小工具

    一.写在前面 说道程序员,你会想到什么呢?有人认为程序员象征着高薪,有人认为程序员都是死肥宅,还有人想到的则是996和 ICU. 别人眼中的程序员:飞快的敲击键盘.酷炫的切换屏幕.各种看不懂的字符代码 ...

  10. ContentProvider域名替换小工具

    开发项目域名想怎么换就怎么换,就是这么任性! 这是一个很有意思的小工具! 这是一个方便开发人员和测试人员的小工具!! 吐槽: 一直在做Android开发,一直总有一个问题存在:做自己公司的apk开发时 ...

随机推荐

  1. #二分,负环#JZOJ 3852 单词接龙

    题目 只要一个单词的最后两个字母和另一个单词的前两个字母相同,那么这两个单词就可以有序的连接起来.给出\(n\)个单词组成单词环,求所有环的环中单词平均长度最大值. 分析 二分答案,判断是否存在正环( ...

  2. 基于分级安全的OpenHarmony架构设计

      本文转载自 OpenHarmony TSC 官方微信公众号<峰会回顾第1期 | 基于分级安全的OpenHarmony架构设计> 演讲嘉宾 | 付天福 回顾整理 | 廖   涛 排版校对 ...

  3. Pandas对象(数据结构)

    Pandas是Python的一个扩展程序库,是在Numpy基础上建立的,提供高性能.易使用的数据结构和数据分析工具. Pandas 可以从各种文件格式比如 CSV.JSON.SQL.Excel 等中导 ...

  4. Python操作临时文件---tempfile

    # 使用标准库中 tempfile 下的 TemporaryFile,NamedTemporaryFile # TemporaryFile(mode='w+b', bufsize=1, suffix= ...

  5. 填报表中也可以添加 html 事件

    在实际的项目开发中,填报表的应用十分广泛. 多数情况下,填报表会作为整个项目的一部分配合需求灵活使用,但有时也会受大项目环境的影响,产生一些特别的要求.比如,通常报表单元格的数据类型大多是文本,有时却 ...

  6. js 如何实现管道或者说组合

    前言 概念:管道是从左往右函数执行,组合是从右往左执行. 实现 原理与作用后续补齐. function compose(...funcs) { return function(x) { funcs.r ...

  7. 鸿蒙HarmonyOS实战-ArkUI组件(Tabs)

    一.Tabs Tabs组件是一种常见的用户界面(UI)组件,它是一个可以容纳多个选项卡的容器组件.每个选项卡通常包含一个面板和一个标签,用户可以通过点击标签来切换面板.Tabs组件通常用于展示多个相关 ...

  8. 初识大数据技术之Hadoop

    先上一张图: 看到这张图,我脑子里出现的第一个东西就是:这货太像旅行商问题了 有限的输入与有限的输出,当输入大于一定数值时,输出趋向于无法计算.... 其实要我说啊,旅行商问题其实没必要管他,因为这个 ...

  9. 本地部署Llama3-8B/72b 并进行逻辑推理测试

    美国当地时间4月18日,Meta开源了Llama3大模型,目前开源版本为8B和70B.Llama 3模型相比Llama 2具有重大飞跃,并在8B和70B参数尺度上建立了LLM模型的新技术.由于预训练和 ...

  10. 力扣205(java)-同构字符串(简单)

    题目: 给定两个字符串 s 和 t ,判断它们是否是同构的. 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的. 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序 ...