<template> <div class="map-container"> <mars-map :options="options" @onload="mapLoad"></mars-map> </div> </template> <script setup> import { ref, onMounted, onUnmounted } from "vue"; import marsMap from "@/components/marsMap"; let options = { scene: { center: { lat: 30.647679, lng: 120.691682, alt: 37478.2, heading: 2.7, pitch: -36.9, }, showSun: false, showMoon: false, showSkyBox: false, showSkyAtmosphere: false, fog: false, // backgroundColor: "#363635", // 天空背景色 globe: { baseColor: "#363635", // 地球地面背景色 showGroundAtmosphere: false, enableLighting: false, }, clock: { currentTime: "2023-11-01 12:00:00", // 固定光照时间 }, cameraController: { zoomFactor: 1.5, minimumZoomDistance: 0.1, maximumZoomDistance: 200000, enableCollisionDetection: false, // 允许进入地下 }, }, terrain: { show: false, }, basemaps: [ { id: 2017, pid: 10, name: "蓝色底图", icon: "https://data.mars3d.cn/img/thumbnail/basemap/my_blue.png", type: "gaode", layer: "vec", chinaCRS: "GCJ02", invertColor: true, filterColor: "#015CB3", brightness: 0.6, contrast: 1.8, gamma: 0.3, hue: 1, saturation: 0, show: true, }, ], }; const gamepadIndex = ref(null); // 当前手柄索引 const direction = ref(""); // 当前方向(上、下、左、右) let map = null; let Cesium = {}; let mapLayer = {}; let uav = null; const params = reactive({ lat: 31.162232, lng: 120.734077, altitude: 3000, heading: 0, //当前朝向 pitch: 0, //保当前俯仰角 roll: 0, //当前翻滚角 correction: 1, speed: 800, gamepad: true, }); /** * 地图渲染完毕 * @param mapInstance 当前地图对象 */ const mapLoad = (mapInstance) => { map = mapInstance; Cesium = mars3d.Cesium; //创建marker图层 mapLayer.markerLayer = new mars3d.layer.GraphicLayer({ allowDrillPick: true, // 如果存在坐标完全相同的图标点,可以打开该属性,click事件通过graphics判断 }); map.addLayer(mapLayer.markerLayer); onAddGamepadboardListener() boostrapUav(); }; /** * 监听游戏手柄 */ const onAddGamepadboardListener =()=>{ window.addEventListener('gamepadconnected', function (e) { var gp = navigator.getGamepads()[e.gamepad.index] console.log(gp, '链接') }) // 监听游戏手柄拔出 window.addEventListener('gamepaddisconnected', function (e) { clearInterval(interval) }) } /** * 创建模型对象 */ const initModel = () => { const position = Cesium.Cartesian3.fromDegrees(120.734077, 31.162232, 2000) uav = new mars3d.graphic.Route({ id:"uav", name:"无人机模型", position:position, model:{ url: "https://data.mars3d.cn/gltf/mars/wrj.glb", scale: 5, minimumPixelSize: 50, // heading:220 }, camera:{ type:'gs', radius:25000, heading:25, pitch:-35 } }) mapLayer.markerLayer.addGraphic(uav); }; const boostrapUav = () => { initModel(); const renderer = () => { startgamepad() onAdjustAttitude(); requestAnimationFrame(renderer); }; renderer(); }; const startgamepad = () => { var gamepad = navigator.getGamepads()[0] if (gamepad) { //手柄方向按键 // pressKey(gamepad!.buttons) // 手柄方向遥感 rocker(gamepad.axes) } } const rocker = (axes) => { const deadZone = 0.5 const x = axes[0] const y = axes[1] // //机体左转 if (x < -deadZone) { //机体左转 params.heading -= 0.1 if (params.roll > -0.785) { params.roll -= 1 } } else if (x > deadZone) { //机体右转 params.heading += 0.1 if (params.roll < 0.785) { params.roll += 0.1 } } // 检测垂直方向机体爬升 if (y < -deadZone && params.pitch <= 0.3) { params.pitch += 0.015 if (params.pitch > 0) { const { speed, pitch } = params const temp = (params.speed / 60 / 60 / 60) * 110 //1经纬度约等于110km params.altitude += temp * Math.sin(pitch) } } else if (y > deadZone && params.pitch >= -0.3) { //机体俯冲 params.pitch -= 0.016 if (params.pitch < 0) { const { speed, pitch } = params //1经纬度约等于110km const temp = (params.speed / 60 / 60 / 60) * 110 params.altitude += temp * Math.sin(pitch) } } uavCommit() } const uavCommit = () => { const { heading, pitch, roll } = params const { abs, cos } = Math params.correction = abs(cos(heading) * cos(pitch)) if (abs(heading) < 0.001) params.heading = 0 if (abs(roll) < 0.001) params.roll = 0 if (abs(pitch) < 0.001) params.pitch = 0 //方向自动回正 // if (params.heading > 0) params.heading -= 0.0025 // if (params.heading < 0) params.heading += 0.0025 if (params.roll > 0) params.roll -= 0.003 if (params.roll < 0) params.roll += 0.003 if (params.pitch < 0) params.pitch += 0.005 if (params.pitch > 0) params.pitch -= 0.003 } // 开启飞行姿态调整 const onAdjustAttitude = () => { const temp = params.speed / 60 / 60 / 60 / 110 params.lng += temp * Math.cos(params.heading) params.lat -= temp * Math.sin(params.heading) const { lng, lat, altitude, heading, pitch, roll } = params params.altitude += temp * Math.sin(pitch) * 110 * 1000 * 10 // const position = Cesium.Cartesian3.fromDegrees(lng, lat, altitude) // const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll) // const orientation = Cesium.Transforms.headingPitchRollQuaternion( // position, // hpr // ) const point = new mars3d.LngLatPoint(lng, lat, altitude) uav.model.setStyle({ heading:heading, pitch:pitch, roll:roll, }) uav.addTimePosition(point) } onUnmounted(() => { window.removeEventListener("gamepadconnected", ); window.removeEventListener("gamepaddisconnected", ); }); </script> <style lang="scss" scoped> .map-container { height: 100%; } </style>