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

Unity Mesh生成Cube

1. 配置一个Cube的每个面的数据

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一共是6个面,每个面包含的数据包括4个顶点的相对顶点坐标(Cube的中心为原点),法线方向,UV坐标,顶点渲染顺序,以及这个面用到的材质,因为这里是Top,即顶部,所以法线方向是(0,1,0),其他面以此类推。
顶点的渲染顺序依照左手定则和法线方向判断
在这里插入图片描述
即这里的渲染顺序为[0,2,1,0,3,2],按照左手定则,这两个三角形的法线方向才是朝上的,否则会看不见渲染出的东西,其他面以此类推

再配置一个Cube的数据
在这里插入图片描述
显然包含了每个面

2. 生成

public class MeshBuild : MonoBehaviour
{private MeshRenderer meshRenderer;private MeshFilter meshFilter;public BlockAsset blockAsset;/// <summary>/// 顶点坐标/// </summary>private List<Vector3> vertices = new List<Vector3>();  private List<Vector3> normals = new List<Vector3>();private List<Vector2> uvs = new List<Vector2>();/// <summary>/// 顶点的渲染顺序索引,相同材质的为一组/// </summary>private List<List<int>> subs = new List<List<int>>();/// <summary>/// 用来存储材质的渲染顺序/// </summary>private Dictionary<Material, int> materials = new Dictionary<Material,int>();private List<Vector3> offsets = new List<Vector3>(){new Vector3(0.5f, 0.5f, 0.5f),new Vector3(1.5f, 0.5f, 0.5f)};private void Start(){meshRenderer = GetComponent<MeshRenderer>();meshFilter = GetComponent<MeshFilter>();Build();}public void Build(){Mesh mesh = new Mesh();if (blockAsset != null){foreach (var o in offsets){var offset = o;if (blockAsset.top != null){Append(blockAsset.top, offset);}if (blockAsset.bottom != null){Append(blockAsset.bottom,offset);}if (blockAsset.left != null){Append(blockAsset.left,offset);}if (blockAsset.right != null){Append(blockAsset.right,offset);}if (blockAsset.forward != null){Append(blockAsset.forward,offset);}if(blockAsset.backward != null){Append(blockAsset.backward,offset);}   }}BuildMesh(mesh);BuildMaterial();}private void Append(BlockFaceAsset face, Vector3 offset){List<int> indices;if (!materials.TryGetValue(face.material, out var sub_index))   //如果这个材质不曾出现过{sub_index = subs.Count;     indices = new List<int>();subs.Add(indices);materials.Add(face.material, sub_index);}else      //如果这个材质已经出现过,则直接拿出这个材质的顶点渲染顺序索引,相同的材质的顶点需要放到一起渲染{indices = subs[sub_index];}var base_index = vertices.Count;   //所有的顶点索引必须连一块儿foreach (var v in face.vertices){vertices.Add(v.position + offset);normals.Add(v.normal);uvs.Add(v.uv);}foreach (var i in face.indices){indices.Add(base_index + i);    //添加到这一组顶点渲染顺序索引中}}private void BuildMesh(Mesh mesh){mesh.Clear();mesh.SetVertices(vertices);mesh.SetNormals(normals);mesh.SetUVs(0, uvs);mesh.subMeshCount = subs.Count;for (int i = 0; i < subs.Count; i++){mesh.SetTriangles(subs[i], i,false);}meshFilter.mesh = mesh;}private void BuildMaterial(){var mats = new Material[this.materials.Count];foreach (var kv in materials){mats[kv.Value] = kv.Key;}meshRenderer.materials = mats;}
}

在这里插入图片描述

最终生成效果
在这里插入图片描述
一共用到三个材质
在这里插入图片描述
顶部为白色,侧边为绿色,底部为红色

3. 代码解释

在这里插入图片描述
首先定义三个列表,用来存储顶点坐标,法线,UV坐标
在这里插入图片描述
此列表存储材质相同的一组顶点渲染顺序索引,比如上面的两个Cube,顶部是一组白色的材质,侧面是一组绿色的材质,底面是一组红色的材质
在这里插入图片描述
此字典用来存储材质的渲染顺序
在这里插入图片描述
两个偏移值,用来遍历生成两个Cube
在这里插入图片描述
对于这段代码,先尝试从材质字典中判断当前的材质是否已经渲染过,如果没有,则初始化sub_index,即此材质和顶点所在的渲染组别,并且同时初始化渲染顺序列表和添加材质字典。
如果已经渲染过此材质了,那么直接拿出之前存储过的顶点渲染顺序组别。
对于base_index的理解,就是看之前已经渲染过多少顶点,然后接着这些顶点的顺序渲染
就比如拿顶部举例
在这里插入图片描述
第一个Cube的顶部,此时vertices列表中是空的,所以base_index是0,然后遍历这个面的顶点的渲染顺序,将其添加到这个组别的列表中,即[0,2,1,0,3,2],也就是说subs[0]目前是这个列表
然后继续迭代,当再一次渲染到第二个Cube的顶部时
在这里插入图片描述
这里因为是使用的相同的材质,所以直接从材质字典中取出了sub_index,为0,再从subs中索引,里面的数据就是第一个Cube填入的顶点渲染顺序,然后发现此时base_index为24,因为渲染第一个Cube总共4*6=24个顶点
然后继续
在这里插入图片描述
当遍历完第二个Cube的顶部时,可以发现按照之前的顺序将现有的顶点顺序填入了当前组别的列表,即0+24,2+24,1+24,以此类推

在这里插入图片描述
然后依次调用Mesh的方法绘制Mesh,其中设置三角形就是按照组别一个个设置

在这里插入图片描述
最后设置材质,将材质从字典中拿出,组成材质数组,给到meshRenderer

相关文章:

Unity Mesh生成Cube

1. 配置一个Cube的每个面的数据 一共是6个面&#xff0c;每个面包含的数据包括4个顶点的相对顶点坐标&#xff08;Cube的中心为原点&#xff09;&#xff0c;法线方向&#xff0c;UV坐标&#xff0c;顶点渲染顺序&#xff0c;以及这个面用到的材质&#xff0c;因为这里是Top&am…...

2、pycharm常用快捷命令和配置【持续更新中】

1、常用快捷命令 Ctrl / 行注释/取消行注释 Ctrl Alt L 代码格式化 Ctrl Alt I 自动缩进 Tab / Shift Tab 缩进、不缩进当前行 Ctrl N 跳转到类 Ctrl 鼠标点击方法 可以跳转到方法所在的类 2、使用pip命令安装request库 命令&#xff1a;pip install requests 安装好了…...

Go语言方法和接收器类型详解

Go语言方法和接收器类型详解 1. 方法接收器类型 1.1 值接收器 值接收器方法不会改变接收器的状态&#xff0c;因为Go语言会在调用时复制接收器的值。因此&#xff0c;任何对接收器成员变量的修改都只会影响副本&#xff0c;而不会影响原始结构体实例。 type Person struct …...

Flutter:打包apk,详细图文介绍(一)

困扰了一天&#xff0c;终于能正常打包apk安装了&#xff0c;记录下打包的流程。建议参考我这篇文章时&#xff0c;同时看下官网的构建说明。 官网构建并发布 Android 应用详情 1、AS创建Flutter项目 2、cmd执行命令 生成一个sunluyi.jks的文件&#xff0c;可以自行把sunluyi替…...

Vue.js组件开发-实现动态切换菜单简单示例

在Vue.js中&#xff0c;实现动态切换菜单通过组件化开发和Vue的响应式数据绑定来实现。 示例&#xff1a; 展示如何创建一个可以动态切换菜单的Vue组件。 首先&#xff0c;需要定义一个Vue组件&#xff0c;该组件将包含菜单项和用于切换菜单的状态。 1. 创建Vue组件 <t…...

如何在 Ubuntu 22.04 上优化 Apache 以应对高流量网站教程

简介 在本教程中&#xff0c;我们将学习如何优化 Apache 以应对高流量网站。 当运行高流量网站时&#xff0c;确保你的 Apache Web 服务器得到优化对于有效处理负载至关重要。在本指南中&#xff0c;我们将介绍配置 Apache 以提高性能和可扩展性的基本技巧。 为高流量网站优…...

17爬虫:关于DrissionPage相关内容的学习01

概述 前面我们已经大致了解了selenium的用法&#xff0c;DerssionPage同selenium一样&#xff0c;也是一个基于Python的网页自动化工具。 DrissionPage既可以实现网页的自动化操作&#xff0c;也能够实现收发数据包&#xff0c;也可以把两者的功能合二为一。 DressionPage的…...

【HarmonyOS之旅】HarmonyOS概述(一)

目录 1 -> HarmonyOS简介 2 -> HarmonyOS发展历程 3 -> HarmonyOS技术特性 3.1 -> 硬件互助&#xff0c;资源共享 3.1.1 -> 分布式软总线 3.1.2 -> 分布式设备虚拟化 3.1.3 -> 分布式数据管理 3.1.4 -> 分布式任务调度 3.1.5 -> 分布式连接…...

chatwoot 开源客服系统搭建

1. 准备开源客服系统&#xff08;我是用的Chatwoot &#xff09; 可以选择以下开源客服系统作为基础&#xff1a; Chatwoot: 开源&#xff0c;多语言&#xff0c;跟踪和分析&#xff0c;支持多渠道客户对接&#xff0c;自动化和工作流等。源码Zammad: 现代的开源工单系统。Fr…...

30分钟搭建 Typecho 个人博客教程

Typecho是一款PHP博客程序&#xff0c;相比于WordPress&#xff0c;Typecho显得更加的轻量级和简洁。现在越来越多的人倾向于用Typecho来搭建个人博客——众所周知&#xff0c;能跑WordPress的机器都不便宜。 Typecho是一款国人团结打造的开源博客系统&#xff0c;和WordPress…...

智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之7 附件(文档)

为AI聊天工具添加一个知识系统 Part1 人性化&去中心化 前情提要 这一次我们暂时抛开前面对“智能工厂的软件设计”的考虑--其软件智能 产品就是 应用程序。直接将这些思维方式和方法论 运用在其具体应用场景中。本文是其中的一个应用场景。 今天用了 一个新的AI助手工具…...

鸿蒙应用开发启航计划

以前有过简单的学习了解&#xff0c;但是现在工作内容的原因&#xff0c;要专门搞这个&#xff0c;因此需要更加熟练地掌握鸿蒙应用开发。 1.开发IDE -- DevEco Studio Windows环境 运行环境要求 为保证DevEco Studio正常运行&#xff0c;建议电脑配置满足如下要求&#xff…...

基本算法——回归

目录 创建工程 加载数据 分析属性 创建与评估回归模型 线性回归 回归树 评估 完整代码 结论 本节将通过分析能源效率数据集&#xff08;Tsanas和Xifara&#xff0c;2012&#xff09;学习基本的回归算法。我们将基 于建筑的结构特点&#xff08;比如表面、墙体与屋顶面…...

深度学习——神经网络中前向传播、反向传播与梯度计算原理

一、前向传播 1.1 概念 神经网络的前向传播&#xff08;Forward Propagation&#xff09;就像是一个数据处理的流水线。从输入层开始&#xff0c;按照网络的层次结构&#xff0c;每一层的神经元接收上一层神经元的输出作为自己的输入&#xff0c;经过线性变换&#xff08;加权…...

解决git push报错:not valid: is this a git repository?

今天想把代码更新到仓库里&#xff0c;执行git push origin master:main的时候报错&#xff1a;not valid: is this a git repository? 查了好多方法都没用。后来经过这篇文章的启发&#xff1a;https://zhuanlan.zhihu.com/p/301518109 可能是由于校园网的问题&#xff0c;…...

树形查询转成TreeNode[],添加新节点

在使用PrimeVue的TreeTable组件时&#xff0c;需要将带有层级的数据转换为TreeNode[]类型的数据结构。TreeNode是PrimeVue中定义的一个接口&#xff0c;用于表示树节点。通常&#xff0c;带有层级的数据是一个嵌套的对象或数组&#xff0c;其中每个对象可能包含子对象&#xff…...

【Rust自学】8.2. Vector + Enum的应用

8.2.0. 本章内容 第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构&#xff0c;这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。 第八章中的集合是存储在堆内存上而非栈内存上的&#xff0c;这也意味着这些集合的数据大小无需在编…...

攻防世界web第十题Web_python_template_injection

这是题目&#xff0c;从题目上看是一个python模板注入类型的题目。 首先测试是否存在模板注入漏洞&#xff0c;构造http://61.147.171.105:57423/{{config}} 得到 说明存在模板注入漏洞&#xff0c;继续注入 构造http://61.147.171.105:57423/{{‘’.class.mro}}: 得到 再构造…...

vmware 修改Ubuntu终端字体大小

1. 2、 3、 4、 5、 6、点击select...

API 设计:从基础到最佳实践

https://levelup.gitconnected.com/api-design-101-from-basics-to-best-practices-a0261cdf8886 在本次深入研究中&#xff0c;我们将从基础开始&#xff0c;逐步了解 API 设计&#xff0c;并逐步实现定义卓越 API 的最佳实践。 作为开发人员&#xff0c;您可能熟悉其中的许多…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...