一个网格合并(weld)小工具
在日常开发中会有需求合并多个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)小工具的更多相关文章
- 开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码
开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码. 开源地址: https://github.com/jkpang/PPRows
- 用 C# 写一个 Redis 数据同步小工具
用 C# 写一个 Redis 数据同步小工具 Intro 为了实现 redis 的数据迁移而写的一个小工具,将一个实例中的 redis 数据同步到另外一个实例中.(原本打算找一个已有的工具去做,找了一 ...
- 自己动手写一个U盘拷贝小工具
这是五一期间,参照知乎上一篇的文章<十行代码--用python写一个USB病毒>写成的,最初只是单纯的想写成死循环,直到文件占满硬盘为止,第一个遇到的问题是,拷贝到硬盘之后,由于要无限次拷 ...
- (win环境)使用Electron打造一个桌面应用翻译小工具
初始化项目 npm init 修改package.json {"name": "trans","version": "1.0.0& ...
- 腾讯的一个移动端测试小工具GT
上周末参加了Ministar北京的测试聚会.腾讯的MIG专项测试组的组长给大家介绍了他们最近开发出来的手机测试工具GT. 下面是GT的官方说明: GT(随身调)是APP的随身调测平台,它是直接运行在手 ...
- 一个sql盲注小工具 (Golang版)
并发,二分法判断. 源码写的有点垃圾,有点乱,结果也存在一些缺失. 记录: sql:select distinct 中的distinct选项,这是只会获取你表中不重复数据,是表中,而不是你一次sql执 ...
- 好用的一个从SharePoint导出小工具
1. 输入 Site Url(Site Collection), 然后点"load"按钮 2.选择Web后,点选需导出的文档库,然后点"Next"按钮 ...
- 基于百度通用翻译API的一个翻译小工具
前几天写了一个简单的翻译小工具,是基于有道翻译的,不过那个翻译接口有访问限制,超过一定次数后会提示访问过于频繁,偶然发现百度翻译API如果月翻译字符少于200万是不收取费用的,所以就注册了一个百度开发 ...
- Python学习之旅:用Python制作一个打字训练小工具
一.写在前面 说道程序员,你会想到什么呢?有人认为程序员象征着高薪,有人认为程序员都是死肥宅,还有人想到的则是996和 ICU. 别人眼中的程序员:飞快的敲击键盘.酷炫的切换屏幕.各种看不懂的字符代码 ...
- ContentProvider域名替换小工具
开发项目域名想怎么换就怎么换,就是这么任性! 这是一个很有意思的小工具! 这是一个方便开发人员和测试人员的小工具!! 吐槽: 一直在做Android开发,一直总有一个问题存在:做自己公司的apk开发时 ...
随机推荐
- CH392作服务器TCP Server应用配置使用
CH392工作在TCP Server模式时,参考手册说明需要打开监听Socket端口,也要设置数据连接Socket端口,注意数据连接Socket的源端口和监听Socket的源端口一致. 配置TCP S ...
- Visual Studio 2022插件的安装及使用 - 编程手把手系列文章
这次开始写手把手编程系列文章,刚写到C#的Dll程序集类库的博文,就发现需要先介绍Visual Studio 2022的插件的安装及使用,因为在后面编码的时候会用到这些个插件,所以有必要先对这个内容进 ...
- Jenkins安装插件很慢的解决方法
修改 Jenkins / update / default.json 这个文件就可以了 修改内容 1. 把 " www.google.com " 改成 " h ...
- Pytorch-tensor的转置,运算
1.矩阵的转置 方法:t() a=torch.randint(1,10,[2,3]) print(a,'\n') print(a.t()) 输出结果 tensor([[2, 8, 2], [9, 2, ...
- 华为云CodeArts IDE For Python 快速使用指南
本文分享自华为云社区<华为云CodeArts IDE For Python 快速使用指南>,作者:为云PaaS服务小智. CodeArts IDE 带有 Python 扩展,为 Pytho ...
- js判断元素内文字是否超出元素宽度,溢出隐藏
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 力扣409(java&python)-最长回文串(简单)
题目: 给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的 最长的回文串 . 在构造过程中,请注意 区分大小写 .比如 "Aa" 不能当做一个回文字符串. 示 ...
- 力扣451(java)-根据字符出现频率排序(中等)
题目: 给定一个字符串 s ,根据字符出现的 频率 对其进行 降序排序 .一个字符出现的 频率 是它出现在字符串中的次数. 返回 已排序的字符串 .如果有多个答案,返回其中任何一个. 示例 1: 输入 ...
- CF1857G Counting Graphs 题解
题目描述 给定一棵最小生成树,求有多少张图的最小生成树是给定的树,并且这张图的所有边边权不超过 \(S\). 思路 考虑在最小生成树中加边. 我们回顾一下 Kruskal 的过程: 找到没被用过的,最 ...
- 【知识点】如何快速开发、部署 Serverless 应用?
简介: 本文将详细介绍如何开发和部署 Serverless 应用,并通过阿里云函数计算控制台与开发者工具 Serverless Devs 进行应用的初始化.部署:最后分享应用的调试,通过科学发布.可观 ...