Cesium随笔:视锥绘制(上)

Cesium随笔:视锥绘制(上),第1张

第一篇CesiumJS技术日记,不管技术难不难,认真归纳是个好习惯。本文绕弯太多,要直接绘制视锥的请移步 这里 。

最近在研究视域分析,思路:使用ShadowMapjs接口开放的阴影绘制功能,指定点光源的相关参数。然而在调试的过程中发现并没有那么简单,生成ShadowMap对象时会抛出无法在参数中找到Context对象的异常,这个Context对象在Api文档中并没有提及,这个问题在 >

我们加载一个3DTileset 到地图里面了,怎样获取这个3DTileset 对象下面的feature呢。比如获取某个房屋的构件“窗子”

1,通过点击事件获取

2,通过对3DTileset 对象添加监听和回调函数获取

3,通过tileset tileVisible监听获取 feature

4,通过 _selectedTiles对象获取被选中的featrue

5,从Cesium3DTileFeature里获取Cesium3DTileset 

快三年了,在写了四篇文章,关于Cesium的基本都是水一下,不是不想写,一是没时间,二来确实比较懒,关于Cesium已经一年多没有看过了,最多也就关注一下官网的更新内容,对于Cesium深入了解还真没有下功夫。

最近公司业务调整,手头的业务也停掉了,只剩下维护了,也没有继续待着的意义了,趁着换工作的空,整理一下以前抄过、请教过、写过的一些东西吧,不确定能写多少,就简单记录一下吧。

Ceisum本身有一个clipPlane可以进行裁剪,但是不支持多边形裁剪,想要支持多边形裁剪也要费一番功夫。

多边形裁剪的主要原理:

一、构造裁剪多边形;

二、将构造多边形的定点归化到模型局部坐标系,并获取模型Rectangle,记录并传递给片元着色器;

三、将多边形渲染到到一张构造的纹理上,给多边形一个绘制的颜色,并将纹理赋值给片元着色器;

四、在顶点着色器中把从attribute获取到的定点传递给片元着色器,如

gl_Position = czm_projectionu_modelViewMatrix viewPos; //投影矩阵模型视图矩阵顶点坐标

中的viewPosxyz;

五、在片元着色器中,根据(四)中传递过来的顶点,判定该顶点是否在(二)中的rectangle中,若在,则计算该顶点在(三)中纹理的uv坐标,用texture2D(texture,uv)获取当前顶点的color值,若不为空,则继续,若为空则discard并返回。

通过以上步骤就可以实现以多边形为边界的模型裁剪。

加载了模型,可能会遇到白天模型很亮,但是晚上模型却很暗的问题,很明显会联想到cesium中模型会受到日光光照影响。

初始化cesium的时候,如果timeline设置为true,然后拖动时间线就可以观察模型亮度是随着时间变化的。

如果摇取消该光照影响,可以再初始化cesium时:

对于DirectionalLight的解释,可以查看官方文档 DirectionalLight

很多人用sceneMode 来进行二三维切换 ,其实这样不好用,位置什么的 图层状态都不好绑定,给人体验非常差

对于arcgis 引擎 可以锁视角实现平滑切换,mapbox 引擎也可以锁视角实现,但是对于cesium 也是可以的

首先我们要知道获取中心点方法

function getCenter(viewer: any) {

// debugger

const scene = viewerscene;

const target = pickCenterPoint(scene);

let bestTarget = target;

const globe = sceneglobe;

const carto = scenecamerapositionCartographicclone();

const height = globegetHeight(carto);

cartoheight = height || 0;

bestTarget = CesiumEllipsoidWGS84cartographicToCartesian(carto);

const result = formatPosition(bestTarget);

// 获取地球中心点世界位置 与 摄像机的世界位置 之间的距离

const distance = CesiumCartesian3distance(bestTarget, viewerscenecamerapositionWC);

resultcameraZ = distance;

return result;

}

function pickCenterPoint(scene: any) {

const canvas = scenecanvas;

const center = new CesiumCartesian2(canvasclientWidth / 2, canvasclientHeight / 2);

const ray = scenecameragetPickRay(center);

const target = sceneglobepick(ray, scene);

return target || scenecamerapickEllipsoid(center);

}

function formatPosition(position) {

const carto = CesiumCartographicfromCartesian(position);

const result = {};

resulty = formatNum(CesiumMathtoDegrees(cartolatitude), 6);

resultx = formatNum(CesiumMathtoDegrees(cartolongitude), 6);

resultz = formatNum(cartoheight, 2);

return result;

}

function formatNum(num, digits) {

return Number(numtoFixed(digits || 0));

}

第二我们要知道屏幕中心点位置

function getScreenCenter(_viewer: any) {

const viewer = _viewer;

const result = viewercamerapickEllipsoid(new CesiumCartesian2(viewercanvasclientWidth / 2, viewercanvasclientHeight / 2));

const curPosition = CesiumEllipsoidWGS84cartesianToCartographic(result);

const lon = (curPositionlongitude  180) / MathPI;

const lat = (curPositionlatitude  180) / MathPI;

const height = curPositionheight;

return {

x: lon,

y: lat

};

}

下面我们来定义调用切换二三维的方法, 其中mapType 我定义为mapView和sceneView类型, 哈哈学习arcgis模式

```javascript

type mapType = 'mapView' | 'sceneView';

public changeSV23D(viewer: any, type: mapType) {

const viewer = viewer;

const result: any = getCenter(viewer);

const curPosition = getScreenCenter(viewer);

const center = CesiumCartesian3fromDegrees(curPositionx, curPositiony);

if (type === 'sceneView') {

if (viewerview === 'sceneView') {

return;

}

viewerscenescreenSpaceCameraControllerenableTilt = true;

viewerview = 'sceneView';

let x = -90;

let pitch;

const range = resultcameraZ 12;

 更多参考 >

以上就是关于Cesium随笔:视锥绘制(上)全部的内容,包括:Cesium随笔:视锥绘制(上)、cesium加载动图方案三:通过apng-js库实现、从3DTileset 对象获取Cesium3DTileFeature 的过程,和逆向 *** 作(基础篇)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9566250.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存