提交 0209c099 authored 作者: 詹银鑫's avatar 詹银鑫

当前可以传单个点位让无人机进行移动

上级 e6670372
...@@ -2060,13 +2060,14 @@ export class World extends Mini3d { ...@@ -2060,13 +2060,14 @@ export class World extends Mini3d {
drone.addEventListener("mousedown", (event) => { drone.addEventListener("mousedown", (event) => {
this.showDronePopup(drone); this.showDronePopup(drone);
}); });
this.moveDroneAlongPath(drone, [ // this.moveDroneAlongPath(drone, [
[110.9801, 39.8002], // [110.9801, 39.8002],
[111.0806, 39.7005], // [111.0806, 39.7005],
[111.1803, 39.6054], // [111.1803, 39.6054],
[110.9008, 39.8056], // [110.9008, 39.8056],
[111.1003, 39.7386], // [111.1003, 39.7386],
], 20); // ], 20);
this.moveDroneAlongPath(drone, [110.9801, 39.8002], 15);
console.log("无人机模型加载完成", drone); console.log("无人机模型加载完成", drone);
}, },
(xhr) => { (xhr) => {
...@@ -2195,43 +2196,72 @@ export class World extends Mini3d { ...@@ -2195,43 +2196,72 @@ export class World extends Mini3d {
this._updateDronePopupPos(); this._updateDronePopupPos();
} }
/** /**
* 让无人机沿指定经纬度路径平滑移动 * 让无人机沿指定经纬度路径或飞到单点
* @param {THREE.Object3D} drone 无人机模型对象 * @param {THREE.Object3D} drone 无人机模型对象
* @param {Array} lngLatArr 经纬度数组 * @param {Array} lngLatArrOrPoint 经纬度数组或单个点 [lng,lat] 或 [[lng,lat],...]
* @param {number} duration 动画时长(秒) * @param {number} duration 动画时长(秒)
*/ */
moveDroneAlongPath(drone, lngLatArr, duration = 10) { moveDroneAlongPath(drone, lngLatArrOrPoint, duration = 10) {
// 1. 经纬度转three世界坐标 // 判断是单点还是数组
const z = this.depth + 1; // 高度可调整 let points;
const points = lngLatArr.map(([lng, lat]) => { if (
Array.isArray(lngLatArrOrPoint) &&
lngLatArrOrPoint.length === 2 &&
typeof lngLatArrOrPoint[0] === "number"
) {
// 单点
const [lng, lat] = lngLatArrOrPoint;
const z = this.depth + 1;
const [x, y] = this.geoProjection([lng, lat]); const [x, y] = this.geoProjection([lng, lat]);
return new THREE.Vector3(x, z, y); const target = new THREE.Vector3(x, z, y);
});
// 2. 创建平滑曲线
const curve = new THREE.CatmullRomCurve3(points, false, "catmullrom", 0.5);
// 3. 动画 // 动画到目标点
const start = drone.position.clone();
let startTime = null;
const animate = (now) => {
if (!startTime) startTime = now;
const elapsed = (now - startTime) / 1000;
let t = Math.min(elapsed / duration, 1);
drone.position.lerpVectors(start, target, t);
if (t < 1) {
drone._moveReq = requestAnimationFrame(animate);
} else {
drone.position.copy(target);
}
};
if (drone._moveReq) cancelAnimationFrame(drone._moveReq);
drone._moveReq = requestAnimationFrame(animate);
return;
} else if (
Array.isArray(lngLatArrOrPoint) &&
Array.isArray(lngLatArrOrPoint[0])
) {
// 多点曲线
const z = this.depth + 1;
points = lngLatArrOrPoint.map(([lng, lat]) => {
const [x, y] = this.geoProjection([lng, lat]);
return new THREE.Vector3(x, z, y);
});
} else {
console.warn("moveDroneAlongPath 参数格式错误");
return;
}
// 曲线动画
const curve = new THREE.CatmullRomCurve3(points, false, "catmullrom", 0.5);
let startTime = null; let startTime = null;
const animate = (now) => { const animate = (now) => {
if (!startTime) startTime = now; if (!startTime) startTime = now;
const elapsed = (now - startTime) / 1000; const elapsed = (now - startTime) / 1000;
let t = elapsed / duration; let t = Math.min(elapsed / duration, 1);
if (t > 1) t = 1;
// 沿曲线取点
const pos = curve.getPoint(t); const pos = curve.getPoint(t);
drone.position.copy(pos); drone.position.copy(pos);
// 可选:让无人机朝向运动方向
if (t < 1) { if (t < 1) {
const nextPos = curve.getPoint(Math.min(t + 0.01, 1)); const nextPos = curve.getPoint(Math.min(t + 0.01, 1));
drone.lookAt(nextPos); drone.lookAt(nextPos);
}
if (t < 1) {
drone._moveReq = requestAnimationFrame(animate); drone._moveReq = requestAnimationFrame(animate);
} }
}; };
// 停止之前的动画
if (drone._moveReq) cancelAnimationFrame(drone._moveReq); if (drone._moveReq) cancelAnimationFrame(drone._moveReq);
drone._moveReq = requestAnimationFrame(animate); drone._moveReq = requestAnimationFrame(animate);
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论