Feat/map-environment #6

Merged
math-pixel merged 116 commits from feat/map-environment into develop 2026-05-29 00:00:51 +00:00
3 changed files with 22 additions and 37 deletions
Showing only changes of commit a52d57ae6c - Show all commits
-18
View File
@@ -9,7 +9,6 @@ export function SceneLoadingOverlay({
}: SceneLoadingOverlayProps): React.JSX.Element | null { }: SceneLoadingOverlayProps): React.JSX.Element | null {
const isReady = state.status === "ready"; const isReady = state.status === "ready";
const progress = Math.round(Math.max(0, Math.min(1, state.progress)) * 100); const progress = Math.round(Math.max(0, Math.min(1, state.progress)) * 100);
const helperText = getLoadingHelperText(state.progress);
return ( return (
<div <div
@@ -18,7 +17,6 @@ export function SceneLoadingOverlay({
> >
<div className="scene-loading-overlay__content"> <div className="scene-loading-overlay__content">
<strong>{state.currentStep}</strong> <strong>{state.currentStep}</strong>
<p>{helperText}</p>
<div className="scene-loading-overlay__track"> <div className="scene-loading-overlay__track">
<span style={{ width: `${progress}%` }} /> <span style={{ width: `${progress}%` }} />
<em>{progress}%</em> <em>{progress}%</em>
@@ -27,19 +25,3 @@ export function SceneLoadingOverlay({
</div> </div>
); );
} }
function getLoadingHelperText(progress: number): string {
if (progress >= 0.95) {
return "Finalisation de la scène et de la première frame.";
}
if (progress >= 0.7) {
return "Préparation des collisions et du gameplay.";
}
if (progress >= 0.25) {
return "Chargement progressif de la map autour du joueur.";
}
return "Récupération des données et modèles nécessaires.";
}
-10
View File
@@ -466,16 +466,6 @@ canvas {
text-transform: uppercase; text-transform: uppercase;
} }
.scene-loading-overlay p {
max-width: 290px;
margin: -8px 0 0;
color: #64748b;
font-size: 12px;
font-weight: 500;
line-height: 1.45;
text-align: center;
}
.scene-loading-overlay__track { .scene-loading-overlay__track {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
+22 -9
View File
@@ -111,10 +111,13 @@ export function GameMap({
const settledMapNodesRef = useRef(new Set<number>()); const settledMapNodesRef = useRef(new Set<number>());
const groups = useMapPerformanceStore((state) => state.groups); const groups = useMapPerformanceStore((state) => state.groups);
const models = useMapPerformanceStore((state) => state.models); const models = useMapPerformanceStore((state) => state.models);
const [mapNodes, setMapNodes] = useState<LoadedMapNode[]>([]); const [renderMapNodes, setRenderMapNodes] = useState<LoadedMapNode[]>([]);
const [collisionMapNodes, setCollisionMapNodes] = useState<LoadedMapNode[]>(
[],
);
const [mapLoaded, setMapLoaded] = useState(false); const [mapLoaded, setMapLoaded] = useState(false);
const [settledMapNodeCount, setSettledMapNodeCount] = useState(0); const [settledMapNodeCount, setSettledMapNodeCount] = useState(0);
const mapReady = mapLoaded && settledMapNodeCount >= mapNodes.length; const mapReady = mapLoaded && settledMapNodeCount >= renderMapNodes.length;
const handleMapNodeSettled = useCallback((index: number) => { const handleMapNodeSettled = useCallback((index: number) => {
if (settledMapNodesRef.current.has(index)) return; if (settledMapNodesRef.current.has(index)) return;
@@ -125,7 +128,8 @@ export function GameMap({
const showEmptyMap = useCallback( const showEmptyMap = useCallback(
(currentStep: string) => { (currentStep: string) => {
setMapNodes([]); setRenderMapNodes([]);
setCollisionMapNodes([]);
setMapLoaded(true); setMapLoaded(true);
settledMapNodesRef.current.clear(); settledMapNodesRef.current.clear();
setSettledMapNodeCount(0); setSettledMapNodeCount(0);
@@ -174,6 +178,12 @@ export function GameMap({
const modelUrl = sceneData.models.get(node.name); const modelUrl = sceneData.models.get(node.name);
return { node, modelUrl: modelUrl ?? null }; return { node, modelUrl: modelUrl ?? null };
}); });
const loadedCollisionNodes = sceneData.mapNodes
.filter((node) => node.name === "terrain")
.map((node) => {
const modelUrl = sceneData.models.get(node.name);
return { node, modelUrl: modelUrl ?? null };
});
const missingModelCount = loadedMapNodes.filter( const missingModelCount = loadedMapNodes.filter(
(mapNode) => mapNode.modelUrl === null, (mapNode) => mapNode.modelUrl === null,
).length; ).length;
@@ -188,7 +198,8 @@ export function GameMap({
); );
} }
setMapNodes(loadedMapNodes); setRenderMapNodes(loadedMapNodes);
setCollisionMapNodes(loadedCollisionNodes);
setMapLoaded(true); setMapLoaded(true);
settledMapNodesRef.current.clear(); settledMapNodesRef.current.clear();
setSettledMapNodeCount(0); setSettledMapNodeCount(0);
@@ -209,21 +220,23 @@ export function GameMap({
}, [onLoadingStateChange, showEmptyMap]); }, [onLoadingStateChange, showEmptyMap]);
useEffect(() => { useEffect(() => {
if (mapNodes.length === 0) return; if (renderMapNodes.length === 0) return;
const renderProgress = const renderProgress =
mapNodes.length === 0 ? 1 : settledMapNodeCount / mapNodes.length; renderMapNodes.length === 0
? 1
: settledMapNodeCount / renderMapNodes.length;
onLoadingStateChange?.({ onLoadingStateChange?.({
currentStep: "Chargement des modèles de la map", currentStep: "Chargement des modèles de la map",
progress: 0.25 + renderProgress * 0.45, progress: 0.25 + renderProgress * 0.45,
status: "loading", status: "loading",
}); });
}, [mapNodes.length, onLoadingStateChange, settledMapNodeCount]); }, [renderMapNodes.length, onLoadingStateChange, settledMapNodeCount]);
return ( return (
<> <>
<group> <group>
{mapNodes.map((mapNode, index) => ( {renderMapNodes.map((mapNode, index) => (
<ModelErrorBoundary <ModelErrorBoundary
key={index} key={index}
fallback={<FallbackMapNode node={mapNode.node} />} fallback={<FallbackMapNode node={mapNode.node} />}
@@ -251,7 +264,7 @@ export function GameMap({
<GameMapCollision <GameMapCollision
buildOctree={buildOctree} buildOctree={buildOctree}
mapReady={mapReady} mapReady={mapReady}
nodes={mapNodes} nodes={collisionMapNodes}
onLoaded={onLoaded} onLoaded={onLoaded}
onLoadingStateChange={onLoadingStateChange} onLoadingStateChange={onLoadingStateChange}
onOctreeReady={onOctreeReady} onOctreeReady={onOctreeReady}