SuperMap iClient3D for WebGL教程(模型篇)-3DMax插件使用

本文详细介绍如何使用3DMax插件将建筑模型数据导出至SuperMap平台,包括插件下载、安装步骤及模型导出的具体设置,适用于GIS数据生产和管理的专业人士。

作者:为梦齐舞

本文同步更新于简书文章https://www.jianshu.com/p/5223806d7c51
3DMax是目前最流行的三维软件,占据了主流地位,广泛应用于建筑模型和室内精细化建模,应用于三维GIS数据的生产,本文将以3DMax为例,介绍如何将建模成果应用于SuperMap。

一、插件下载

目前最新支持版本为3DMax 2014

插件下载地址:http://support.supermap.com.cn/DownloadCenter/DownloadPage.aspx?tt=ProductAAS&id=115

百度云盘:https://pan.baidu.com/s/1i5Fzntr 百度云盘密码:dee8

二、插件安装

1、解压插件包,并设置为系统环境变量Path路径的最前端。(PS:一定确保其在path路径的最前端。)

2、将插件包中的SuMax2014Plugin.gup文件复制到Autodesk 3ds Max 2014安装目录下的stdplugin目录下(如图1),3ds Max插件即安装成功
图1
3、将插件包中的Resource文件夹拷贝至Autodesk 3ds Max 2014安装目录下(如不需要使用“导入地形”功能,此步骤可忽略)

到此插件安装成功,重启Autodesk 3ds Max 2014软件,软件菜单栏中添加了“超图Max插件”,3ds Max插件的具体位置如图2所示。
图2
三、模型导出

1、在3DMax软件中打开建模成果数据。

2、单击菜单列表中的“超图Max插件”按钮,在弹出的下拉菜单中选择“BIM生成数据集”,弹出“BIM生成数据集”面板,如图3所示。

在这里插入图片描述

图3

3、导出模式介绍

插件提供了两种导出模式,可根据模型情况和用户需求合理选择。

a、插入点:可以直接设置球面坐标或平面坐标,插入点即是3DMax中的原点,所以建议模型坐标归为原点后导出,选择球面坐标导出的模型数据坐标系为WGS1984(EPSG:4326),选择平面坐标则导出的模型数据坐标系为平面无投影。

b、自定义投影:自行选择投影方式导出模型,此导出模式要求模型在3DMax中位置为真实世界坐标,自定义投影设置需要的XML文件,可以根据建模依据的坐标系在SuperMap iDesktop中自定义或从已有坐标系中,导出相应的XML文件,导出后的模型坐标系为自定义的坐标系。

4、选择纹理路径

纹理路径即为建模时使用到的纹理资源路径,此处建议将纹理资源全部放置到一个文件夹中,不然会导致部分纹理丢失。

5、数据源设置

此处只支持SuperMap UDB格式的数据源,可以在SuperMap iDesktop中新建一个UDB数据源,因为 UDB数据源为独占型,在进行模型导出时,请确保UDB处于关闭状态。数据集的设置此处可以选择数据源中已存在的数据集或新建一个数据集。

6、以上参数全部设置完成后,点击确定按钮即可导出模型数据,导出完成后,使用SuperMap iDesktop打开输入的UDB数据源即可查看模型数据。

<template> <div class="drone-monitor"> <!-- 视角控制控件 --> <div class="camera-control"> <label>相机高度: {{ cameraHeight }}米</label> <input type="range" min="50" max="1000" v-model="cameraHeight" @input="updateCameraHeight"> </div> <!-- Cesium容器 --> <div id="cesium-container"></div> </div> </template> <script> import * as Cesium from 'cesium' import * as Supermap from '@supermap/iclient-3d-webgl' import { ref, onMounted, onBeforeUnmount } from 'vue' export default { setup() { const viewer = ref(null) const droneEntity = ref(null) const socket = ref(null) const cameraHeight = ref(150) // 默认相机高度 const droneId = 'Drone-001' const modelUrl = "/models/drone.glb" // 无人机3D模型地址 // 初始化地图 const initViewer = () => { // 创建Cesium视图 viewer.value = new Cesium.Viewer('cesium-container', { // SuperMap配置(如使用SuperMap,取消注释以下配置) // ...Supermap.WebMap terrainProvider: Cesium.createWorldTerrain(), animation: false, timeline: false, vrButton: false, baseLayerPicker: false, geocoder: false }) // 添加OSM建筑层 viewer.value.scene.primitives.add( Cesium.createOsmBuildings() ) // 设置初始视角定位 viewer.value.camera.setView({ destination: Cesium.Cartesian3.fromDegrees( 116.39, 39.9, 10000 ) }) } // 创建无人机模型 const createDroneModel = (initPosition) => { droneEntity.value = viewer.value.entities.add({ id: droneId, name: '无人机', position: initPosition, model: { uri: modelUrl, minimumPixelSize: 64, maximumScale: 20000, silhouette: true, silhouetteColor: Cesium.Color.RED, runAnimations: true }, orientation: new Cesium.VelocityOrientationProperty(initPosition) }) // 创建后自动拉高相机视角 liftCameraPosition(initPosition) } // 拉高相机视角 const liftCameraPosition = (position) => { const cartographic = Cesium.Cartographic.fromCartesian(position) const cameraPosition = Cesium.Cartesian3.fromRadians( cartographic.longitude, cartographic.latitude, cartographic.height + cameraHeight.value ) viewer.value.camera.flyTo({ destination: cameraPosition, orientation: { heading: 0, pitch: -Math.PI / 3, // 60度俯角 roll: 0 }, duration: 2.5 }) } // 更新相机高度 const updateCameraHeight = () => { if (droneEntity.value) { const position = droneEntity.value.position.getValue(Cesium.JulianDate.now()) liftCameraPosition(position) } } // 初始化WebSocket连接 const initWebSocket = () => { socket.value = new WebSocket('wss://your-drone-server.com') const cartesian = Cesium.Cartesian3.ZERO socket.value.addEventListener('open', () => { console.log('WebSocket连接已建立') }) socket.value.addEventListener('message', (event) => { const data = JSON.parse(event.data) const { droneId, positionData } = data // 定位新位置 const newPosition = Cesium.Cartesian3.fromDegrees( positionData.longitude, positionData.latitude, positionData.height ) // 如果没有模型则创建模型 if (!droneEntity.value) { createDroneModel(newPosition) } // 已有模型则更新位置 else { // 更新无人机位置 droneEntity.value.position = new Cesium.ConstantPositionProperty(newPosition) // 更新无人机朝向(基于运动方向) if (droneEntity.value.orientation instanceof Cesium.VelocityOrientationProperty) { droneEntity.value.orientation.position = droneEntity.value.position } // 相机跟随(位置调整) const cartographic = Cesium.Cartographic.fromCartesian(newPosition) const cameraPosition = Cesium.Cartesian3.fromRadians( cartographic.longitude, cartographic.latitude, cartographic.height + cameraHeight.value ) // 平滑更新相机位置 viewer.value.scene.camera.flyTo({ destination: cameraPosition, orientation: { heading: Cesium.Math.toRadians(data.heading || 0), pitch: -Math.PI / 3, roll: 0 }, duration: 0.8 // 800ms过渡时间 }) } }) socket.value.addEventListener('close', () => { console.log('WebSocket连接已关闭') setTimeout(initWebSocket, 2000) // 2秒后重连 }) } onMounted(() => { initViewer() initWebSocket() }) onBeforeUnmount(() => { // 清理资源 if (socket.value) socket.value.close() if (viewer.value) viewer.value.destroy() }) return { cameraHeight, updateCameraHeight } } } </script> <style scoped> .drone-monitor { position: relative; width: 100%; height: 100vh; } #cesium-container { position: absolute; top: 0; left: 0; right: 0; bottom: 0; } .camera-control { position: absolute; top: 20px; left: 20px; z-index: 100; background: rgba(0,0,0,0.7); padding: 10px 15px; border-radius: 5px; color: white; } .camera-control label { margin-right: 10px; } </style> 上述代码,模型在移动中地图视角不以模型为中心进行移动
最新发布
01-10
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值