当前位置: 首页 > article >正文

Unity给物体添加网格(Wire)绘制的方法

先看效果:       

 

再看代码:

using System.Collections.Generic;
using UnityEngine;

public class WireMesh : MonoBehaviour
{
	[SerializeField]
	Material material;

	void Start()
	{
		Mesh mesh = OptimizeMesh(GetComponent<MeshFilter>().mesh);

		GameObject objWire = new(gameObject.name + "_wire");
		objWire.layer = LayerMask.NameToLayer("Wire");

		Mesh meshWird = new() { vertices = mesh.vertices };
		int[] edges = GetEdges(mesh);

		meshWird.SetIndices(edges, MeshTopology.Lines, 0);
		//-------------------------------------------------------------------------------------------
		MeshFilter meshFilter = objWire.AddComponent<MeshFilter>();
		meshFilter.mesh = meshWird;
		MeshRenderer meshRenderer = objWire.AddComponent<MeshRenderer>();
		meshRenderer.material = material;
		objWire.transform.SetParent(transform);
		objWire.transform.localPosition = Vector3.zero;
		objWire.transform.localRotation = Quaternion.identity;
		objWire.transform.localScale = Vector3.one;

		int[] GetEdges(Mesh mesh)
		{
			var hashEdges = new HashSet<(int, int)>();

			var triangles = mesh.triangles;

			for (int i = 0; i < triangles.Length; i += 3)
			{
				AddEdge(triangles[i], triangles[i + 1]);
				AddEdge(triangles[i + 1], triangles[i + 2]);
				AddEdge(triangles[i + 2], triangles[i]);
			}

			List<int> listTriangle = new();
			foreach (var val in hashEdges)
			{
				listTriangle.Add(val.Item1);
				listTriangle.Add(val.Item2);
			}

			return listTriangle.ToArray();

			void AddEdge(int id1, int id2)
			{
				var edge = (Mathf.Min(id1, id2), Mathf.Max(id1, id2));
				hashEdges.Add(edge); // 只添加唯一组合
			}
		}
	}

	Mesh OptimizeMesh(Mesh originalMesh, bool recalculate = false)
	{
		Vector3[] originalVertices = originalMesh.vertices;
		int[] originalTriangles = originalMesh.triangles;

		Dictionary<Vector3, int> uniqueVertices = new Dictionary<Vector3, int>();
		List<Vector3> newVertices = new List<Vector3>();
		List<int> newTriangles = new List<int>();

		// Re-index vertices
		for (int i = 0; i < originalVertices.Length; i++)
		{
			Vector3 vertex = originalVertices[i];

			if (!uniqueVertices.ContainsKey(vertex))
			{
				uniqueVertices[vertex] = newVertices.Count;
				newVertices.Add(vertex);
			}
		}

		// Map old indices to new ones
		for (int i = 0; i < originalTriangles.Length; i++)
		{
			int oldIndex = originalTriangles[i];
			int newIndex = uniqueVertices[originalVertices[oldIndex]];
			newTriangles.Add(newIndex);
		}

		// Create new optimized mesh
		Mesh optimizedMesh = new()
		{
			vertices = newVertices.ToArray(),
			triangles = newTriangles.ToArray()
		};
		//
		if (recalculate)
		{
			optimizedMesh.RecalculateNormals();
			optimizedMesh.RecalculateBounds();
		} 

		return optimizedMesh;
	}
}

        这个代码给一个物体添加一个与原始物体重叠的网格渲染的物体。

        这里面涉及到了一些知识点和操作方法,逐条说一下。

        首先是网格内容优化。这里说的优化只是Mesh记录数据量的优化,并不是说能在渲染速度上的优化。为什么这么说呢?当我们把一个模型文件导入到unity中后,不管原来的网格数据是怎样的,unity总是会让顶点数组中的顶点(Vector3)复制出多个来,假设一个fbx格式的立方体有8个顶点,但Unity在使用时会显示Mesh包含24个顶点,不知道是否是出于提升渲染速度的考虑。但我们要尽可能优化这个点数,这样索引的最大值也会变小,也能让我们渲染的wire的边变少,否则同样的边会重复渲染多次。这里OptimizeMesh方法将Mesh中重复的点去掉,同时也重置了面索引。在GetEdges方法中使用HashSet,这保证了不出现重叠的边。最后我们让Mesh使用了MeshTopology.Lines方式渲染,就得到了最终的结果。

        


http://www.kler.cn/news/324873.html

相关文章:

  • Dubbo快速入门(一):分布式与微服务、Dubbo基本概念
  • 推荐一款开源的链路监控系统
  • java 框架组件
  • python习题1
  • 半导体制造过程中设备通信的高级概述
  • 从 Tesla 的 TTPoE 看资源和算法
  • 第一弹:llama.cpp编译
  • macOS安装MySQL以后如何配置环境变量
  • MongoDB 数据库服务搭建(单机)
  • 指定PDF或图片多个识别区域,识别区域文字,并批量对PDF或图片文件改名
  • 【H2O2|全栈】关于CSS(7)CSS基础(六)
  • VMware 虚拟机配置固定 IP
  • MyBatis-Plus自动填充字段
  • Ubuntu 上安装 Miniconda
  • 华为FreeBuds 6i怎么佩戴不容易掉?
  • 人工智能时代,程序员如何保持核心竞争力
  • 柯桥学英语商务口语中老外最爱说的“what‘s up“是什么意思?回答错超尴尬!
  • R包:ggheatmap热图
  • linux 下80端口被占用
  • 经典sql题(十二)UDTF之Explode炸裂函数
  • ceph pg rebalance
  • 大数据-148 Apache Kudu 从 Flink 下沉数据到 Kudu
  • 探索顶级低代码开发平台,实现创新
  • 解决Android Studio 右上角Gradle不显示task
  • Docker技术深度解析与实践案例
  • 解决macOS搭建flutter错误 CocoaPods not installed
  • 自然语言处理实战项目:从理论到实现
  • 3. 轴指令(omron 机器自动化控制器)——>MC_MoveRelative
  • ChatGPT+R语言强强联合,数据分析不再难!回归与混合效应模型、多元统计分析、结构方程模型(SEM)(lavaan)、Meta分析、贝叶斯回归等应用
  • CORE MVC 过滤器 (筛选器)