Cesium实现动态旋转四棱锥(2023.9.11) 您所在的位置:网站首页 四菱锥体图片 Cesium实现动态旋转四棱锥(2023.9.11)

Cesium实现动态旋转四棱锥(2023.9.11)

2024-06-05 16:45| 来源: 网络整理| 查看: 265

Cesium实现动态悬浮旋转四棱锥效果 2023.9.11 1、引言2、两种实现思路介绍2.1 思路一:添加已有的四棱锥(金字塔)模型实现(简单但受限)2.2 思路二:自定义四棱锥几何模型实现(复杂且灵活) 3、代码实现及效果展示3.1 思路一3.1.1 代码实现3.1.2 展示结果 3.2 思路二3.2.1 代码实现3.2.2 展示结果 4、总结

1、引言

        最近看到一些数字城市特效,其中包含四棱锥动态旋转的效果,乍一看眼前一亮,静下来来冷静思考觉得实现起来应该也十分简单,于是打算写此博客与诸位开发者共同分享,当然也是为了记录学习点滴!🕺🕺🕺❤️❤️❤️

2、两种实现思路介绍

        顾名思义,动态悬浮旋转四棱锥效果中的关键词包括:四棱锥(金字塔)、旋转、动态。

2.1 思路一:添加已有的四棱锥(金字塔)模型实现(简单但受限)

        寻找并选择一个现成的四棱锥模型(gltf 或 glb文件),调用Cesium添加Model的API将其作为模型加载到三维场景当中,之后动态设置旋转角度、位置高度即可。         假设准备好的模型文件为pyramid.glb文件,利用Windows系统自带的3D查看器通过设置跳跃、悬浮等动作即可预览动态效果。

在这里插入图片描述 在这里插入图片描述

2.2 思路二:自定义四棱锥几何模型实现(复杂且灵活)

        调用Cesium底层API自定义几何形状(Geometry)和原型(Primitive),构造属于四棱锥的DrawCommand类,实现create方法在三维场景(Scene)中添加四棱锥几何形状并设置纹理显示,实现update方法在每一帧画面中更新显示动态旋转及上下悬浮效果。

图1 四棱锥几何立体示意 注:红色圆圈代表顶点、橙色数字代表顶点索引编号、蓝色实线代表各边。

        值得注意的是,我们仍需明确有关正四棱锥的一些数学理论知识:在三维立体几何空间中,四棱锥包含5个顶点、6个三角面(1个四边形可拆分为2个三角形),每个顶点包含X、Y、Z这三个坐标。如果给所有顶点从0开始进行顺序编号,那么各个三角面就能根据三个顶点索引随着确定,相应地纹理赋值也能随之确定。

3、代码实现及效果展示

        接下来将具体调用Cesium的API按照上述两种思路分别进行实现,具体代码如下:

3.1 思路一 3.1.1 代码实现 Cesium旋转金字塔-jing_zhong * { margin: 0; padding: 0; } html, body, #viewer-container { width: 100%; height: 100%; overflow: hidden; } .cesium-widget-credits{ display:none!important; visibility:hide!important; } .cesium-viewer-toolbar{ display:none!important; visibility:hide!important; } .form-container { position: absolute; left: 10px; top: 90px; padding: 10px 15px; border-radius: 4px; border: 1px solid rgba(128, 128, 128, 0.5); color: #ffffff; background: rgba(0, 0, 0, 0.4); box-shadow: 0 3px 14px rgb(128 128 128 / 50%); max-width: 380px; } button { background: transparent; border: 1px solid #00d0ffb8; color: white; padding: 7px 9px; border-radius: 2px; margin: 3px; cursor: pointer } .tip-item { margin: 2px 0px; padding: 5px 1px; } 添加旋转金字塔 移除旋转金字塔 var viewer = null; var modelEntity = null; // 开关 function setvisible(value) { switch (value) { case 'add': addPyramidModel(); break; case 'remove': removeRotateCircle(); break; } } // 添加旋转金字塔 function addPyramidModel() { let hpr = new Cesium.HeadingPitchRoll( Cesium.Math.toRadians(0), Cesium.Math.toRadians(180),//0朝下 180朝上 Cesium.Math.toRadians(0) ) let r = Cesium.Math.toRadians(2); let lon = 121.50320483066757, lat = 31.23641093043576, height = 382.83983348350085,isUp = true; // let position = Cesium.Cartesian3.fromDegrees(121.50320483066757, 31.23641093043576, 382.83983348350085); modelEntity = this.viewer.entities.add({ position: new Cesium.CallbackProperty(e => { if(height > 400) { height = 400; isUp = false; } else if(height height += 1.0; } else { height -= 1.0; } return Cesium.Cartesian3.fromDegrees(lon,lat,height); }, false), //旋转起来 orientation: new Cesium.CallbackProperty(e => { window.console.log(e); hpr.heading += r; let position = Cesium.Cartesian3.fromDegrees(lon,lat, height); return Cesium.Transforms.headingPitchRollQuaternion(position, hpr); }, false), model: { uri: "pyramid.glb", scale: 40, color: Cesium.Color.YELLOW.withAlpha(0.8), colorBlendMode: Cesium.ColorBlendMode.MIX, } }); viewer.flyTo(modelEntity); } // 移除旋转金字塔 function removeRotateCircle() { if(modelEntity != null) { viewer.entities.remove(modelEntity); modelEntity.destroy(); modelEntity = null; } } // init function initPage() { // 切换自己的token Cesium.Ion.defaultAccessToken = 'your_token'; // 初始化 viewer = new Cesium.Viewer("viewer-container", { infoBox: false, shouldAnimate: true, vrButton: true, geocoder: false, homeButton: false, sceneModePicker: false, baseLayerPicker: false, navigationHelpButton: false, animation: false,//动画控制不显示 timeline: false,//时间线不显示 fullscreenButton: false,//全屏按钮不显示 terrainProvider: Cesium.createWorldTerrain({ requestWaterMask: true, // 水特效 requestVertexNormals: true // 地形光 }), }); viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ url: './dayanta/tileset.json', show: true, backFaceCulling: true, }) ).readyPromise.then((tileset) => { //拉伸模型高度代码 let heightOffset = -26; var boundingSphere = tileset.boundingSphere; var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center); var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0); var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset); var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3()); tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); //viewer.zoomTo(tileset) viewer.flyTo(tileset); }) } // window.onload = function () { initPage(); } 3.1.2 展示结果 3.2 思路二 3.2.1 代码实现 .cesium-widget-credits{ display:none!important; visibility:hide!important; } .cesium-viewer-toolbar{ display:none!important; visibility:hide!important; } .middleTop { width: 300px; height: 30px; position: fixed; top: 10px; left: 20px; text-align: center; background: red; opacity: 0.6; } button { background: gray; border: 1px solid #00d0ffb8; color: white; padding: 7px 9px; border-radius: 2px; margin: 3px; cursor: pointer } .tip-item { margin: 2px 0px; padding: 5px 1px; } 添加倒立四棱锥 移除一个倒立四棱锥 Cesium.Ion.defaultAccessToken = "your_token"; const viewer = new Cesium.Viewer('cesiumContainer', { // Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID. baseLayerPicker: false, //shadows: true, shouldAnimate: true, infoBox: false, animation: false,//动画控制不显示 timeline: false,//时间线不显示 fullscreenButton: false, //全屏按钮不显示 terrainProvider: Cesium.createWorldTerrain({ requestWaterMask: true, // 水特效 requestVertexNormals: true // 地形光 }), selectionIndicator: false, // By jing_zhong 2022.9.21 移除Cesium自带的绿色聚焦瞄准框 //imageryProvider: new Cesium.ArcGisMapServerImageryProvider({ // url: 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer', //}), }); viewer._cesiumWidget._creditContainer.style.display = "none";//去除版权信息 //viewer.scene.globe.depthTestAgainstTerrain = true; let silhouette = null,skylineAnayStages = null;//天际线分析工具 //打开天际线分析 function openSkylineAnay() { if(skylineAnayStages){ silhouette.enabled=true; return; } skylineAnayStages = viewer.scene.postProcessStages; let edgeDetection = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); let postProccessStage = new Cesium.PostProcessStage({ //此后处理阶段的唯一名称,供组合中其他阶段参考,如果未提供名称,将自动生成GUID // name:name, //unform着色器对象 textureScale fragmentShader: 'uniform sampler2D colorTexture;' + 'uniform sampler2D depthTexture;' + 'varying vec2 v_textureCoordinates;' + 'void main(void)' + '{' + 'float depth = czm_readDepth(depthTexture, v_textureCoordinates);' + 'vec4 color = texture2D(colorTexture, v_textureCoordinates);' + 'if(depth


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有