【Unity3D】绘制物体表面三角形网格

news2024/11/15 6:56:10

1 仅绘制三角形网格

        1)创建游戏对象 

        创建一个空对象,重命名为 Grid,并在其下添加需要绘制网格的对象,如下:

         场景显示如下:

        2)添加脚本组件

        GridController.cs

using System;
using UnityEngine;

public class GridController : MonoBehaviour {

	private void Start () {
		ForAllChildren(transform, RebuildMesh);
	}

	private void RebuildMesh(Transform transform) {
		MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
		if (meshFilter != null && meshFilter.mesh != null) {
			int[] indices = MakeIndices(meshFilter.mesh.triangles);
			meshFilter.mesh.SetIndices(indices, MeshTopology.Lines, 0);
		}
	}

	private int[] MakeIndices(int[] triangles) {
		int[] indices = new int[2 * triangles.Length];
		for( int i = 0; i < triangles.Length; i += 3 ) {
			for (int j = 0; j < 6; j++) {
				// 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 1 ~ 5
				indices[2 * i + j] = triangles[i + (j + 1) % 6 / 2];
			}
		}
		return indices;
	}

	private void ForAllChildren(Transform transform, Action<Transform> action) {
		action.Invoke(transform);
		for (int i = 0; i < transform.childCount; i++) {
			ForAllChildren(transform.GetChild(i), action);
		}
	}
}

        说明: GridController 脚本组件挂在 Grid 对象上。

        运行效果:

        3)给网格添加新材质

        GridController.cs

using System;
using UnityEngine;

public class GridController : MonoBehaviour {
	public Material material;

	private void Start () {
		ForAllChildren(transform, RebuildMesh);
	}

	private void RebuildMesh(Transform transform) {
		MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
		MeshRenderer meshRenderer = transform.GetComponent<MeshRenderer>();
		if (meshFilter != null && meshFilter.mesh != null && meshRenderer != null) {
			meshRenderer.material = material;
			int[] indices = MakeIndices(meshFilter.mesh.triangles);
			meshFilter.mesh.SetIndices(indices, MeshTopology.Lines, 0);
		}
	}

	private int[] MakeIndices(int[] triangles) {
		int[] indices = new int[2 * triangles.Length];
		for( int i = 0; i < triangles.Length; i += 3 ) {
			for (int j = 0; j < 6; j++) {
				// 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 1 ~ 5
				indices[2 * i + j] = triangles[i + (j + 1) % 6 / 2];
			}
		}
		return indices;
	}

	private void ForAllChildren(Transform transform, Action<Transform> action) {
		action.Invoke(transform);
		for (int i = 0; i < transform.childCount; i++) {
			ForAllChildren(transform.GetChild(i), action);
		}
	}
}

        运行效果:

2 绘制表面和三角形网格

        场景中所有对象同第 1 节,脚本组件如下:

        GridController.cs

using System;
using UnityEngine;
using UnityEngine.Rendering;

public class GridController : MonoBehaviour {
	public Material material;

	private void Start () {
		ForAllChildren(transform, RebuildMesh);
	}

	private void RebuildMesh(Transform transform) {
		MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
		MeshRenderer meshRenderer = transform.GetComponent<MeshRenderer>();
		if (meshFilter != null && meshFilter.mesh != null && meshRenderer != null) {
			InitMaterials(meshRenderer);
			int[] indices = MakeIndices(meshFilter.mesh.triangles);
			InitSubMesh(meshFilter.mesh, indices, indices.Length / 3);
		}
	}

	private void InitMaterials(MeshRenderer meshRenderer) {
		Material[] materials = new Material[meshRenderer.materials.Length + 1];
		meshRenderer.materials.CopyTo(materials, 0);
		materials[materials.Length - 1] = material;
		meshRenderer.materials = materials;
	}

	private void InitSubMesh(Mesh mesh, int[] indices, int divide) {
		mesh.SetIndexBufferParams(indices.Length, IndexFormat.UInt32);
        mesh.SetIndexBufferData(indices, 0, 0, indices.Length);
        mesh.subMeshCount = 2; // 设置2个子网格
		// 第一部分绘制三角形内部
        SubMeshDescriptor subMeshDescriptor1 = new SubMeshDescriptor(0, divide, MeshTopology.Triangles);
        mesh.SetSubMesh(0, subMeshDescriptor1);
		// 第二部分绘制线段
        SubMeshDescriptor subMeshDescriptor2 = new SubMeshDescriptor(divide, indices.Length - divide, MeshTopology.Lines);
        mesh.SetSubMesh(1, subMeshDescriptor2);
	}

	private int[] MakeIndices(int[] triangles) {
		int[] indices = new int[3 * triangles.Length];
		triangles.CopyTo(indices, 0);
		for( int i = 0; i < triangles.Length; i += 3 ) {
			for (int j = 0; j < 6; j++) {
				// 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 1 ~ 5
				indices[triangles.Length + 2 * i + j] = triangles[i + (j + 1) % 6 / 2];
			}
		}
		return indices;
	}

	private void ForAllChildren(Transform transform, Action<Transform> action) {
		action.Invoke(transform);
		for (int i = 0; i < transform.childCount; i++) {
			ForAllChildren(transform.GetChild(i), action);
		}
	}
}

        运行效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/61836.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaWeb_第4章_RequestResponse

JavaWeb_第4章_Request&Response 文章目录JavaWeb_第4章_Request&Response1&#xff0c;Request和Response的概述2&#xff0c;Request对象2.1 Request继承体系2.2 Request获取请求数据2.2.1 获取请求行数据2.2.2 获取请求头数据2.2.3 获取请求体数据2.2.4 获取请求参数…

【ceph】分布式存储ceph

1 块存储&#xff0c;文件存储&#xff0c;对象存储 1.1 简介 文件存储&#xff1a;分层次存储&#xff0c;文件存储在文件夹中&#xff1b;访问文件时系统需要知道文件所在的路径。 举例&#xff1a;企业部门之间运用网络存储器&#xff08;NAS&#xff09;进行文件共享。 …

把握出租车行驶的数据脉搏 :出租车轨迹数据给你答案!

城市化带来的道路拥堵、出行耗时长等交通问题给交管部门带来了巨大的挑战。 ▼ 通过安装在出租车上的GPS设备&#xff0c;可以采集到大量的轨迹数据&#xff0c;从而帮助我们分析人们出行信息&#xff0c;达到优化交通的目的。 最近我们被客户要求撰写关于出租车行驶的研究报…

一次性分清zip、gzip、bzip2、tar命令

文章目录归类zip与unzip命令tar命令使用方式zipunzipgzipgunzipbzip2bunzip2tar归类 我们把这几个命令归类为几种能力&#xff0c;一个是解压缩能力一个是打拆包能力。 我这里打包的意思是不使用压缩算法对文件进行压缩&#xff0c;只是简单的把多个文件归档为一个文件。而拆包…

Qt OpenGL(二十五)——Qt OpenGL 核心模式-Qt封装的函数实现彩色三角形

Qt OpenGL(二十五)——Qt OpenGL 核心模式-Qt封装的函数实现彩色三角形 上一篇文章我们绘制了彩色的三角形,接下来其实就应该是让这个三角形旋转起来了,但是,旋转起来之前,还是想通过Qt自己的封装类实现彩色的三角形,并且让他旋转起来。 这才我(冯一川)是写这个系列…

编程之美4 Nim游戏

Tag&#xff1a;贪心&#xff1b;动态规划 题目 N块石头排成一行&#xff0c;每块石头有各自固定的位置。两个玩家依次取石头&#xff0c;每个玩家每次可以取其中任意一块石头&#xff0c;或者相邻的两块石头&#xff0c;石头在游戏过程中不能移位&#xff08;即编号不会改变…

在ASF中使用On Demand生产DEM等产品时使用不同参考DEM的区别

在ASF中使用On Dmand生产DEM等产品时使用不同参考DEM 主要有两种DEM&#xff0c;分别是SRTM和COP-DEM&#xff08;GLO-30&#xff09; 当我们添加Dmand进程之后&#xff0c;点击On Demand Queue 然后进入On Demand界面&#xff08;如下图所示&#xff09; 在Processing Op…

MySQL主从复制介绍及实操演示

1. 基本概念 MySQL主从复制的主要效果简单来说是将两个单独的数据库服务器关联起来&#xff0c;对于主机&#xff08;Master&#xff09;以及从机&#xff08;Slave&#xff09;&#xff0c;从机的数据会伴随着主机数据的变化而同步 2. 主从复制作用 可以解决单个MySQL数据库…

leetcode 63. 不同路径 II

文章目录题目思考代码和注释总结题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑…

Android WorkManager使用介绍

一、引言 WorkManager 是google提供的异步执行任务的管理框架&#xff0c;是 Android Jetpack 的一部分&#xff0c;会根据手机的API版本和应用程序的状态来选择适当的方式执行任务。   在后台执行任务的需求是非常常见的&#xff0c;Android也提供了多种解决方案&#xff0c…

高阶数据结构:并查集

本篇主要是介绍并查集的内容&#xff1a;所谓并查集就是一种描述不相交集合的数据结构&#xff0c;即若一个问题涉及多个元素&#xff0c;它们可以划分到不同集合&#xff0c;同属一个集合内的元素等价&#xff0c;不同集合内的元素不等价。 文章目录 一、并查集原理二、并查集…

Prophet在R语言中进行时间序列数据预测

您将学习如何使用Prophet&#xff08;在R中&#xff09;解决一个常见问题&#xff1a;预测公司明年的每日订单。 最近我们被客户要求撰写关于时间序列的研究报告&#xff0c;包括一些图形和统计输出。 数据准备与探索 Prophet最适合每日数据以及至少一年的历史数据。 我们将…

Ansible

Ansible是什么&#xff1f; Ansible是一个基于eythn开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pbet和Saltstack能实现的功能&#xff0c;As;ble基本上都可以实现。Ansible能批量配置、部署、管理上…

MongoDB入门与实战-第五章-MongoDB副本集

目录参考一、副本集概念1、**主要功能**2、主从复制和副本集区别3、复制结构图二、副本集成员角色1.主节点2.副本节点3.仲裁节点三、副本集架构&#xff08;一主一副本一仲裁&#xff09;1、**设置读操作权限&#xff1a;**2、取消作为奴隶节点的读权限四、选举原则1、触发条件…

时序逻辑电路

数字电路分为两大类&#xff0c;组合逻辑电路和时序逻辑电路 今天我们要开始学习的是时序逻辑电路&#xff0c;要求大家掌握 同步逻辑电路的分析方法 常用的时序逻辑电路的使用方法 当然由于时序逻辑电路的特点&#xff0c;使得时序逻辑电路难度远远大于组合逻辑电路 电路任…

一文详解Redis键过期策略,最全文档

文章目录1 设置带过期时间的 key1.1 刷新过期时间1.2 Redis 之前的 2.1.3 的差异1.3 返回值1.4 示例1.5 带过期时间的 key1.6 过期精度1.7 过期和持久化2 Redis的key过期策略2.1 惰性删除2.1.1 优点2.1.2 缺点定时删除优点缺点2.2 定期删除优点缺点难点定期删除流程Redis采用的…

SpringMVC异常处理器

1.异常 1.1 异常结构层次 异常主要分为&#xff1a;错误、一般性异常&#xff08;检查异常&#xff09;、运行期异常&#xff08;非受控异常&#xff09; 错误&#xff1a;如果应用程序出现了 Error&#xff0c;那么将无法恢复&#xff0c;只能重新启动应用程序&#xff0c;最…

VUE3-工作笔记-06

本节&#xff1a;总结11月份学习的内容 1.如果有很多个功能是一样的&#xff0c;那就先写一个测试很多次&#xff0c;确定没有bug再全部改&#xff0c;不然辛辛苦苦全部改了之后&#xff0c;发现还是有bug又要重新改&#xff0c;最好是写成组件的形式&#xff0c;写成hook。 …

ACM第三周---周训---题目合集.

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石.CSDN &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​ &#x1f4e3;系列专栏&#xff1a;ACM周训练题目合集.CSDN &#x1f4ac;总结&#xff1a…

微服务框架 SpringCloud微服务架构 10 使用Docker 10.7 数据卷命令

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构10 使用Docker10.7 数据卷命令10.7.1 数据卷10.7.2 操作数据卷10.7.3 直接…