From 2b08665508668d9fc64dc0da1171f1d7e2cb9a78 Mon Sep 17 00:00:00 2001 From: Tom Boullay Date: Mon, 25 May 2026 17:54:57 +0200 Subject: [PATCH] fix(map): align path preview with terrain projection --- src/utils/world/terrainSurfaceSampler.ts | 4 ++-- src/world/paths/PathSystem.tsx | 6 +++++- src/world/paths/usePathTileData.ts | 8 ++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/utils/world/terrainSurfaceSampler.ts b/src/utils/world/terrainSurfaceSampler.ts index c80fc2e..43eacb9 100644 --- a/src/utils/world/terrainSurfaceSampler.ts +++ b/src/utils/world/terrainSurfaceSampler.ts @@ -91,8 +91,8 @@ export function terrainSurfaceUvFromXZ( ): TerrainSurfaceUv { const width = bounds.maxX - bounds.minX; const depth = bounds.maxZ - bounds.minZ; - let u = width === 0 ? 0 : (x - bounds.minX) / width; - let v = depth === 0 ? 0 : (z - bounds.minZ) / depth; + let u = width === 0 ? 0 : x / width + 0.5; + let v = depth === 0 ? 0 : z / depth + 0.5; if (projection?.flipX) { u = 1 - u; diff --git a/src/world/paths/PathSystem.tsx b/src/world/paths/PathSystem.tsx index be8c8c2..7cad014 100644 --- a/src/world/paths/PathSystem.tsx +++ b/src/world/paths/PathSystem.tsx @@ -62,7 +62,11 @@ function PathDebugPreview({ const instance = instances[i]; if (!instance) continue; - position.set(instance.position[0], 0.08, instance.position[2]); + position.set( + instance.position[0], + instance.position[1] + 0.08, + instance.position[2], + ); matrix.compose(position, quaternion, scale); instancedMesh.setMatrixAt(i, matrix); } diff --git a/src/world/paths/usePathTileData.ts b/src/world/paths/usePathTileData.ts index b024dd0..d0fd8c6 100644 --- a/src/world/paths/usePathTileData.ts +++ b/src/world/paths/usePathTileData.ts @@ -1,5 +1,6 @@ import { useMemo } from "react"; import { TERRAIN_SURFACE_PROJECTION } from "@/data/world/terrainConfig"; +import { useTerrainHeightSampler } from "@/hooks/three/useTerrainHeight"; import { useTerrainSurfaceData } from "@/hooks/world/useTerrainSurfaceData"; import type { Vector3Tuple } from "@/types/three/three"; import { sampleTerrainSurfaceAtXZ } from "@/utils/world/terrainSurfaceSampler"; @@ -25,6 +26,7 @@ function createSampleCenters(min: number, max: number, step: number): number[] { export function usePathTileData(): MapAssetInstance[] { const terrainSurfaceData = useTerrainSurfaceData(); + const terrainHeight = useTerrainHeightSampler(); return useMemo(() => { if (!terrainSurfaceData) return []; @@ -55,8 +57,10 @@ export function usePathTileData(): MapAssetInstance[] { if (sample.key !== PATH_SURFACE_KEY) continue; + const height = terrainHeight.getHeight(x, z) ?? 0; + instances.push({ - position: [x, 0, z], + position: [x, height, z], rotation: [...PATH_TILE_ROTATION] as Vector3Tuple, scale: [...PATH_TILE_SCALE] as Vector3Tuple, }); @@ -64,5 +68,5 @@ export function usePathTileData(): MapAssetInstance[] { } return instances; - }, [terrainSurfaceData]); + }, [terrainHeight, terrainSurfaceData]); }