diff --git a/src/world/vegetation/VegetationSystem.tsx b/src/world/vegetation/VegetationSystem.tsx index a8e9d4c..8f20a6c 100644 --- a/src/world/vegetation/VegetationSystem.tsx +++ b/src/world/vegetation/VegetationSystem.tsx @@ -1,6 +1,39 @@ import { Suspense } from "react"; import { InstancedVegetation } from "@/world/vegetation/InstancedVegetation"; -import { useVegetationData } from "@/world/vegetation/useVegetationData"; +import { + type VegetationInstance, + useVegetationData, +} from "@/world/vegetation/useVegetationData"; +import { + INSTANCED_MAP_CHUNK_SIZE, + INSTANCED_MAP_NO_SHADOW_NAMES, +} from "@/world/vegetation/vegetationConfig"; + +function createChunkKey(instance: VegetationInstance): string { + const [x, , z] = instance.position; + const chunkX = Math.floor(x / INSTANCED_MAP_CHUNK_SIZE); + const chunkZ = Math.floor(z / INSTANCED_MAP_CHUNK_SIZE); + return `${chunkX}:${chunkZ}`; +} + +function chunkInstances( + instances: VegetationInstance[], +): Map { + const chunks = new Map(); + + for (const instance of instances) { + const key = createChunkKey(instance); + const chunk = chunks.get(key); + + if (chunk) { + chunk.push(instance); + } else { + chunks.set(key, [instance]); + } + } + + return chunks; +} export function VegetationSystem(): React.JSX.Element | null { const { data, isLoading } = useVegetationData(); @@ -16,16 +49,20 @@ export function VegetationSystem(): React.JSX.Element | null { return null; } - return ( - + const castShadow = !INSTANCED_MAP_NO_SHADOW_NAMES.has(modelName); + const receiveShadow = castShadow; + const chunks = chunkInstances(entry.instances); + + return [...chunks.entries()].map(([chunkKey, instances]) => ( + - ); + )); })} ); diff --git a/src/world/vegetation/vegetationConfig.ts b/src/world/vegetation/vegetationConfig.ts index fb151b2..73e7200 100644 --- a/src/world/vegetation/vegetationConfig.ts +++ b/src/world/vegetation/vegetationConfig.ts @@ -9,3 +9,14 @@ export const INSTANCED_MAP_EXCEPTIONS = new Set([ "blocking", "terrain", ]); + +export const INSTANCED_MAP_CHUNK_SIZE = 45; + +export const INSTANCED_MAP_NO_SHADOW_NAMES = new Set([ + "arbre", + "sapin", + "buisson", + "champdeble", + "champdesoja", + "champsdetournesol", +]);