fix path to terrain alignment

This commit is contained in:
munsel 2026-04-26 00:28:26 +02:00
parent b836d9c01b
commit 81a6f1fa37

View File

@ -71,6 +71,7 @@ export function createCustom3DLayer(id: string, map: Map): Layer3DHandle {
let renderer: THREE.WebGLRenderer | null = null
let origin: MercatorCoordinate | null = null
let originLngLat: [number, number] | null = null
let dirty = true
let currentLines: Line3D[] = []
let currentPoints: Point3D[] = []
@ -96,6 +97,7 @@ export function createCustom3DLayer(id: string, map: Map): Layer3DHandle {
sphereMeshes.length = 0
sphereIds.length = 0
origin = null
originLngLat = null
}
function rebuildGeometry() {
@ -109,6 +111,7 @@ export function createCustom3DLayer(id: string, map: Map): Layer3DHandle {
if (!firstPt) return
const [lon0, lat0, alt0] = firstPt
originLngLat = [lon0, lat0]
// Use exaggerated altitude so geometry aligns with visual terrain.
origin = MercatorCoordinate.fromLngLat([lon0, lat0], alt0 * TERRAIN_EXAGGERATION)
const mpu = origin.meterInMercatorCoordinateUnits()
@ -198,9 +201,14 @@ export function createCustom3DLayer(id: string, map: Map): Layer3DHandle {
// modelViewProjectionMatrix (used by terrain tiles) but absent from
// mercatorMatrix (passed to custom layers). Subtracting it here makes
// our exaggerated-altitude objects align with the visual terrain surface.
const mpu = origin.meterInMercatorCoordinateUnits()
//
// Use MercatorCoordinate.fromLngLat (not origin.meterInMercatorCoordinateUnits)
// because altitude z uses 1/(circumference*cos(lat)) while mpu gives
// cos(lat)/circumference — they differ by cos²(lat), causing ~2× error at lat 50°.
const centerElevM = (map as unknown as { transform: { elevation: number } }).transform?.elevation ?? 0
const centerElevMerc = centerElevM * mpu
const centerElevMerc = originLngLat
? MercatorCoordinate.fromLngLat(originLngLat, centerElevM).z
: centerElevM * origin.meterInMercatorCoordinateUnits()
const m = new THREE.Matrix4().fromArray(matrix)
const t = new THREE.Matrix4().makeTranslation(