在Unity3D中创建一个Cube,在Inspector可以看到其中含有MeshFilter、MeshRenderer组件。
MeshFilter含有一个Public成员 Mesh。
在Mesh中存储着三维模型的数据:vertices(顶点数据数组Vector3[])、triangles(三角形顶点索引数组,int[])、normals(法线向量数组,Vector3[])、uv(纹理坐标数组,Vector2[])。
创建一个脚本dyn3d.cs,成为Main Camera的组件,点击运行即可看到动态生成的Cube
1 using UnityEngine;
2 using System.Collections;
3
4 public class dyn3d : MonoBehaviour {
5
6 // Use this for initialization
7 void Start () {
8
9 CreateCube();
10 }
11
12 // Update is called once per frame
13 void Update () {
14
15 }
16
17 void CreateCube()
18 {
19
20 GameObject obj=new GameObject("cube");
21 MeshFilter mf=obj.AddComponent<MeshFilter>();
22 MeshRenderer mr=obj.AddComponent<MeshRenderer>();
23
24
25 Vector3[] vertices=new Vector3[24];
26 int[] triangles=new int[36];
27
28 //forward
29 vertices[0].Set(0.5f,-0.5f,0.5f);
30 vertices[1].Set(-0.5f,-0.5f,0.5f);
31 vertices[2].Set(0.5f,0.5f,0.5f);
32 vertices[3].Set(-0.5f,0.5f,0.5f);
33 //back
34 vertices[4].Set(vertices[2].x,vertices[2].y,-0.5f);
35 vertices[5].Set(vertices[3].x,vertices[3].y,-0.5f);
36 vertices[6].Set(vertices[0].x,vertices[0].y,-0.5f);
37 vertices[7].Set(vertices[1].x,vertices[1].y,-0.5f);
38 //up
39 vertices[8]=vertices[2];
40 vertices[9]=vertices[3];
41 vertices[10]=vertices[4];
42 vertices[11]=vertices[5];
43 //down
44 vertices[12].Set(vertices[10].x,-0.5f,vertices[10].z);
45 vertices[13].Set(vertices[11].x,-0.5f,vertices[11].z);
46 vertices[14].Set(vertices[8].x,-0.5f,vertices[8].z);
47 vertices[15].Set(vertices[9].x,-0.5f,vertices[9].z);
48 //right
49 vertices[16]=vertices[6];
50 vertices[17]=vertices[0];
51 vertices[18]=vertices[4];
52 vertices[19]=vertices[2];
53 //left
54 vertices[20].Set(-0.5f,vertices[18].y,vertices[18].z);
55 vertices[21].Set(-0.5f,vertices[19].y,vertices[19].z);
56 vertices[22].Set(-0.5f,vertices[16].y,vertices[16].z);
57 vertices[23].Set(-0.5f,vertices[17].y,vertices[17].z);
58
59 int currentCount=0;
60 for(int i=0;i<24;i=i+4)
61 {
62 triangles[currentCount++]=i;
63 triangles[currentCount++]=i+3;
64 triangles[currentCount++]=i+1;
65
66 triangles[currentCount++]=i;
67 triangles[currentCount++]=i+2;
68 triangles[currentCount++]=i+3;
69
70 }
71
72 mf.mesh.vertices=vertices;
73 mf.mesh.triangles=triangles;
74
75 }
76 }
在这里定义vertices数组存储顶点坐标信息,定义triangles数组存储三角形顶点索引。但是这个Mesh不包含normals和uv信息,所以显示出来的正方体是无纹理贴图,并且不能反应环境光照的。
正方体6个面,每个面由2个三角形组成,所以共需要36个三角形顶点索引。但是正方体只有8个顶点,为什么需要24个顶点坐标数据呢?
答案是:Unity3D的Mesh.triangles是三角形索引数组,不仅依靠这个索引值索引三角形顶点坐标,而且索引纹理坐标,索引法线向量。即正方体的每个顶点都参与了3个平面,而这3个平面的法线向量是不同的,该顶点在渲染这3个平面的时候需要索引到不同的法线向量。而由于顶点坐标和法线向量是由同一个索引值triangles[Index]取得的,例如,根据triangles[0],triangles[14],triangles[17]在vertices中索引到的顶点都为(0.5,-0.5,0.5),但是在normals中索引到的法向量值各不相同。这就决定了在正方体中一个顶点,需要有3份存储。(如果你需要创建其它模型,需要根据实际情况决定顶点坐标的冗余度。实质上顶点坐标的冗余正是方便了法线坐标、纹理坐标的存取。)
准则:三角形有两面,正面可见,背面不可见。三角形的渲染顺序与三角形的正面法线呈左手螺旋定则。
这就决定了,如果我们需要渲染如下一个正方形面,那么就需要保证组成这个正方形的两个小三角形的正面法线都是指向屏幕外的。
我在程序中的顶点顺序为,三角形1: 0->3->1,三角形2: 0->2->3 。
1 int currentCount=0;
2 for(int i=0;i<24;i=i+4)
3 {
4 //三角形1
5 triangles[currentCount++]=i;
6 triangles[currentCount++]=i+3;
7 triangles[currentCount++]=i+1;
8 //三角形2
9 triangles[currentCount++]=i;
10 triangles[currentCount++]=i+2;
11 triangles[currentCount++]=i+3;
12 }
这段代码保证了正方体的6个面,12个三角形的都正确被渲染(正面法线朝外)。
在多媒体通信领域,MRCP(Media Resource Control Protocol)协议被广泛用于控制语音识别和合成等媒体资源。UniMRCP是一个开源的MRCP实现,提供了客户端和服务端的库。UmcFramework是一个基于UniMRCP客户端库的示例应用程序框架,它帮助开发者快速集成和测试MRCP客户端功能。本文将详细介绍如何使用UmcFramework和unimrcpclient.xml配置文件连接到多个SIP设置,以及如何用C代码进行示例说明。
文章浏览阅读3k次。报错:java.net.ProtocolException: Server redirected too many times (20)1.没有检查到cookie,一直循环重定向。解决:CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));URL url = new URL(url); ..._java.net.protocolexception: server redirected too many times (20)
文章浏览阅读4.1k次。问题这是部分报错信息2019-07-11 14:03:34.283 WARN [restartedMain][DirectJDKLog.java:175] - Failed to scan [file:/D:/repo/org/apache/derby/derby/10.14.2.0/derbyLocale_ja_JP.jar] from classloader hierarchyjava...._failed to scan from classloader hierarchy
文章浏览阅读2.8k次,点赞3次,收藏7次。在MATLAB中,ones函数用于创建一个指定大小的由1组成的矩阵或数组。_matlab中ones函数
文章浏览阅读3.9w次,点赞2次,收藏9次。 在使用电脑办公过程中,安装应用程序时难免遇到无法安装或者无法正常启动的问题,这对我们使用电脑带来了诸多不便。那遇到应用程序无法正常启动的问题要如何解决呢?相信大家肯定都是十分疑问的,每次都是只能忍痛重新安装软件。今天,小编就和大家探讨下应用程序无法正常启动的解决方法,帮助大家排忧解难。0xc000007b电脑图解1 第一种方案:SFC检查系统完整性来尝试修复丢失文件 1、打开电脑搜索输入cmd.exe,选择以管理员身份运行,跳出提示框时选择继续。0xc000007b电脑图解2_photoshop应用程序无法正常启动0xc000007b。请单击“确认”关闭应用程序。
文章浏览阅读396次。1、概念 REDO LOG是Oracle为确保已经提交的事务不会丢失而建立的一个机制。实际上REDO LOG的存在是为两种场景准备的:实例恢复(INSTANCE RECOVERY);介质恢复(MEDIA RECOVERY)。 实例恢复的目的是在数据库发生故障时,确保BUFFER CACHE中的数据不会丢失,不会造成数据库的..._oracle 实例恢复和介质恢复
文章浏览阅读141次。之前几章演示的熔断,降级 都是 RestTemplate + Ribbon 和RestTemplate + Hystrix ,但是在实际开发并不是这样,实际开发中都是 Feign 远程接口调用。Feign + Hystrix 演示: eruka(略)order 服务工程: pom.xml<?xml version="1.0" encoding="U..._this is order 服务工程
文章浏览阅读3.4k次,点赞35次,收藏43次。学习率是影响目标检测精度和速度的重要因素之一。合适的学习率调度策略可以加速模型的收敛和提高模型的精度。在YOLOv7算法中,可以使用基于余弦函数的学习率调度策略(Cosine Annealing Learning Rate Schedule)来调整学习率。
文章浏览阅读4k次,点赞4次,收藏9次。 linux中进程退出函数:exit()和_exit()的区别(1)_exit()执行后立即返回给内核,而exit()要先执行一些清除操作,然后将控制权交给内核。(2)调用_exit函数时,其会关闭进程所有的文件描述符,清理内存以及其他一些内核清理函数,但不会刷新流(stdin, stdout, stderr ...). exit函数是在_exit..._linux结束进程可以用哪些函数,它们之间有何区别?
文章浏览阅读134次。select 5000/10000.0 --想变成0.5select 5500/10000.0 --想变成0.55select 5550/10000.0 --想变成0.555select 5555/10000.0 --想变成0.5555其结果分别为:0.5000000 0.5500000 0.5550000 0.5555000一、如果想去掉数字5后面多余的0 ,需要转化一下:selec..._sql server 去小数 0
文章浏览阅读3.1k次。例一:import { Injectable } from '@angular/core';import { Observable } from 'rxjs';import { User } from "./model/User";import { map } from 'rxjs/operators';import { Http, Response, Headers, RequestOp..._angular6,requestoptions改成了什么
文章浏览阅读7.9k次,点赞17次,收藏110次。C++读取XML文件_c++ xml解析