feat(map): generate path tiles from terrain colors
This commit is contained in:
@@ -24,6 +24,7 @@ import { GeneratedMapNodeInstance } from "@/world/map-generated/GeneratedMapNode
|
||||
import { isGeneratedMapModelName } from "@/world/map-generated/generatedMapModelConfig";
|
||||
import { MapInstancingSystem } from "@/world/map-instancing/MapInstancingSystem";
|
||||
import { isInstancedMapNodeName } from "@/world/map-instancing/mapInstancingConfig";
|
||||
import { PathSystem } from "@/world/paths/PathSystem";
|
||||
import { VegetationSystem } from "@/world/vegetation/VegetationSystem";
|
||||
import type { SceneLoadingChangeHandler } from "@/types/world/sceneLoading";
|
||||
import { logger } from "@/utils/core/Logger";
|
||||
@@ -257,6 +258,7 @@ export function GameMap({
|
||||
))}
|
||||
</group>
|
||||
<MapInstancingSystem />
|
||||
<PathSystem />
|
||||
<VegetationSystem />
|
||||
{isMapModelVisible("terrain", { groups, models }) ? (
|
||||
<TerrainModel />
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { InstancedMapAsset } from "@/world/map-instancing/InstancedMapAsset";
|
||||
import { PATH_TILE_MODEL_PATH } from "@/world/paths/pathConfig";
|
||||
import { usePathTileData } from "@/world/paths/usePathTileData";
|
||||
|
||||
export function PathSystem(): React.JSX.Element | null {
|
||||
const pathTiles = usePathTileData();
|
||||
|
||||
if (pathTiles.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<InstancedMapAsset
|
||||
castShadow={false}
|
||||
instances={pathTiles}
|
||||
modelPath={PATH_TILE_MODEL_PATH}
|
||||
receiveShadow
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { TERRAIN_COLORS, TERRAIN_TILE_SIZE } from "@/data/world/terrainConfig";
|
||||
|
||||
export const PATH_SURFACE_KEY = "chemin";
|
||||
export const PATH_TILE_MODEL_PATH = TERRAIN_COLORS.chemin.modelPath;
|
||||
export const PATH_TILE_SIZE =
|
||||
TERRAIN_COLORS.chemin.tileSize ?? TERRAIN_TILE_SIZE;
|
||||
export const PATH_TILE_SAMPLE_STEP = 2;
|
||||
export const PATH_TILE_MAX_COUNT = 1500;
|
||||
export const PATH_TILE_ROTATION = [0, 0, 0] as const;
|
||||
export const PATH_TILE_SCALE = [1, 1, 1] as const;
|
||||
@@ -0,0 +1,68 @@
|
||||
import { useMemo } from "react";
|
||||
import { useTerrainSurfaceData } from "@/hooks/world/useTerrainSurfaceData";
|
||||
import type { Vector3Tuple } from "@/types/three/three";
|
||||
import { sampleTerrainSurfaceAtXZFromRaycast } from "@/utils/world/terrainSurfaceSampler";
|
||||
import type { MapAssetInstance } from "@/world/map-instancing/useMapInstancingData";
|
||||
import {
|
||||
PATH_TILE_MAX_COUNT,
|
||||
PATH_SURFACE_KEY,
|
||||
PATH_TILE_ROTATION,
|
||||
PATH_TILE_SAMPLE_STEP,
|
||||
PATH_TILE_SCALE,
|
||||
} from "@/world/paths/pathConfig";
|
||||
|
||||
function createSampleCenters(min: number, max: number, step: number): number[] {
|
||||
const start = Math.ceil(min / step) * step + step * 0.5;
|
||||
const centers: number[] = [];
|
||||
|
||||
for (let value = start; value <= max; value += step) {
|
||||
centers.push(value);
|
||||
}
|
||||
|
||||
return centers;
|
||||
}
|
||||
|
||||
export function usePathTileData(): MapAssetInstance[] {
|
||||
const terrainSurfaceData = useTerrainSurfaceData();
|
||||
|
||||
return useMemo(() => {
|
||||
if (!terrainSurfaceData) return [];
|
||||
|
||||
const instances: MapAssetInstance[] = [];
|
||||
const xCenters = createSampleCenters(
|
||||
terrainSurfaceData.bounds.minX,
|
||||
terrainSurfaceData.bounds.maxX,
|
||||
PATH_TILE_SAMPLE_STEP,
|
||||
);
|
||||
const zCenters = createSampleCenters(
|
||||
terrainSurfaceData.bounds.minZ,
|
||||
terrainSurfaceData.bounds.maxZ,
|
||||
PATH_TILE_SAMPLE_STEP,
|
||||
);
|
||||
const raycastY = terrainSurfaceData.bounds.maxY + 10;
|
||||
|
||||
for (const x of xCenters) {
|
||||
for (const z of zCenters) {
|
||||
if (instances.length >= PATH_TILE_MAX_COUNT) return instances;
|
||||
|
||||
const sample = sampleTerrainSurfaceAtXZFromRaycast(
|
||||
terrainSurfaceData.imageData,
|
||||
terrainSurfaceData.raycastTarget,
|
||||
x,
|
||||
z,
|
||||
raycastY,
|
||||
);
|
||||
|
||||
if (sample?.key !== PATH_SURFACE_KEY) continue;
|
||||
|
||||
instances.push({
|
||||
position: [x, 0, z],
|
||||
rotation: [...PATH_TILE_ROTATION] as Vector3Tuple,
|
||||
scale: [...PATH_TILE_SCALE] as Vector3Tuple,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return instances;
|
||||
}, [terrainSurfaceData]);
|
||||
}
|
||||
Reference in New Issue
Block a user