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个面,每个面包含的数据包括4个顶点的相对顶点坐标(Cube的中心为原点),法线方向,UV坐标,顶点渲染顺序,以及这个面用到的材质,因为这里是Top&am…...
2、pycharm常用快捷命令和配置【持续更新中】
1、常用快捷命令 Ctrl / 行注释/取消行注释 Ctrl Alt L 代码格式化 Ctrl Alt I 自动缩进 Tab / Shift Tab 缩进、不缩进当前行 Ctrl N 跳转到类 Ctrl 鼠标点击方法 可以跳转到方法所在的类 2、使用pip命令安装request库 命令:pip install requests 安装好了…...
Go语言方法和接收器类型详解
Go语言方法和接收器类型详解 1. 方法接收器类型 1.1 值接收器 值接收器方法不会改变接收器的状态,因为Go语言会在调用时复制接收器的值。因此,任何对接收器成员变量的修改都只会影响副本,而不会影响原始结构体实例。 type Person struct …...
Flutter:打包apk,详细图文介绍(一)
困扰了一天,终于能正常打包apk安装了,记录下打包的流程。建议参考我这篇文章时,同时看下官网的构建说明。 官网构建并发布 Android 应用详情 1、AS创建Flutter项目 2、cmd执行命令 生成一个sunluyi.jks的文件,可以自行把sunluyi替…...
Vue.js组件开发-实现动态切换菜单简单示例
在Vue.js中,实现动态切换菜单通过组件化开发和Vue的响应式数据绑定来实现。 示例: 展示如何创建一个可以动态切换菜单的Vue组件。 首先,需要定义一个Vue组件,该组件将包含菜单项和用于切换菜单的状态。 1. 创建Vue组件 <t…...
如何在 Ubuntu 22.04 上优化 Apache 以应对高流量网站教程
简介 在本教程中,我们将学习如何优化 Apache 以应对高流量网站。 当运行高流量网站时,确保你的 Apache Web 服务器得到优化对于有效处理负载至关重要。在本指南中,我们将介绍配置 Apache 以提高性能和可扩展性的基本技巧。 为高流量网站优…...
17爬虫:关于DrissionPage相关内容的学习01
概述 前面我们已经大致了解了selenium的用法,DerssionPage同selenium一样,也是一个基于Python的网页自动化工具。 DrissionPage既可以实现网页的自动化操作,也能够实现收发数据包,也可以把两者的功能合二为一。 DressionPage的…...
【HarmonyOS之旅】HarmonyOS概述(一)
目录 1 -> HarmonyOS简介 2 -> HarmonyOS发展历程 3 -> HarmonyOS技术特性 3.1 -> 硬件互助,资源共享 3.1.1 -> 分布式软总线 3.1.2 -> 分布式设备虚拟化 3.1.3 -> 分布式数据管理 3.1.4 -> 分布式任务调度 3.1.5 -> 分布式连接…...
chatwoot 开源客服系统搭建
1. 准备开源客服系统(我是用的Chatwoot ) 可以选择以下开源客服系统作为基础: Chatwoot: 开源,多语言,跟踪和分析,支持多渠道客户对接,自动化和工作流等。源码Zammad: 现代的开源工单系统。Fr…...
30分钟搭建 Typecho 个人博客教程
Typecho是一款PHP博客程序,相比于WordPress,Typecho显得更加的轻量级和简洁。现在越来越多的人倾向于用Typecho来搭建个人博客——众所周知,能跑WordPress的机器都不便宜。 Typecho是一款国人团结打造的开源博客系统,和WordPress…...
智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之7 附件(文档)
为AI聊天工具添加一个知识系统 Part1 人性化&去中心化 前情提要 这一次我们暂时抛开前面对“智能工厂的软件设计”的考虑--其软件智能 产品就是 应用程序。直接将这些思维方式和方法论 运用在其具体应用场景中。本文是其中的一个应用场景。 今天用了 一个新的AI助手工具…...
鸿蒙应用开发启航计划
以前有过简单的学习了解,但是现在工作内容的原因,要专门搞这个,因此需要更加熟练地掌握鸿蒙应用开发。 1.开发IDE -- DevEco Studio Windows环境 运行环境要求 为保证DevEco Studio正常运行,建议电脑配置满足如下要求ÿ…...
基本算法——回归
目录 创建工程 加载数据 分析属性 创建与评估回归模型 线性回归 回归树 评估 完整代码 结论 本节将通过分析能源效率数据集(Tsanas和Xifara,2012)学习基本的回归算法。我们将基 于建筑的结构特点(比如表面、墙体与屋顶面…...
深度学习——神经网络中前向传播、反向传播与梯度计算原理
一、前向传播 1.1 概念 神经网络的前向传播(Forward Propagation)就像是一个数据处理的流水线。从输入层开始,按照网络的层次结构,每一层的神经元接收上一层神经元的输出作为自己的输入,经过线性变换(加权…...
解决git push报错:not valid: is this a git repository?
今天想把代码更新到仓库里,执行git push origin master:main的时候报错:not valid: is this a git repository? 查了好多方法都没用。后来经过这篇文章的启发:https://zhuanlan.zhihu.com/p/301518109 可能是由于校园网的问题,…...
树形查询转成TreeNode[],添加新节点
在使用PrimeVue的TreeTable组件时,需要将带有层级的数据转换为TreeNode[]类型的数据结构。TreeNode是PrimeVue中定义的一个接口,用于表示树节点。通常,带有层级的数据是一个嵌套的对象或数组,其中每个对象可能包含子对象ÿ…...
【Rust自学】8.2. Vector + Enum的应用
8.2.0. 本章内容 第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构,这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。 第八章中的集合是存储在堆内存上而非栈内存上的,这也意味着这些集合的数据大小无需在编…...
攻防世界web第十题Web_python_template_injection
这是题目,从题目上看是一个python模板注入类型的题目。 首先测试是否存在模板注入漏洞,构造http://61.147.171.105:57423/{{config}} 得到 说明存在模板注入漏洞,继续注入 构造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 在本次深入研究中,我们将从基础开始,逐步了解 API 设计,并逐步实现定义卓越 API 的最佳实践。 作为开发人员,您可能熟悉其中的许多…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
