在日常开发中会有需求合并多个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. 使用OHOS SDK构建ogg

    参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone --depth=1 https://github.com/xiph/ogg 进入源 ...

  2. SQL CREATE INDEX 语句- 提高数据库检索效率的关键步骤

    SQL CREATE INDEX 语句 SQL CREATE INDEX 语句用于在表中创建索引. 索引用于比其他方式更快地从数据库中检索数据.用户无法看到索引,它们只是用于加速搜索/查询. 注意: ...

  3. 面试必备HashMap源码解析

    Map的实现有很多种,而HashMap算是最经典的实现之一了吧,在平时的使用中,绝大部分的使用也都是HashMap,我记得刚入行那会,脑子里对Map的使用就是Map map = new HashMap ...

  4. Kubernetes(K8S)命令指南

    本文提供了一份全面的Kubernetes(K8S)命令指南,旨在帮助用户掌握和运用K8S的各种命令. 关注[TechLeadCloud],分享互联网架构.云服务技术的全维度知识.作者拥有10+年互联网 ...

  5. 给你安利一款鲁班大叔开发的maven依赖搜索神器

    写在前面 一款好的插件往往能提高我们的开发效率.今天就给大家安利一款maven 依赖搜索插件. 插件是自己一直关注的鲁班大叔开发的,用了几天真的好用 废话不多说,我们就来看看这是一款什么插件 一.ma ...

  6. HarmonyOS实现表单页面的输入,必填校验和提交

    一. 样例介绍 本篇Codelab基于input组件.label组件和dialog组件,实现表单页面的输入.必填校验和提交: 1.  为input组件设置不同类型(如:text,email,date等 ...

  7. 保护C#代码的艺术:深入浅出代码混淆技术

    摘要 在C#开发中,代码的保护是一个不可忽视的问题.本文深入探讨了几种常用的C#代码混淆工具,帮助开发者理解如何有效地保护代码不被反编译.同时,本文也对混淆技术的优缺点进行了分析,并提供了一些实际使用 ...

  8. IIS 加载32dll失败

    前言 遇到一个这样的问题,因为在一个项目中是32位的,至于为什么是32位的呢,因为调用的都是老库,32位的,部署到iis出现错误如下: Server Error in '/' Application. ...

  9. iNeuOS工业互联网操作系统,民爆远程运维平台案例

    iNeuOS工业互联网操作系统,民爆远程运维平台案例 目       录 1.      概述... 2 2.      iNeuOS在民爆生产厂区和北京运维中心配置... 3 1.1         ...

  10. web开发可不可以是这样的?

    service不外乎就是数据校验,调用其它service,调用第三方api,读写数据库,既然这样,那我认为Service也可以做成可配置化的样子,配置项大致有 所需参数配置:参数列表,参数类型,参数长 ...