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中封装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、创建数据库和

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

Spring Boot整合消息队列RabbitMQ的实现示例

《SpringBoot整合消息队列RabbitMQ的实现示例》本文主要介绍了SpringBoot整合消息队列RabbitMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装Spring

Spring Boot 3 整合 Spring Cloud Gateway实践过程

《SpringBoot3整合SpringCloudGateway实践过程》本文介绍了如何使用SpringCloudAlibaba2023.0.0.0版本构建一个微服务网关,包括统一路由、限... 目录引子为什么需要微服务网关实践1.统一路由2.限流防刷3.登录鉴权小结引子当前微服务架构已成为中大型系统的标

SpringBoot整合easy-es的详细过程

《SpringBoot整合easy-es的详细过程》本文介绍了EasyES,一个基于Elasticsearch的ORM框架,旨在简化开发流程并提高效率,EasyES支持SpringBoot框架,并提供... 目录一、easy-es简介二、实现基于Spring Boot框架的应用程序代码1.添加相关依赖2.添