Feat/map-environment #6
@@ -1,6 +1,39 @@
|
|||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { InstancedVegetation } from "@/world/vegetation/InstancedVegetation";
|
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<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 {
|
export function VegetationSystem(): React.JSX.Element | null {
|
||||||
const { data, isLoading } = useVegetationData();
|
const { data, isLoading } = useVegetationData();
|
||||||
@@ -16,16 +49,20 @@ export function VegetationSystem(): React.JSX.Element | null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
const castShadow = !INSTANCED_MAP_NO_SHADOW_NAMES.has(modelName);
|
||||||
<Suspense key={modelName} fallback={null}>
|
const receiveShadow = castShadow;
|
||||||
|
const chunks = chunkInstances(entry.instances);
|
||||||
|
|
||||||
|
return [...chunks.entries()].map(([chunkKey, instances]) => (
|
||||||
|
<Suspense key={`${modelName}:${chunkKey}`} fallback={null}>
|
||||||
<InstancedVegetation
|
<InstancedVegetation
|
||||||
modelPath={entry.modelPath}
|
modelPath={entry.modelPath}
|
||||||
instances={entry.instances}
|
instances={instances}
|
||||||
castShadow={true}
|
castShadow={castShadow}
|
||||||
receiveShadow={true}
|
receiveShadow={receiveShadow}
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
));
|
||||||
})}
|
})}
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,3 +9,14 @@ export const INSTANCED_MAP_EXCEPTIONS = new Set([
|
|||||||
"blocking",
|
"blocking",
|
||||||
"terrain",
|
"terrain",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
export const INSTANCED_MAP_CHUNK_SIZE = 45;
|
||||||
|
|
||||||
|
export const INSTANCED_MAP_NO_SHADOW_NAMES = new Set([
|
||||||
|
"arbre",
|
||||||
|
"sapin",
|
||||||
|
"buisson",
|
||||||
|
"champdeble",
|
||||||
|
"champdesoja",
|
||||||
|
"champsdetournesol",
|
||||||
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user