Cesium之使用polygon简要总结

需求:

cesium中画不规则的多面体包围盒,简称volume,并且可移动。

P.S. 以下<component>基于Vue组件的表示

1. 方案一 Entity之PolygonGraphics

<component v-for="(positions, index) in volume">
	// https://cesium.com/learn/cesiumjs-learn/cesiumjs-creating-entities/
	// https://cesium.com/learn/cesiumjs/ref-doc/PolygonGraphics.html
	viewer.entities.add({
  		name: ""+index,
  		polygon: {
    		hierarchy: new Cesium.PolygonHierarchy(positions),
			perPositionHeight: true,
			// ...
  		},
	});
</component>

基本功能没问题,而且更改颜色、轮廓等接口非常方便。Entity就是好用。
缺点是卡顿非常严重,且有拖影,节流后可适当减少拖影。

2. 方案二 Entity之PolygonGraphics+CallbackProperty

<component v-for="(positionsMutable, index) in volume">
	// https://cesium.com/learn/cesiumjs/ref-doc/PolygonGraphics.html
	viewer.entities.add({
  		name: ""+index,
  		polygon: {
    		hierarchy: new new Cesium.CallbackProperty(function (time, result) {
    			return positionsMutable
			}, /*isConstant*/ false),
			perPositionHeight: true,
			// ...
  		},
	});
</component>

从万能的stackoverflow,看到了CallbackProperty这么个玩意。
基本功能还是没问题。拖影还是存在,cesium的顶点数据更新策略有点让人摸不清,居然不是一起更新的,也没看到什么loadAsync的开关。
节流后,卡顿有所缓解,但是还是能感知到存在。

3. 方案三 Primitive之PolygonGeometry+PolygonOutlineGeometry

卡顿与拖影的根本原因,还是在顶点数据的更新上。可能出于性能原因,cesium选择不实时检测及更新Entity的顶点数据(待后面有机会再探究了)。
那么有没有什么东西,是频繁变化更新的呢?
众所周知,在OpenGL里面,layout 是非常重的东西,一般给场景中不太变化的大量数据准备,也是直接影响shader计算的数据;但是在drawcall中MVP三个投影参数,是比较小且经常需要变化的,即Uniforms。
那么如果我每次移动只是操作模型的变换矩阵,是不是就能从根本上解决卡顿与拖影呢?理论上应该是的才对。
Use advanced CesiumJS features 可以找到在这里插入图片描述
Custom,嗯,这个应该就是我要的了。
cesium提供了较低层的接口,Primitive。其中PolygonGeometry正是我们想要的。


	// https://cesium.com/learn/cesiumjs-learn/cesiumjs-geometry-appearances/
	const instances = []
	const length = volume.length
	for(let i = 0; i < length; ++i) {
		var instance = new Cesium.GeometryInstance({
  			geometry : new Cesium.PolygonGeometry({
    			polygonHierarchy: Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
    			vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
  			}),
  			attributes: {
				//color:...
  			}
		});
		instances.push(instance)
	}
	
	const primitive = scene.primitives.add(new Cesium.Primitive({
  		geometryInstances : [instance, anotherInstance],
  		modelMatrix : Cesium.Matrix4.Matrix4.fromTranslation(new Cesium.Cartesian3(translation), new Cesium.Matrix4()),
  		appearance : new Cesium.EllipsoidSurfaceAppearance({
    		// ...
  		})
	}));
	function onDrag() {
		translation = updateTranslation()
		// 实时更新!!!
		primitive.modelMatrix = Cesium.Matrix4.Matrix4.fromTranslation(new Cesium.Cartesian3(translation), new Cesium.Matrix4()),
	}
	

OK,到这似乎一切都结束了。没有拖影,也没有卡顿,一切都是那么完美。
但是,等等,为什么有些面只有一个三角形???

4. 方案四 Primitive之CoplanarPolygonGeometry+CoplanarPolygonOutlineGeometry

很早就有人提出过这个问题,为啥有些面会显示不全:
Small Wall or Verticle Polygon not rendering properly

2018年一位大佬开发了一个接口用来支持任意多边形:
CoplanarPolygonGeometry and CoplanarPolygonOutlineGeometry
Support for vertical polygons

支持带洞的多边形
Add holes and stRotation to coplanar polygon

由于CoplanarPolygonOutlineGeometry的demo太难找,适配这玩意也花了挺多时间。其实在cesium仓库中已经存在一个非常好用的demo。
Sandcastle/gallery/development/Coplanar Polygon Outline.html

打完收工,有坑再填

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值