Primitive 的组成
前面我们提到,Primitive 由两部分组成
1、几何形状(Geometry):定义了 Primitive 的结构,例如三角形、线条、点等
2、外观(Appearance ):定义 Primitive 的着色(Sharding)
Geometry - 几何形状
在Cesium中,支持以下几种 Geometry 几何图形
| 几何图形 | 说明 |
|---|---|
| BoxGeometry | 立方体 |
| BoxOutlineGeometry | 仅有轮廓的立方体,只有外部线条的的盒子 |
| CircleGeometry | 圆形或者拉伸的圆形,圆圈或挤压圆 |
| CircleOutlineGeometry | 只有轮廓的圆形 |
| CorridorGeometry | 走廊:沿着地表的多段线(垂直于表面的折线),且具有一定的宽度,可以拉伸到一定的高度 |
| CorridorOutlineGeometry | 只有轮廓的走廊 |
| CylinderGeometry | 圆柱、圆锥或者截断的圆锥 |
| CylinderOutlineGeometry | 只有轮廓的圆柱、圆锥或者截断的圆锥 |
| EllipseGeometry | 椭圆或者拉伸的椭圆 |
| EllipseOutlineGeometry | 只有轮廓的椭圆或者拉伸的椭圆 |
| EllipsoidGeometry | 椭球体 |
| EllipsoidOutlineGeometry | 只有轮廓的椭球体 |
| RectangleGeometry | 矩形或者拉伸的矩形 |
| RectangleOutlineGeometry | 只有轮廓的矩形或者拉伸的矩形 |
| PolygonGeometry | 多边形,可以具有空洞或者拉伸一定的高度 |
| PolygonOutlineGeometry | 只有轮廓的多边形 |
| PolylineGeometry | 多段线,可以具有一定的宽度 |
| SimplePolylineGeometry | 简单的多段线 |
| PolylineVolumeGeometry | 多段线柱体 |
| PolylineVolumeOutlineGeometry | 只有轮廓的多段线柱体 |
| SphereGeometry | 球体 |
| SphereOutlineGeometry | 只有轮廓的球体 |
| WallGeometry | 墙 |
| WallOutlineGeometry | 只有轮廓的墙 |
Geometry Instances - 几何图形实例
它相当于 Geometry 的容器,而多个 Instance 可以公用一个 Geomotry 并利用 GeometryInstance.modelMatrix 提供多种属性信息
// 以原点为中心创建一个立方体
var geometry = Cesium.BoxGeometry.fromDimensions({
vertexFormat: Cesium.VertexFormat.POSITION_AND_NORMAL,
dimensions: new Cesium.Cartesian3(1000000.0, 1000000.0, 500000.0)
});
// 几何实例化允许一个 Geometry 对象在多个对象中的位置不同的位置和独特的颜色
var instanceBottom = new Cesium.GeometryInstance({
geometry: geometry,
modelMatrix: Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)
},
id: 'bottom'
});
var instanceTop = new Cesium.GeometryInstance({
geometry: geometry,
modelMatrix: Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 3000000.0), new Cesium.Matrix4()),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)
},
id: 'top'
});
Combing Geometries - 合并几何图形
我们可以合并多个 Instance(几何实例) 为一个 Primitive,提高我们的性能
var instances = [Instance1, Instance2, Instance3];
scene.primitives.add(new Cesium.Primitive({
geometryInstances: instances, //合并
// 某些外观允许每个几何图形实例分别指定某个属性,例如:
appearance: new Cesium.PerInstanceColorAppearance({ translucent: false, closed: true })
}));
选取几何图形
即使多个 GeometryInstance 被合并为单个 Primitive,让然可以独立的被访问。我们可以为每一个GeometryInstance 指定一个id,并且可以通过 Scene.pick 来判断该实例是否被选取
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
// 创建几何实例
var instance = new Cesium.GeometryInstance({
geometry: new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0)
}),
id: 'rectangle-1',
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
}
});
// 添加到 Primitive
scene.primitives.add(new Cesium.Primitive({
geometryInstances: instance,
appearance: new Cesium.PerInstanceColorAppearance()
}));
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
// 监听单击事件
handler.setInputAction(function (movement) {
var pick = scene.pick(movement.position);
if (Cesium.defined(pick) && (pick.id === 'rectangle-1')) {
console.log('矩形被选取');
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
更新单个 Instance 属性
在添加到Primitive后,我们仍然可以通过Id获取指定Instance并修改其属性
// 创建实例并添加
var circleInstance = new Cesium.GeometryInstance({
geometry: new Cesium.CircleGeometry({
center: Cesium.Cartesian3.fromDegrees(-95.0, 43.0),
radius: 250000.0,
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5)),
show: new Cesium.ShowGeometryInstanceAttribute(true) //显示或者隐藏
},
id: 'circle'
});
var primitive = new Cesium.Primitive({
geometryInstances: circleInstance,
appearance: new Cesium.PerInstanceColorAppearance({
translucent: false,
closed: true
})
});
scene.primitives.add(primitive);
// 获取某个实例的属性集
var attributes = primitive.getGeometryInstanceAttributes('circle');
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({
alpha: 1.0
}));
Appearance - 外观
Cesium 支持以下列出的 Appearance
| 外观 | 描述 |
|---|---|
| MaterialAppearance | 支持各种Geometry类型的外观,支持使用材质来定义着色。支持材料描述阴影 |
| EllipsoidSurfaceAppearance | MaterialAppearance的一个版本。假设几何图形与地表是平行的,并且依此来进行顶点属性(vertex attributes)的计算。和Material Appearance一样,就像一个多边形,并且使用这个假设来通过程序上计算许多顶点属性来节省内存 |
| PerInstanceColorAppearance | 让每个实例使用自定义的颜色来着色,使用每个实例的颜色来遮蔽每个实例 |
| PolylineMaterialAppearance | 支持使用材质来着色多段线。支持材料遮蔽Polyline |
| PolylineColorAppearance | 使用每顶点或者每片段(per-vertex or per-segment )的颜色来着色多段线—使用每顶点或每段着色来遮蔽折线 |
Appearance 定义了需要在 GPU 上执行的 GLSL着色器,这部分一般只有在自定义外观时需要修改。
Render state 用来在绘制 Primitive 的时候控制 GPU状态,一旦外观被创建,render state 就不能再改变了,但是我们可以修改其材质
// 下面的外观可用于定义一个 Viewer 不可进入的不透明盒子
var appearance = new Cesium.PerInstanceColorAppearance({
translucent: false,
closed: true
});
// 下面的代码效果同上
var translucent = new Cesium.PerInstanceColorAppearance({
renderState: {
depthTest: {
enabled: true
},
cull: {
enabled: true,
face: Cesium.CullFace.BACK
}
}
});
Primitive 常见参数
geometryInstances,它是 Primitive 最基本的要素之一,定义了绘制要素的几何形状
appearance:几何要素显示出来的外观
modelMatrix:几何形状的4元素变换矩阵。可提供绘制要素位置并对其进行旋转、平移、缩放等操作
show:是否渲染