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'

// 初始化map
 initMap (){
     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);
  },
  // 初始化ThreeJs
 initThree (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 vertical
      this.camera.updateProjectionMatrix()

      this.camera.matrixAutoUpdate = false
      const cvm = this.cesiumViewer.camera.viewMatrix
      const civm = this.cesiumViewer.camera.inverseViewMatrix
      this.camera.lookAt(this.cameraCenter)
//部分省略......
      const width = this.cesiumViewer.scene.canvas.clientWidth
      const height = this.cesiumViewer.scene.canvas.clientHeight
      this.camera.aspect = width / height
      this.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'

// 初始化map
 initMap (){
      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 = material
      this.initThree(this.threeJs);
      // this.getClickPosition()
      this.createAEllipsoid();
      this.createAFanShape();
  },
2.1 初始化Meshes

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

    initMeshes (scene) {
      // 环形 extrude
      const 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 settings
      closedSpline.curveType = "catmullrom";
      closedSpline.closed = true;
      const extrudeSettings = {
        steps: 100,
        bevelEnabled: false,
        extrudePath: closedSpline,
      };
      // 3、construct shape
      const 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 geometry
      const geometry1 = new THREE.ExtrudeGeometry(shape1, extrudeSettings);
      // create material
      const material1 = new THREE.MeshLambertMaterial({
        color: 0xb00000,
      });
      // assembly meshes
      const mesh1 = new THREE.Mesh(geometry1, material1);
      // add mesh to scene
      scene.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.mfbz.cn/a/727604.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL快速安装(mysql8.0.30区别之前yum安装)

目录 一.初始化环境并解压 二.创建程序用户管理 三.修改mysql目录和配置文件的权限 四.修改配置文件 五.设置环境变量&#xff0c;申明/宣告mysql命令便于系统识别 六.初始化数据库 七.设置系统识别&#xff0c;进行操作 八.初始化数据库密码 九.用户并设置密码 十.赋…

FinalReference 如何使 GC 过程变得拖拖拉拉

本文基于 OpenJDK17 进行讨论&#xff0c;垃圾回收器为 ZGC。 提示&#xff1a; 为了方便大家索引&#xff0c;特将在上篇文章 《以 ZGC 为例&#xff0c;谈一谈 JVM 是如何实现 Reference 语义的》 中讨论的众多主题独立出来。 FinalReference 对于我们来说是一种比较陌生的 R…

Python - 各种计算器合集【附源码】

计算器合集 一&#xff1a;极简版计算器二&#xff1a;简易版计算器三&#xff1a;不简易的计算器四&#xff1a;还可以计算器 一&#xff1a;极简版计算器 运行效果&#xff1a; import tkinter as tk import tkinter.messagebox win tk.Tk() win.title("计算器")…

如何高效应用与精准选择温补晶振

温补晶振(TCXO)是一种重要的时序元件&#xff0c;因其高精度和高稳定性在通信、导航、测控等多个领域中扮演着关键角色。晶发电子接下来将为您详细阐述温补晶振的选用和使用方法&#xff0c;助您更好地理解和运用这一核心元件。 一、温补晶振的工作原理 温补晶振能够实现在广…

绿茶集团重启IPO:流量渐退、业绩波动,还能讲出好故事吗?

近日&#xff0c;绿茶集团有限公司(下称“绿茶集团”)向港交所递交上市申请&#xff0c;花旗、招银国际为其联席保荐人。 回望绿茶集团的上市之路&#xff0c;可谓有诸多坎坷。该公司于2021年3月首度向港交所发起冲击&#xff0c;但却将中文版招股书中的“流动负债总额”错写成…

1.4自然语言的分布式表示-word2vec实操

文章目录 0写在前面1数据准备2CBOW模型结构的实现3交叉熵损失函数的前向计算3.1关于cross_entropy_error的计算3.2关于softmax 0写在前面 代码都位于&#xff1a;nlp&#xff1b;其他相关内容详见专栏&#xff1a;深度学习自然语言处理基础_骑着蜗牛环游深度学习世界的博客-CS…

深度学习模型训练中 学习率参数 设置大小问题及设置合适值

&#x1f4aa; 专业从事且热爱图像处理&#xff0c;图像处理专栏更新如下&#x1f447;&#xff1a; &#x1f4dd;《图像去噪》 &#x1f4dd;《超分辨率重建》 &#x1f4dd;《语义分割》 &#x1f4dd;《风格迁移》 &#x1f4dd;《目标检测》 &#x1f4dd;《暗光增强》 &a…

Mybatis Plus 详解 IService、BaseMapper、自动填充、分页查询功能

结构直接看目录 前言 MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 愿景 我们的愿景是成为 MyBatis 最好的搭档&#xff0c;就像 魂斗罗 中的 1P、2P&#xff0c;基友搭配&#xff0c;效…

Linux系统ubuntu20.04 无人机PX4 开发环境搭建(失败率很低)

Linux系统ubuntu20.04 无人机PX4 开发环境搭建 PX4固件下载开发环境搭建MAVROS安装安装地面站QGC PX4固件下载 PX4的源码处于GitHub&#xff0c;因为众所周知的原因git clone经常失败&#xff0c;此处从Gitee获取PX4源码和依赖模块。 git clone https://gitee.com/voima/PX4-…

使用 Python 中的美丽汤进行网络数据解析的完整指南

Beautiful Soup 是一个广泛使用的 Python 库&#xff0c;在数据提取方面发挥着重要作用。它为解析 HTML 和 XML 文档提供了强大的工具&#xff0c;使从网页中轻松提取有价值的数据成为可能。该库简化了处理互联网上非结构化内容的复杂过程&#xff0c;使您可以将原始网页数据转…

【nginx】 nginx核心功能

【nginx】 nginx核心功能 1.nginx核心功能 1. 反向代理 2. 负载均衡 3. 动静分离 4. nginx的高可用2. 反向代理 正向代理: 该服务器代理的是客户端&#xff0c;对于服务器来说&#xff0c;不知道真实客户端的ip。比如: 翻墙软件。 访问国外的服务器---使用了翻墙软件----对…

2024年【R1快开门式压力容器操作】考试及R1快开门式压力容器操作考试内容

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年R1快开门式压力容器操作考试为正在备考R1快开门式压力容器操作操作证的学员准备的理论考试专题&#xff0c;每个月更新的R1快开门式压力容器操作考试内容祝您顺利通过R1快开门式压力容器操作考试。 1、【多选题…

开源技术:在线教育系统源码及教育培训APP开发指南

本篇文章&#xff0c;小编将探讨如何利用开源技术开发在线教育系统及教育培训APP&#xff0c;旨在为有志于此的开发者提供全面的指导和实践建议。 一、在线教育系统的基本构架 1.1架构设计 包括前端、后端和数据库三个主要部分。 1.2前端技术 在前端开发中&#xff0c;HTML…

【我是产品经理_注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

论文学习 Learning Robust Representations via Multi-View Information Bottleneck

Code available at https://github.com/mfederici/Multi-View-Information-Bottleneck 摘要&#xff1a;信息瓶颈原理为表示学习提供了一种信息论方法&#xff0c;通过训练编码器保留与预测标签相关的所有信息&#xff0c;同时最小化表示中其他多余信息的数量。然而&#xff0…

HCIA-速查-ENSP模拟器2步清空配置

需求&#xff1a;清空模拟器配置 清空当前图中配置 步骤1&#xff1a;reset saved-configuration 后输入y确认 步骤2&#xff1a;reboot后输入n否认再输入y确认 验证已经清空配置

QT利用QGraphicsDropShadowEffect效果及自定义按钮来实现一个炫酷键盘

1、效果 2、核心代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent<

阿里云 邮件系统DNS域名解析 搭配 postfix+dovecot 邮件服务器

1 创建邮箱域名A记录(一般邮箱客户端&#xff0c;增加pop,imap,stmp 3条记录) 登录阿里云控制台--云解析DNS 2 MX记录 3 SPF记录

chatgpt: linux 下用纯c 编写ui

在Linux下用纯C语言编写用户界面&#xff08;UI&#xff09;&#xff0c;通常会使用GTK或Xlib。GTK是一个更高级的库&#xff0c;提供了丰富的控件和功能&#xff0c;而Xlib则是一个更底层的库&#xff0c;提供了直接操作X Window系统的功能。 下面是一个使用GTK在Linux上创建…

R语言dplyr统计指定列里面种类个数和比例

输入数据框&#xff1a;dfuorf&#xff0c;Type列有uORF和overlpaORF两种类型 dfuorf1 <- dfuorf %>%group_by(Type) %>% summarise(Countn()) %>% mutate(percentCount/sum(Count)) %>% mutate(percent1 (paste0(round((Count/sum(Count)), 2)*100,"%&…