Mesh指的是所有用三角形面组合成的三维物体,JS API 目前提供的 Mesh 类型有:Mesh、MeshAcceptLights、Prism、MeshLine 四种,MeshLine表现为带状线条,放在下一篇介绍
Mesh 和 MeshAcceptLights
Mesh
和 MeshAcceptLights
为 JS API 提供的比较底层的两个网格类型,默认的图元绘制类型为gl.TRIANGLES
。以绘制一个垂直于地面的矩形为例,首先我们创建一个Mesh实例:
创建Mesh实例
JavaScript
var rectangle = new AMap.Object3D.Mesh()
var geometry = rectangle.geometry;//创建之后获取geometry
设置attribute属性
接着需要给实例的geometry
的各个attribute
属性填入数值。任何一个 Object3D 的形体都具有顶点坐标、顶点颜色两个基本属性;如果有大量重复顶点的时候可以使用顶点索引;如果用到贴图的话,就需要顶点纹理坐标,多纹理的时候还会用到纹理索引;需要光照的时候还会有顶点法向量。
Gometry的属性 | 类型 | 说明 |
---|---|---|
vertices | Array<Number> | 存放顶点位置的一维数组,三个元素代表一个顶点的位置 |
vertexColors | Array<Number> | 存放顶点颜色的一维数组,四个元素代表一个顶点的颜色 |
faces | Array<Integer> | 存放三角形顶点索引的一维数组,三个元素代表一个三角形面。当faces长度不为0时,按照faces顶点索引来绘制;否则当faces长度为0时,按照vertices来以此绘制三角形面。 |
vertexUVs | Array<Number> | 存放顶点纹理坐标的一维数组,两个元素代表一个顶点的纹理坐标 |
textureIndices | Array<Integer> | 存放顶点纹理索引的一维数组,一个元素元素代表一个顶点的纹理索引。当Mesh的textures属性的长度大于1时,代表一个mesh使用多个纹理,textureIndices表示每个顶点使用哪个纹理。只使用一个纹理时,这个属性可以不设置 |
vertexNormals | Array<Number> | 存放顶点法向量的一维数组,三个元素元素代表一个顶点的法向量。MeshAcceptLights 专用。 |
以我们所要绘制垂直于地面的矩形为例,它拥有四个顶点V0、V1、V2、V3,首先我们要取得四个顶点的三维坐标,V0和V1的坐标的xy
分量值我们通过 Map
实例对象的lngLatToGeodeticCoord
方法可以算出,V2、V3在V0、V1的基础上增加 z
分量就可以了:
JavaScript
var lnglat1 = new AMap.LngLat(116.39, 39.9)
var lnglat2 = new AMap.LngLat(116.40, 39.9)
var v0xy = map.lngLatToGeodeticCoord(lnglat1);
var v1xy = map.lngLatToGeodeticCoord(lnglat2);
var z = -1000;//3D地图Z方向朝下,所以负值
geometry.vertices.push(v0xy.x, v0xy.y, 0);//V0
geometry.vertices.push(v1xy.x, v1xy.y, 0);//V1
geometry.vertices.push(v0xy.x, v0xy.y, z);//V3
geometry.vertices.push(v1xy.x, v1xy.y, z);//V2
矩形有两个三角形面F1(V0V1V3)、F2(V1V2V3)组成,我们这里使用了两个共享的顶点V1和V3所以可以启用faces
顶点索引,顶点索引的内容为构成三角形面的顶点在vertices
中的索引:
JavaScript
geometry.faces.push(0, 1, 3)
geometry.faces.push(1, 2, 3)
接着我们可以给四个顶点赋予相应的颜色值,默认情况下不开启颜色混合,如果使用了透明颜色或者透明贴图需要设置 Mesh
实例的transparent
属性为true
方能看到透明混合的效果:
JavaScript
geometry.vertexColors.push(1, 0, 0, 1); //V0
geometry.vertexColors.push(0, 1, 0, 1); //V1
geometry.vertexColors.push(0, 0, 1, 1); //V2
geometry.vertexColors.push(0, 1, 1, 1); //V3
rectangle.transparent = false;
也可以使用纹理给进行填色,设定纹理坐标的同时需要给mesh
的texturs
中添加一张纹理图片
JavaScript
rectangle.textures.push("https://a.amap.com/jsapi_demos/static/tourist/crate.gif");
使用纹理时需要给所有顶点添加纹理坐标,纹理坐标以图片的左上角为原点,
x轴朝右,y轴朝下:
geometry.vertexUVs.push(0, 1); //V0
geometry.vertexUVs.push(1, 1); //V1
geometry.vertexUVs.push(1, 0); //V2
geometry.vertexUVs.push(0, 0); //V3
vertexNormals
为MeshAcceptLights
专有的属性,用作记录顶点法向量,来实现光照,这里不细说明。
添加到 Object3DLayer
做好上面的工作之后将 Mesh
实例添加到Object3DLayer
中即可,Mesh
类型默认以顺时针为正面,默认显示反面,可以通过Mesh
的backOrFront
属性来控制显示正反面,这里我们开启两面。
JavaScript
rectangle.backOrFront = 'both';//'back'、'front'、'both'
object3DLayer.add(rectangle)
棱柱 Prism
为了简化使用,我们在 MeshAcceptLights
之上封装了Prism
类型,Prism 可以基于经纬度、高度、颜色来构建不规则棱柱体,使用方法如下:
JavaScript
var bounds = [
new AMap.LngLat(116.5,39.25),
new AMap.LngLat(116.75,39.5),
new AMap.LngLat(116.5,39.75),
new AMap.LngLat(116.25,39.5)
]
var height = 500000;
var color = [0,0,1,0.6];
var prism2 = new AMap.Object3D.Prism({
path:island,
height:height,
color:color
});
垂面 Wall
垂面为垂直于地面的一个折面,用法同Prism
,通过经纬度path、高度height、颜色color来定义,可接收全局光照。与Prism
的区别是 Wall
没有顶面,只有侧面。