CesiumJS整合ThreeJS插件封装

2024-06-21 09:04

本文主要是介绍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

这篇关于CesiumJS整合ThreeJS插件封装的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1080784

相关文章

SpringBoot整合OpenFeign的完整指南

《SpringBoot整合OpenFeign的完整指南》OpenFeign是由Netflix开发的一个声明式Web服务客户端,它使得编写HTTP客户端变得更加简单,本文为大家介绍了SpringBoot... 目录什么是OpenFeign环境准备创建 Spring Boot 项目添加依赖启用 OpenFeig

SpringBoot整合mybatisPlus实现批量插入并获取ID详解

《SpringBoot整合mybatisPlus实现批量插入并获取ID详解》这篇文章主要为大家详细介绍了SpringBoot如何整合mybatisPlus实现批量插入并获取ID,文中的示例代码讲解详细... 目录【1】saveBATch(一万条数据总耗时:2478ms)【2】集合方式foreach(一万条数

Spring Boot 整合 SSE的高级实践(Server-Sent Events)

《SpringBoot整合SSE的高级实践(Server-SentEvents)》SSE(Server-SentEvents)是一种基于HTTP协议的单向通信机制,允许服务器向浏览器持续发送实... 目录1、简述2、Spring Boot 中的SSE实现2.1 添加依赖2.2 实现后端接口2.3 配置超时时

springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法

《springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法》:本文主要介绍springboot整合阿里云百炼DeepSeek实现sse流式打印,本文给大家介绍的非常详细,对大... 目录1.开通阿里云百炼,获取到key2.新建SpringBoot项目3.工具类4.启动类5.测试类6.测

鸿蒙中Axios数据请求的封装和配置方法

《鸿蒙中Axios数据请求的封装和配置方法》:本文主要介绍鸿蒙中Axios数据请求的封装和配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.配置权限 应用级权限和系统级权限2.配置网络请求的代码3.下载在Entry中 下载AxIOS4.封装Htt

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties

一文详解如何从零构建Spring Boot Starter并实现整合

《一文详解如何从零构建SpringBootStarter并实现整合》SpringBoot是一个开源的Java基础框架,用于创建独立、生产级的基于Spring框架的应用程序,:本文主要介绍如何从... 目录一、Spring Boot Starter的核心价值二、Starter项目创建全流程2.1 项目初始化(

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma

SpringBoot整合jasypt实现重要数据加密

《SpringBoot整合jasypt实现重要数据加密》Jasypt是一个专注于简化Java加密操作的开源工具,:本文主要介绍详细介绍了如何使用jasypt实现重要数据加密,感兴趣的小伙伴可... 目录jasypt简介 jasypt的优点SpringBoot使用jasypt创建mapper接口配置文件加密

SpringBoot整合MybatisPlus的基本应用指南

《SpringBoot整合MybatisPlus的基本应用指南》MyBatis-Plus,简称MP,是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,下面小编就来和大家介绍一下... 目录一、MyBATisPlus简介二、SpringBoot整合MybatisPlus1、创建数据库和