@@ -243,33 +429,39 @@ export function EditorPage(): React.JSX.Element {
@@ -279,6 +471,7 @@ export function EditorPage(): React.JSX.Element {
transformMode={transformMode}
onTransformModeChange={handleTransformModeChange}
selectedNodeIndex={selectedNodeIndex}
+ selectedNodeIndexes={selectedNodeIndexes}
mapNodes={sceneData.mapNodes}
nodesCount={sceneData.mapNodes.length}
selectedNodeName={
@@ -286,13 +479,34 @@ export function EditorPage(): React.JSX.Element {
? sceneData.mapNodes[selectedNodeIndex].name || null
: null
}
+ selectedNodeScale={
+ selectedNodeIndex !== null && sceneData.mapNodes[selectedNodeIndex]
+ ? sceneData.mapNodes[selectedNodeIndex].scale
+ : null
+ }
+ lockTerrainSelection={lockTerrainSelection}
+ onLockTerrainSelectionChange={handleTerrainSelectionLockChange}
isSelectionLocked={isSelectionLocked}
onSelectionLockToggle={handleSelectionLockToggle}
onClearSelection={handleClearSelection}
+ snapToTerrain={snapToTerrain}
+ onSnapToTerrainToggle={handleSnapToTerrainToggle}
+ onSnapAllToTerrain={handleSnapAllToTerrainRequest}
+ newNodeName={newNodeName}
+ onNewNodeNameChange={handleNewNodeNameChange}
+ onAddNode={handleAddNode}
+ onDeleteSelectedNode={handleDeleteSelectedNode}
+ onSelectedScaleChange={handleSelectedScaleChange}
undoCount={undoCount}
redoCount={redoCount}
onUndo={handleUndo}
onRedo={handleRedo}
+ cameraActionLabel={
+ selectedNodeIndex !== null && cameraViewMode === "home"
+ ? "Center on object"
+ : "Reset camera"
+ }
+ onCameraAction={handleCameraAction}
onExportJson={handleExportJson}
onSaveToServer={import.meta.env.DEV ? handleSaveToServer : undefined}
onPlayerMode={handlePlayerMode}
diff --git a/src/pages/gallery/page.tsx b/src/pages/gallery/page.tsx
index 2438beb..d86c24f 100644
--- a/src/pages/gallery/page.tsx
+++ b/src/pages/gallery/page.tsx
@@ -33,12 +33,10 @@ import {
AMBIENT_INTENSITY_MAX,
AMBIENT_INTENSITY_MIN,
AMBIENT_INTENSITY_STEP,
- AMBIENT_LIGHT_COLOR,
LIGHTING_DEFAULTS,
SUN_INTENSITY_MAX,
SUN_INTENSITY_MIN,
SUN_INTENSITY_STEP,
- SUN_LIGHT_COLOR,
SUN_X_MAX,
SUN_X_MIN,
SUN_X_STEP,
@@ -50,8 +48,8 @@ import {
SUN_Z_STEP,
} from "@/data/world/lightingConfig";
import {
- GAME_SCENE_FALLBACK_SKY_MODEL_PATH,
- GAME_SCENE_FALLBACK_SKY_MODEL_SCALE,
+ GAME_SCENE_SKY_FALLBACK_MODEL_PATH,
+ GAME_SCENE_SKY_FALLBACK_MODEL_SCALE,
GAME_SCENE_SKY_MODEL_PATH,
GAME_SCENE_SKY_MODEL_SCALE,
} from "@/data/world/environmentConfig";
@@ -337,8 +335,8 @@ function GalleryScene({
return (
<>
>
);
diff --git a/src/pages/page.tsx b/src/pages/page.tsx
index a34c6aa..deae3e3 100644
--- a/src/pages/page.tsx
+++ b/src/pages/page.tsx
@@ -6,12 +6,11 @@ import { DialogMessage } from "@/components/ui/DialogMessage";
import { GameUI } from "@/components/ui/GameUI";
import { BienvenueDisplay, IntroUI } from "@/components/ui/IntroUI";
import { SceneLoadingOverlay } from "@/components/ui/SceneLoadingOverlay";
+import { INITIAL_SCENE_LOADING_STATE } from "@/data/world/sceneLoadingConfig";
import { useGameStore } from "@/managers/stores/useGameStore";
import { HandTrackingProvider } from "@/providers/gameplay/HandTrackingProvider";
-import {
- INITIAL_SCENE_LOADING_STATE,
- type SceneLoadingState,
-} from "@/types/world/sceneLoading";
+import type { SceneLoadingState } from "@/types/world/sceneLoading";
+import { logger } from "@/utils/core/Logger";
import { World } from "@/world/World";
export function HomePage(): React.JSX.Element {
@@ -51,11 +50,43 @@ export function HomePage(): React.JSX.Element {
[],
);
+ const handleCanvasCreated = useCallback(
+ ({ gl }: { gl: THREE.WebGLRenderer }) => {
+ const canvas = gl.domElement;
+
+ gl.shadowMap.enabled = true;
+ gl.shadowMap.type = THREE.PCFShadowMap;
+ gl.shadowMap.autoUpdate = true;
+
+ const handleContextLost = (event: Event) => {
+ event.preventDefault();
+ logger.error("WebGL", "Context lost - GPU resources exhausted");
+ };
+
+ const handleContextRestored = () => {
+ gl.shadowMap.enabled = true;
+ gl.shadowMap.type = THREE.PCFShadowMap;
+ gl.shadowMap.autoUpdate = true;
+ logger.info("WebGL", "Context restored");
+ };
+
+ canvas.addEventListener("webglcontextlost", handleContextLost);
+ canvas.addEventListener("webglcontextrestored", handleContextRestored);
+ },
+ [],
+ );
+
return (