CesiumJS整合ThreeJS插件封装

最近做项目有一个三维需求使用CesiumJS比较难以实现,发现THREEJS中效果比较合适,于是准备将THREEJS整合到CesiumJS中

为实现效果所需我们找到官方Integrating Cesium with Three.js博客,于是根据该博客提供的思路去实现整合

文章目录

    • 一、创建ThreeJS类
    • 二、插件threeJs 优化
      • 1、创建ThressScene工具
        • 1.1、同步camera
        • 1.2、同步场景中的物体
        • 1.3、同步render
      • 2、插件使用
        • 2.1 引入插件初始化map
        • 2.1 初始化Meshes
        • 2.2 初始化threeScene
        • 2.3 效果预览

一、创建ThreeJS类

为了开发时更好的扩展性把他写到了一个ThreeJS 类里面,功能直接调用即可

function ThreeJs(viewer, cesiumGlobal, defaultStatic, threeConf) {if (viewer && threeConf) {const { threeGlobal, containerId, threeContainerId } = threeConf;Cesium = cesiumGlobal;THREE = threeGlobal;this._viewer = viewer;this._containerId = containerId;this._threeContainerId = threeContainerId;this._initContainer();this._initThree();}
}
//部分省略......

项目中使用

import { ThreeJs } from 'cesium_dev_kit'// 初始化mapinitMap (){const ThreeJsObj = new ThreeJs({cesiumGlobal: Cesium,threeGlobal: THREE,containerId: 'cesiumContainer',threeContainerId: 'threeContainer',
//部分省略......})this.c_viewer = ThreeJsObj.viewer;this.threeJs = ThreeJsObj.threeJs;this.initThree(this.threeJs);},// 初始化ThreeJsinitThree (ThreeJs) {const threeDObject = this.create3DOject(ThreeJs, this.c_viewer);ThreeJs.addThreeObjects(threeDObject)this.c_viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)//解除视角锁定},// 创建三维模型create3DOject (threeObj, viewer) {let three = threeObj._three;let _3Dobjects = [], _3DOB;let entity = {name: 'Polygon',polygon: {hierarchy: Cesium.Cartesian3.fromDegreesArray([minWGS84[0], minWGS84[1],maxWGS84[0], minWGS84[1],maxWGS84[0], maxWGS84[1],minWGS84[0], maxWGS84[1]]),material: Cesium.Color.RED.withAlpha(0.1)}}let Polypon = viewer.entities.add(entity);let doubleSideMaterial = new THREE.MeshNormalMaterial({side: THREE.DoubleSide});
//部分省略......return _3Dobjects;}   

根据官网的思量整合后最终实现效果如下
实现效果
效果是实现了,但是这个封装耦合性相当高,多个功能都需要使用这个插件时特别蹩脚,于是开始了下一次造…

二、插件threeJs 优化

理解官方案例的思路整合关键主要有三个方面,第一个是同步Camera,第二个是同步Scene中的物体位置,第三个是需要同步CesiumJS和THREEJS 的render重绘程序

1、创建ThressScene工具

为了扩展与管理我们抽离一个Scene 的工具js

class Scene extends THREE.Scene {}

在这个js 里面去实现插件操作的优化

1.1、同步camera

创建一个updateCameraMatrix来同步项目位置,核心代码如下

  updateCameraMatrix() {//同步相机this.camera.fov = Cesium.Math.toDegrees(this.cesiumViewer.camera.frustum.fovy) // ThreeJS FOV is verticalthis.camera.updateProjectionMatrix()this.camera.matrixAutoUpdate = falseconst cvm = this.cesiumViewer.camera.viewMatrixconst civm = this.cesiumViewer.camera.inverseViewMatrixthis.camera.lookAt(this.cameraCenter)
//部分省略......const width = this.cesiumViewer.scene.canvas.clientWidthconst height = this.cesiumViewer.scene.canvas.clientHeightthis.camera.aspect = width / heightthis.camera.updateProjectionMatrix()this.renderer.setSize(width, height)return this}
1.2、同步场景中的物体

创建一个updateGroupMatrixWorld来进行物体位置同步,核心代码如下

	 // 重写add 方法add(object) {if (arguments.length > 1) {for (let i = 0; i < arguments.length; i++) {this.childrenGroup.add(arguments[i])}return this}//部分省略......return this}updateGroupMatrixWorld() {// 得到面向模型的前向方向const center = this.cartesian3ToVector(Cesium.Cartesian3.fromDegrees(this.lngLat[0], this.lngLat[1], 0))// 使用从左下到左上的方向作为上向量const topLeft = this.cartesian3ToVector(Cesium.Cartesian3.fromDegrees(this.lngLat[0], this.lngLat[1], 2))const latDir = new THREE.Vector3().subVectors(center, topLeft).normalize()// 配置实体的位置和方向// this.syncGroup.position.copy(center)this.syncGroup.lookAt(latDir)this.syncGroup.up.copy(latDir)this.syncGroup.updateMatrix()this.cameraOffset.copy(center)this.sphere.position.set(0 - center.x, 0 - center.y, 0 - center.z)this.syncGroup.up.set(0, 0, -1)this.up.set(0, 0, -1)return this}
1.3、同步render
    renderCesium() {this.cesiumViewer.render()return this}renderThree() {this.renderer.render(this, this.camera)return this}loop(callback) {const _loop = function () {let time = requestAnimationFrame(_loop)callback && callback(time)}_loop()}

2、插件使用

插件改完了心里还是有点鸡冻,马上在项目中引入开始测试

2.1 引入插件初始化map
import { initCesium } from 'cesium_dev_kit'// 初始化mapinitMap (){const { viewer, threeJs, base, graphics, material } = new initCesium({cesiumGlobal: Cesium,threeGlobal: THREE,containerId: 'cesiumContainer',threeContainerId: 'threeContainer',//部分省略......})this.c_viewer = viewer;this.threeJs = threeJs;this.base = base;this.graphics = graphics;this.material = materialthis.initThree(this.threeJs);// this.getClickPosition()this.createAEllipsoid();this.createAFanShape();},
2.1 初始化Meshes

这里我们就使用官方的extrude案例

    initMeshes (scene) {// 环形 extrudeconst closedSpline = new THREE.CatmullRomCurve3([new THREE.Vector3(-60, 30, 60), // 左下new THREE.Vector3(-60, 100, 60), // 左中new THREE.Vector3(-60, 220, 60), // 左上new THREE.Vector3(60, 80, -60), // 右中new THREE.Vector3(60, 30, -60), // 右下]);// 2、extrude settingsclosedSpline.curveType = "catmullrom";closedSpline.closed = true;const extrudeSettings = {steps: 100,bevelEnabled: false,extrudePath: closedSpline,};// 3、construct shapeconst r = 20; // 截面半径const pts1 = [];const count = 3; // 截面的棱边数量for (let index = 0; index < count; index++) {// index/count 几分之几,2π为周长const a = (index / count) * Math.PI * 2;pts1.push(new THREE.Vector2(r * Math.cos(a), r * Math.sin(a)));}const shape1 = new THREE.Shape(pts1);// create geometryconst geometry1 = new THREE.ExtrudeGeometry(shape1, extrudeSettings);// create materialconst material1 = new THREE.MeshLambertMaterial({color: 0xb00000,});// assembly meshesconst mesh1 = new THREE.Mesh(geometry1, material1);// add mesh to scenescene.add(mesh1);//部分省略......},
2.2 初始化threeScene
    initThree (ThreeJs) {const { scene, camera } = ThreeJs.initThree({ center, axesHelper: true, threeHabit: false });this.initLight(scene, camera)this.initMeshes(scene);this.flyto(scene);ThreeJs.loop(function () {scene.update();})},
2.3 效果预览

光线投射
光线投射 图形挤压图形挤压烟花效果
烟花效果

奔跑的士兵
奔跑的士兵

嗯嗯测试了几个功能看了基本上问题不大了,ok先告一段落后期继续优化…

感谢您的阅读,最后附上插件下载与源码地址

  • 插件下载安装
npm install cesium_dev_kit
  • 案例源码地址
    https://github.com/dengxiaoning/cesium_dev_kit

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/856909.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java Array示例说明

Java Array示例说明 数组是相同类型的元素的集合。例如&#xff0c;int数组包含整数元素&#xff0c;String数组包含String元素。Array的元素存储在内存中的相邻位置。Java中的数组基于零基索引系统&#xff0c;这意味着第一个元素位于索引0处。 数组如下所示&#xff1a; i…

LabVIEW与数字孪生

LabVIEW与数字孪生技术在工业自动化、智慧城市、医疗设备和航空航天等领域应用广泛&#xff0c;具备实时数据监控、虚拟仿真和优化决策等特点。开发过程中需注意数据准确性、系统集成和网络安全问题&#xff0c;以确保数字孪生模型的可靠性和有效性。 经典应用&#xff1a;LabV…

ru俄罗斯域名如何申请SSL证书?

我们日常看到的都是com这种国际域名比较普遍&#xff0c;尤其是主流网站&#xff0c;主要原因考虑的其通用性&#xff0c;那么对于地方性的域名大家很少看到&#xff0c;比如俄罗斯国家域名.ru大家还是有些陌生的&#xff0c;但要说中国.CN域名那你就很熟悉了。 有用户在申请过…

来聊聊redis文件事件驱动的设计

写在文章开头 近期团队安排变得比较紧急&#xff0c;关于redis系列的更新相对放缓一些&#xff0c;而我们今天要讨论的就是redis中关于事件模型的设计&#xff0c;我们都知道redis通过单线程实现高效的网络IO处理&#xff0c;本文会从源码的角度来讲解一下redis中文件事件驱动…

学会python——获取文件信息(python实例八)

目录 1、认识Python 2、环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3、获取文件信息 3.1 代码构思 3.2 代码示例 3.3 运行结果 4、总结 1、认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的…

【星环社区版TDH2024年度大事件】全新版本?全新组件?性能提升10倍?

TDH社区版家族迎来新成员 不知不觉社区版已经陪伴大家将近两年的时间了&#xff0c;在这两年里收获到了很多认可&#xff0c;同时也收获到了一些建议与意见&#xff0c;比如资源成本的问题。在去年我们发布了TDH社区开发版&#xff0c;仅需单台服务器即可一键安装部署Inceptor…

创新实训2024.05.01日志:document-loaders

在建立易学知识库的过程中&#xff0c;仅仅有向量数据库以及词嵌入模型、分词器是不够的&#xff0c;因为我们有大量的非结构化文本&#xff08;如doc,pdf&#xff09;或者是图片需要上传&#xff08;例如pdf里面有图片&#xff09;&#xff0c;此时词嵌入无法直接向向量数据库…

Uniapp获取具体地理位置

使用uniapp自带uni.getLocation获取当前定位经纬度 再调用高德逆地理编码API&#xff0c;查到具体位置信息 https://restapi.amap.com/v3/geocode/regeo?location${longitude},${latitude}&key${key}&extensionsall 但是个人申请的key&#xff0c;有配额限制 最多每…

LabVIEW程序闪退问题

LabVIEW程序出现闪退问题可能源于多个方面&#xff0c;包括软件兼容性、内存管理、代码质量、硬件兼容性和环境因素。本文将从这些角度进行详细分析&#xff0c;探讨可能的原因和解决方案&#xff0c;并提供预防措施&#xff0c;以帮助用户避免和解决LabVIEW程序闪退的问题。 1…

qmt量化交易策略小白学习笔记第44期【qmt编程之期货行情数据】

qmt编程之获取期货行情数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 获取行情数据 提示 使用该接口时&#xff0c;需要先订阅实时行情(subscribe_quote)或下载过历史行情(download_hi…

k8s中 docker和containerd 镜像相互导入导出

containerd镜像导出并导入docker 1 查看containerd 本地镜像列表 crictl images 2 containerd 导出本地镜像到当前目录下&#xff08;注意&#xff1a; 导出导入需要指定镜像平台类型 --platform&#xff09; ctr -n k8s.io images export nacos-server-24-06-30-13-02-…

openGauss开发者大会、华为云HDC大会举行; PostgreSQL中国技术大会7月杭州开启

重要更新 1. openGauss Developer Day本周五于北京举行&#xff0c;大会聚集了相关行业专家、用户、伙伴和开发者&#xff0c;分享给予openGauss的联合创新成果和实践案例。([2] ) &#xff1b;华为云 HDC 2024本周五于东莞松山湖举行&#xff0c;主题演讲主要覆盖鸿蒙、AI ([3…

Vue3 + Ant-Design 中 a-date-picke 实现选择切换年份 没有鼠标光标,输入框内自带‘年’

效果图&#xff1a; 效果图 <a-date-picker ref"datePicker" v-model:value"year" picker"year" value-format"YYYY年" format"YYYY年" :bordered"false" :allowClear"false" inputReadOnly change&…

【前端项目笔记】3 用户管理

用户管理相关功能实现 涉及表单、对话框、Ajax数据请求 基本页面 用户列表开发 在router.js中导入Users.vue 解决用户列表小问题 选中&#xff08;激活&#xff09;子菜单后刷新不显示高亮 给二级菜单绑定单击事件&#xff0c;点击链接时把对应的地址保存到sessionSto…

vlan技术--交换机实现局域网分割(Access模式trunk模式)

自作笔记... 目录 vlan技术--交换机连接pc实现局域网分割(Access模式) PC SW1 结果 vlan技术--交换机连接pc实现局域网分割(trunk模式) vlan技术--交换机连接pc实现局域网分割(Access模式) 交换机先创建vlan. 交换机分别进入接口 (配置好连接模式, 连接的vlan) PC SW1 …

Set集合系列——Set、HashSet、LinkedHashset、TreeSet

Set系列的公共特点&#xff1a;无重复、无索引&#xff0c;不可用普通for循环&#xff0c;API和Collection重复 HashSet&#xff1a;采取哈希表存取数据 哈希表组成&#xff1f; JDk8之前&#xff1a;数组链表&#xff0c; JDK8以后&#xff1a;数组链表红黑树 哈希值&#…

简单高效的盈利策略,昂首资本推荐价格行为交易

有没有这样一种简单高效的盈利策略&#xff0c;不仅易于新手掌握&#xff0c;也是专业人士的常用利器?当然有了&#xff0c;就是Anzo Capital昂首资本今天推荐的价格行为交易。价格行为交易以其透明清晰的市场视角受到交易员的青睐&#xff0c;它如实反映了市场的真实动态&…

Ubuntu下安装docker

一、docker安装说明 解决官方源无法下载的问题 二、使用步骤 1.更新软件包索引 sudo apt-get update2.安装必要的软件包&#xff0c;以允许apt通过HTTPS使用仓库 sudo apt-get install apt-transport-https ca-certificates curl software-properties-common3.添加Docker的…

功能测试 之 单模块测试----购物车模块

1.需求分析 &#xff08;1&#xff09;购物车显示 1.若未登录&#xff0c;提示登录&#xff0c;提示文案“购物车内暂时没有商品&#xff0c;登录后将显示您之前加入的商品” 2.若已登录&#xff0c;购物车没有商品&#xff0c;提示去购物。 未登录状态 已登录状态 3.购物车有…

CVPR2024|UniPAD:一种自动驾驶的统一的预训练范式

本文章仅用于学术分享 论文标题丨 UniPAD: A Universal Pre-training Paradigm for Autonomous Driving 论文地址丨 https://arxiv.org/abs/2310.08370 代码地址 | https://github.com/Nightmare-n/UniPAD 关注「AI前沿速递」公众号&#xff0c;获取更多前沿资讯 01总览 这…