vue中Mapbox和Three.JS:實現3D模型與地圖視角的完美適配
本文探討如何在Vue.js應用中,結合Mapbox GL JS和Three.js,實現三維模型與地圖視角的同步,確保模型底部始終固定在地圖表面,不會因視角變化而偏移。這在構建地理信息系統或3D地圖可視化應用中至關重要。
假設你已成功渲染3D立方體到Mapbox地圖,但視角移動時立方體位置發生漂移。問題在于Three.js坐標系與Mapbox地圖坐標系的轉換和模型位置的設置。
以下代碼片段展示了可能存在問題的代碼結構,其中render函數更新Three.js相機矩陣,calculatemodeltransform函數進行坐標轉換:
render: (gl, matrix) => { const m = new THREE.Matrix4().fromArray(matrix); const l = new THREE.Matrix4().makeTranslation(modelTransform.translateX, modelTransform.translateY, modelTransform.translateZ) .scale(new THREE.Vector3(modelTransform.scale, -modelTransform.scale, modelTransform.scale)) .multiply(new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(1, 0, 0), modelTransform.rotateX)) .multiply(new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 1, 0), modelTransform.rotateY)) .multiply(new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 0, 1), modelTransform.rotateZ)); customLayer.camera.projectionMatrix = m.multiply(l); customLayer.renderer.resetState(); customLayer.renderer.render(customLayer.scene, customLayer.camera); customLayer.map.triggerRepaint(); }, calculatemodeltransform(point) { const modelAsMercatorCoordinate = mapboxgl.MercatorCoordinate.fromLngLat([point.lng, point.lat], this.modelAltitude); return { translateX: modelAsMercatorCoordinate.x, translateY: modelAsMercatorCoordinate.y, translateZ: modelAsMercatorCoordinate.z, rotateX: this.modelRotate[0], rotateY: this.modelRotate[1], rotateZ: this.modelRotate[2], scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits() }; }
核心問題在于模型的translateZ以及模型創建時的垂直位置。 我們需要調整模型位置,使其底部與地圖平面精確對齊。
立即學習“前端免費學習筆記(深入)”;
解決方案:
- 模型創建調整: 在創建Three.js模型時,考慮模型高度,并調整其垂直位置(y軸)使其底部位于地圖平面(通常y=0)。
// 創建一個正方體幾何體,altitude 為模型高度 const geometry = new THREE.BoxGeometry(20, altitude, 20); const material = new THREE.MeshStandardMaterial({ color, transparent: true, opacity: 0.8 }); const cube = new THREE.Mesh(geometry, material); // 關鍵步驟:將立方體底部放置在地圖平面上 cube.position.y = altitude / 2;
- render函數調整: 在render函數中,根據模型高度調整translateZ值,確保模型底部始終與地圖平面對齊。
const l = new THREE.Matrix4().makeTranslation(modelTransform.translateX, modelTransform.translateY, modelTransform.translateZ - altitude / 2) .scale(new THREE.Vector3(modelTransform.scale, -modelTransform.scale, modelTransform.scale)) // ... 其他轉換矩陣
通過以上調整,即使地圖視角變化,三維模型的底部也會保持在地圖表面,實現完美的視角適配。 請確保altitude變量正確反映模型的高度。 如有需要,可以根據模型的實際幾何形狀進一步微調垂直位置。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END