You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
6.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>