立方体、球、圆柱体与面

几何数据

Geometry的真实面目

3D渲染依赖于网格,你所看到的所有模型,在引擎内部都会被当作网格同等对待。网格由egret3d.Mesh类实现。一个网格中需要两个重要成员,网格数据与贴图数据。网格数据由CubeGeometry对象实现。其中包含一个模型所需要的顶点数据,索引数据以及顶点法线数据等。

显而易见,我们创建的Geometry对象,无非是创建了一个组有序且能够被引擎所里的数据而已。

Tip

Geometry只是一组数据的抽象结果,仅此而已。

几何体抽象结构

Egret3D中几何体的具体类实现是由Geometry完成的,通过网络所加载的模型数据最终也会为我们创建一个Geometry对象。

Geometry存在4个子类,这4个子类是引擎中预定义标准几何体。

Tip

几何体抽象层的类位于引擎源码的geometry目录中。

属性锁定

属性锁定操作仅存在于4个预定义标准几何体中。我们以立方体为例,其余几何体相同。

CubeGeometry存在3个属性,你可以通过API文档查阅到。3个属性分别为width、height和depth。

查看CubeGeometry源码会发现width、height和depth均为只读属性。你无法在数据生成后动态修改其中的顶点数据。

//egret3d.CubeGeometry源码片段
private _width: number = 80;
public get width(): number {
	return this._width;
}
private _height: number = 80;
public get height(): number {
	return this._height;
}
private _depth: number = 80;
public get depth(): number {
	return this._depth;
}

因为属性锁定的存在,只能在几何体创建时修改其值。这是由于创建CubeGeometry对象时,其构造函数会调用一个名称为buildGeomtry的内部私有函数。这个函数会根据width、height和depth三个值创建顶点数据与顶点索引数据,数据一旦被创建就无法修改。

Tip

width、height和depth属性是模型数据的计算因子,一旦计算完成,数据进入GPU寄存器,这些属性仅供你读取操作。

立方体

立方体是三维空间中最为简单的几何体,立方体就像三维空间中的“Hello World”一样,是经典的入门示例。第二章我们已经接触过立方体的示例,这里不再赘述,仅对其中的一些细节进行讨论。

创建立方体

创建立方体并添加到显示视图核心代码如下:

var cube:egret3d.CubeGeometry = new egret3d.CubeGeometry();
var mat:egret3d.TextureMaterial = new egret3d.TextureMaterial();
this.model = new egret3d.Mesh(cube, mat);
this._view3D.addChild3D(this.model);

编译后运行结果如下:

width、height和depth的默认值均为80,如果需要修改其尺寸,只需要在创建时填写对应参数即可。

//width 100
//height 50
//depth 60
var cube:egret3d.CubeGeometry = new egret3d.CubeGeometry(100,50,60);

width、height和depth属性

这三者分辨对应立方体在三维空间中对应x,y,z轴的线段长度。

由于它仅仅定义线段长度,所以我们无法获取它们之间的相对位置关系以及在对应轴上面的起点与终点坐标。

Tip

width、height和depth仅仅表示长度。

球体

创建球体

创建球体并添加到显示视图核心代码如下:

 var sph:egret3d.SphereGeometry = new egret3d.SphereGeometry(100,50,50);
var mat:egret3d.TextureMaterial = new egret3d.TextureMaterial();
this.model = new egret3d.Mesh(sph, mat);
this._view3D.addChild3D(this.model);

编译后运行结果如下:

segmentsW、segmentsH和radius属性

radius属性是球体的半径,默认半径为100。segmentsWsegmentsH分别是球体的宽度分段数和高度分段数,其默认值均为15。

什么是宽度分段数和高度分段数?看下图便会一目了然。

左侧图片为高度丰等分线示意图,右侧图片为宽度等分线示意图。我们将一个球体横纵两个方向将其平分。当我们的等高线越多,球体边缘就会越加平滑。

为何让大家更好的观察等分线对球体模型影响效果,我们制作两个球体,第一个球体等分线数量均为10,第二个等分线数量为50。运行后对比图如下:

球体与立方体的差异

现在我们将接触一个新的概念——面,后面的章节中会深入讨论“面”的问题。这里仅做一个简单介绍。

球体中,由于存在等分线,我们可以想象球体被切割成多个小块。等分线数量越多,被切分的小方块越多。而立方体无论我们设置它的尺寸为多少,永远都是存在6个面。这是两个几何体最大的区别。

影响这些面的生层次因素是产生的顶点数量不同,后续章节会进行讨论。

创建面

创建面并添加到显示视图核心代码如下:

var plane:egret3d.PlaneGeometry = new egret3d.PlaneGeometry();
var mat:egret3d.TextureMaterial = new egret3d.TextureMaterial();
this.model = new egret3d.Mesh(plane, mat);
this._view3D.addChild3D(this.model);

编译后运行结果如下:

面的属性

面的属性较多,但大部分属性在其他几个预定义几何体中都出现过,其作用也相同。

6个属性中的UV是我们到目前为止还没有接触过的概念,不要着急。目前UV还不会影响到我们学习3D开发,这部分会在后面章节讲解纹理贴图的时候深入介绍。

另外一个新概念需要你小小的好奇心才能发现,当你拖拽鼠标,观察面的另一面时,你会发现什么都看不到了,这是因为有个叫做“法线”的家伙在作怪。关于“法线”后面的章节中也会深入讨论,现在还不是时候。