Merge branch 'feat/map-environment' of https://git.fabrik.mathieu-chavanel.fr/math-pixel/La-Fabrik into feat/map-environment
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled

This commit is contained in:
Tom Boullay
2026-05-24 22:07:15 +02:00
147 changed files with 1490 additions and 329 deletions
+25 -45
View File
@@ -1,68 +1,48 @@
import { Suspense } from "react";
import {
isMapModelVisible,
useMapPerformanceStore,
} from "@/managers/stores/useMapPerformanceStore";
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,
VEGETATION_TYPES,
type VegetationType,
} 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<string, VegetationInstance[]> {
const chunks = new Map<string, VegetationInstance[]>();
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 groups = useMapPerformanceStore((state) => state.groups);
const models = useMapPerformanceStore((state) => state.models);
const { data, isLoading } = useVegetationData();
if (isLoading || !data) {
return null;
}
const enabledTypes = Object.entries(VEGETATION_TYPES).filter(
([, config]) =>
config.enabled && isMapModelVisible(config.mapName, { groups, models }),
);
return (
<group name="instanced-map-system">
{[...data.entries()].map(([modelName, entry]) => {
if (entry.instances.length === 0) {
<group name="vegetation-system">
{enabledTypes.map(([type, config]) => {
const instances = data.get(type as VegetationType);
if (!instances || instances.length === 0) {
return null;
}
const castShadow = !INSTANCED_MAP_NO_SHADOW_NAMES.has(modelName);
const receiveShadow = castShadow;
const chunks = chunkInstances(entry.instances);
return [...chunks.entries()].map(([chunkKey, instances]) => (
<Suspense key={`${modelName}:${chunkKey}`} fallback={null}>
return (
<Suspense key={type} fallback={null}>
<InstancedVegetation
modelPath={entry.modelPath}
modelPath={config.modelPath}
instances={instances}
castShadow={castShadow}
receiveShadow={receiveShadow}
castShadow={config.castShadow}
receiveShadow={config.receiveShadow}
/>
</Suspense>
));
);
})}
</group>
);