tune(debug): refine fog and debug controls
This commit is contained in:
@@ -2,7 +2,7 @@ import { TERRAIN_COLORS } from "@/data/world/terrainConfig";
|
|||||||
|
|
||||||
export const FOG_CONFIG = {
|
export const FOG_CONFIG = {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
color: "#eef3f5",
|
color: "#dce8df",
|
||||||
near: 38,
|
near: 38,
|
||||||
far: 45,
|
far: 45,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import GUI from "lil-gui";
|
import GUI from "lil-gui";
|
||||||
import type { CameraMode, SceneMode } from "@/types/debug/debug";
|
import type { CameraMode, SceneMode } from "@/types/debug/debug";
|
||||||
import type { HandTrackingSource } from "@/types/handTracking/handTracking";
|
import type { HandTrackingSource } from "@/types/handTracking/handTracking";
|
||||||
|
import { FOG_CONFIG } from "@/data/world/fogConfig";
|
||||||
import { EventEmitter } from "@/utils/core/EventEmitter";
|
import { EventEmitter } from "@/utils/core/EventEmitter";
|
||||||
import { isDebugEnabled } from "@/utils/debug/isDebugEnabled";
|
import { isDebugEnabled } from "@/utils/debug/isDebugEnabled";
|
||||||
|
|
||||||
@@ -15,6 +16,15 @@ interface DebugEvents {
|
|||||||
change: void;
|
change: void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEBUG_FOLDER_ORDER = [
|
||||||
|
"La Fabrik",
|
||||||
|
"Lighting",
|
||||||
|
"Game",
|
||||||
|
"Interaction",
|
||||||
|
"Hand Tracking",
|
||||||
|
"Performance / Map",
|
||||||
|
] as const;
|
||||||
|
|
||||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
return typeof value === "object" && value !== null;
|
return typeof value === "object" && value !== null;
|
||||||
}
|
}
|
||||||
@@ -58,6 +68,7 @@ export class Debug {
|
|||||||
private readonly folderRefCounts = new Map<string, number>();
|
private readonly folderRefCounts = new Map<string, number>();
|
||||||
private readonly controls: {
|
private readonly controls: {
|
||||||
cameraMode: CameraMode;
|
cameraMode: CameraMode;
|
||||||
|
fogEnabled: boolean;
|
||||||
handTrackingSource: HandTrackingSource;
|
handTrackingSource: HandTrackingSource;
|
||||||
showDebugOverlay: boolean;
|
showDebugOverlay: boolean;
|
||||||
showHandTrackingSvg: boolean;
|
showHandTrackingSvg: boolean;
|
||||||
@@ -80,7 +91,8 @@ export class Debug {
|
|||||||
|
|
||||||
this.controls = {
|
this.controls = {
|
||||||
cameraMode: storedControls.cameraMode ?? "player",
|
cameraMode: storedControls.cameraMode ?? "player",
|
||||||
handTrackingSource: "backend",
|
fogEnabled: FOG_CONFIG.enabled,
|
||||||
|
handTrackingSource: "browser",
|
||||||
showDebugOverlay: true,
|
showDebugOverlay: true,
|
||||||
showHandTrackingSvg: false,
|
showHandTrackingSvg: false,
|
||||||
showInteractionSpheres: false,
|
showInteractionSpheres: false,
|
||||||
@@ -88,10 +100,10 @@ export class Debug {
|
|||||||
sceneMode: storedControls.sceneMode ?? "game",
|
sceneMode: storedControls.sceneMode ?? "game",
|
||||||
};
|
};
|
||||||
|
|
||||||
this.gui = this.active ? new GUI({ title: "La-Fabrik Debug" }) : null;
|
this.gui = this.active ? new GUI({ title: "Debug" }) : null;
|
||||||
|
|
||||||
if (this.gui) {
|
if (this.gui) {
|
||||||
const folder = this.createFolder("Debug");
|
const folder = this.createFolder("La Fabrik", { open: true });
|
||||||
|
|
||||||
if (!folder) return;
|
if (!folder) return;
|
||||||
|
|
||||||
@@ -127,6 +139,14 @@ export class Debug {
|
|||||||
this.emit();
|
this.emit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
folder
|
||||||
|
.add(this.controls, "fogEnabled")
|
||||||
|
.name("Fog")
|
||||||
|
.onChange((value: boolean) => {
|
||||||
|
this.controls.fogEnabled = value;
|
||||||
|
this.emit();
|
||||||
|
});
|
||||||
|
|
||||||
const handTrackingFolder = this.createFolder("Hand Tracking");
|
const handTrackingFolder = this.createFolder("Hand Tracking");
|
||||||
|
|
||||||
handTrackingFolder
|
handTrackingFolder
|
||||||
@@ -139,8 +159,8 @@ export class Debug {
|
|||||||
|
|
||||||
handTrackingFolder
|
handTrackingFolder
|
||||||
?.add(this.controls, "handTrackingSource", {
|
?.add(this.controls, "handTrackingSource", {
|
||||||
Backend: "backend",
|
|
||||||
"Browser JS": "browser",
|
"Browser JS": "browser",
|
||||||
|
Backend: "backend",
|
||||||
})
|
})
|
||||||
.name("Source")
|
.name("Source")
|
||||||
.onChange((value: HandTrackingSource) => {
|
.onChange((value: HandTrackingSource) => {
|
||||||
@@ -154,7 +174,7 @@ export class Debug {
|
|||||||
* Acquires a named GUI folder. Returns the folder on first acquisition and null
|
* Acquires a named GUI folder. Returns the folder on first acquisition and null
|
||||||
* on subsequent acquisitions so callers only register controls once.
|
* on subsequent acquisitions so callers only register controls once.
|
||||||
*/
|
*/
|
||||||
createFolder(name: string): GUI | null {
|
createFolder(name: string, options?: { open?: boolean }): GUI | null {
|
||||||
if (!this.gui) return null;
|
if (!this.gui) return null;
|
||||||
|
|
||||||
const existing = this.folders.get(name);
|
const existing = this.folders.get(name);
|
||||||
@@ -167,6 +187,13 @@ export class Debug {
|
|||||||
const folder = this.gui.addFolder(name);
|
const folder = this.gui.addFolder(name);
|
||||||
this.folders.set(name, folder);
|
this.folders.set(name, folder);
|
||||||
this.folderRefCounts.set(name, 1);
|
this.folderRefCounts.set(name, 1);
|
||||||
|
this.sortFolders();
|
||||||
|
|
||||||
|
if (options?.open) {
|
||||||
|
folder.open();
|
||||||
|
} else {
|
||||||
|
folder.close();
|
||||||
|
}
|
||||||
|
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
@@ -206,6 +233,10 @@ export class Debug {
|
|||||||
return this.controls.handTrackingSource;
|
return this.controls.handTrackingSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFogEnabled(): boolean {
|
||||||
|
return this.controls.fogEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
getShowInteractionSpheres(): boolean {
|
getShowInteractionSpheres(): boolean {
|
||||||
return this.controls.showInteractionSpheres;
|
return this.controls.showInteractionSpheres;
|
||||||
}
|
}
|
||||||
@@ -247,4 +278,29 @@ export class Debug {
|
|||||||
|
|
||||||
this.emit();
|
this.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sortFolders(): void {
|
||||||
|
if (!this.gui) return;
|
||||||
|
|
||||||
|
const rootElement = this.gui.domElement.querySelector(".children");
|
||||||
|
if (!rootElement) return;
|
||||||
|
|
||||||
|
const orderedFolders = [...this.folders.entries()].sort(([a], [b]) => {
|
||||||
|
const aIndex = DEBUG_FOLDER_ORDER.indexOf(
|
||||||
|
a as (typeof DEBUG_FOLDER_ORDER)[number],
|
||||||
|
);
|
||||||
|
const bIndex = DEBUG_FOLDER_ORDER.indexOf(
|
||||||
|
b as (typeof DEBUG_FOLDER_ORDER)[number],
|
||||||
|
);
|
||||||
|
const safeAIndex = aIndex === -1 ? DEBUG_FOLDER_ORDER.length : aIndex;
|
||||||
|
const safeBIndex = bIndex === -1 ? DEBUG_FOLDER_ORDER.length : bIndex;
|
||||||
|
|
||||||
|
if (safeAIndex !== safeBIndex) return safeAIndex - safeBIndex;
|
||||||
|
return a.localeCompare(b);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [, folder] of orderedFolders) {
|
||||||
|
rootElement.appendChild(folder.domElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ import {
|
|||||||
useMapPerformanceStore,
|
useMapPerformanceStore,
|
||||||
} from "@/managers/stores/useMapPerformanceStore";
|
} from "@/managers/stores/useMapPerformanceStore";
|
||||||
import { SkyModel } from "@/components/three/world/SkyModel";
|
import { SkyModel } from "@/components/three/world/SkyModel";
|
||||||
|
import { useDebugStore } from "@/hooks/debug/useDebugStore";
|
||||||
|
|
||||||
export function Environment(): React.JSX.Element {
|
export function Environment(): React.JSX.Element {
|
||||||
const cameraMode = useCameraMode();
|
const cameraMode = useCameraMode();
|
||||||
const sceneMode = useSceneMode();
|
const sceneMode = useSceneMode();
|
||||||
|
const fogEnabled = useDebugStore((debug) => debug.getFogEnabled());
|
||||||
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 showSky = isMapModelVisible("sky", { groups, models });
|
const showSky = isMapModelVisible("sky", { groups, models });
|
||||||
@@ -30,7 +32,10 @@ export function Environment(): React.JSX.Element {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{FOG_CONFIG.enabled && sceneMode === "game" && cameraMode === "player" ? (
|
{FOG_CONFIG.enabled &&
|
||||||
|
fogEnabled &&
|
||||||
|
sceneMode === "game" &&
|
||||||
|
cameraMode === "player" ? (
|
||||||
<fog
|
<fog
|
||||||
attach="fog"
|
attach="fog"
|
||||||
args={[FOG_CONFIG.color, FOG_CONFIG.near, FOG_CONFIG.far]}
|
args={[FOG_CONFIG.color, FOG_CONFIG.near, FOG_CONFIG.far]}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const VEGETATION_TYPES = {
|
|||||||
sapin: {
|
sapin: {
|
||||||
mapName: "sapin",
|
mapName: "sapin",
|
||||||
modelPath: "/models/sapin/model.gltf",
|
modelPath: "/models/sapin/model.gltf",
|
||||||
scaleMultiplier: 2,
|
scaleMultiplier: 5,
|
||||||
castShadow: true,
|
castShadow: true,
|
||||||
receiveShadow: true,
|
receiveShadow: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user