第一篇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 的过程,和逆向 *** 作(基础篇)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)