refactor: split hooks types and utils by domain
This commit is contained in:
@@ -25,7 +25,7 @@ This document describes the code that exists today in the repository.
|
|||||||
- `src/components/three/interaction/InteractableObject.tsx` handles focus detection through distance and raycasting.
|
- `src/components/three/interaction/InteractableObject.tsx` handles focus detection through distance and raycasting.
|
||||||
- `src/components/three/interaction/TriggerObject.tsx` implements trigger-style interactions.
|
- `src/components/three/interaction/TriggerObject.tsx` implements trigger-style interactions.
|
||||||
- `src/components/three/interaction/GrabbableObject.tsx` implements hold-and-release interactions.
|
- `src/components/three/interaction/GrabbableObject.tsx` implements hold-and-release interactions.
|
||||||
- `src/hooks/useInteraction.ts` exposes the interaction snapshot to React UI.
|
- `src/hooks/interaction/useInteraction.ts` exposes the interaction snapshot to React UI.
|
||||||
- `src/components/ui/InteractPrompt.tsx` shows the `E` prompt for trigger interactions.
|
- `src/components/ui/InteractPrompt.tsx` shows the `E` prompt for trigger interactions.
|
||||||
|
|
||||||
## Audio
|
## Audio
|
||||||
@@ -59,8 +59,8 @@ This document describes the code that exists today in the repository.
|
|||||||
- `src/hooks/editor/useEditorSceneData.ts` loads scene data and handles folder upload fallback.
|
- `src/hooks/editor/useEditorSceneData.ts` loads scene data and handles folder upload fallback.
|
||||||
- `src/hooks/editor/useEditorHistory.ts` owns editor undo and redo state.
|
- `src/hooks/editor/useEditorHistory.ts` owns editor undo and redo state.
|
||||||
- `src/utils/editor/loadEditorScene.ts` handles editor-only folder upload parsing.
|
- `src/utils/editor/loadEditorScene.ts` handles editor-only folder upload parsing.
|
||||||
- `src/utils/loadMapSceneData.ts` is shared by the game scene and editor to load `public/map.json` and resolve model URLs.
|
- `src/utils/map/loadMapSceneData.ts` is shared by the game scene and editor to load `public/map.json` and resolve model URLs.
|
||||||
- `src/types/editor.ts` contains the shared `MapNode`, `SceneData`, and `TransformMode` types.
|
- `src/types/editor/editor.ts` contains the shared `MapNode`, `SceneData`, and `TransformMode` types.
|
||||||
|
|
||||||
## Map Data
|
## Map Data
|
||||||
|
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ src/
|
|||||||
|
|
||||||
`src/controls/editor/FlyController.tsx` provides editor movement controls for player-style navigation.
|
`src/controls/editor/FlyController.tsx` provides editor movement controls for player-style navigation.
|
||||||
|
|
||||||
`src/utils/loadMapSceneData.ts` is shared by the game map and editor. It loads `/map.json` and resolves available `public/models/{name}/model.glb` files first, then falls back to `public/models/{name}/model.gltf`.
|
`src/utils/map/loadMapSceneData.ts` is shared by the game map and editor. It loads `/map.json` and resolves available `public/models/{name}/model.glb` files first, then falls back to `public/models/{name}/model.gltf`.
|
||||||
|
|
||||||
`src/utils/editor/loadEditorScene.ts` contains editor-only upload handling for user-selected folders.
|
`src/utils/editor/loadEditorScene.ts` contains editor-only upload handling for user-selected folders.
|
||||||
|
|
||||||
## Data Format
|
## Data Format
|
||||||
|
|
||||||
The shared editor type lives in `src/types/editor.ts`.
|
The shared editor type lives in `src/types/editor/editor.ts`.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
interface MapNode {
|
interface MapNode {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ The feature is currently scoped to the debug physics scene and is not yet a prod
|
|||||||
|
|
||||||
## Runtime Flow
|
## Runtime Flow
|
||||||
|
|
||||||
1. The browser captures webcam frames in `src/hooks/useRemoteHandTracking.ts`.
|
1. The browser captures webcam frames in `src/hooks/handTracking/useRemoteHandTracking.ts`.
|
||||||
2. Frames are sent to the local Python backend over WebSocket.
|
2. Frames are sent to the local Python backend over WebSocket.
|
||||||
3. The backend runs MediaPipe hand landmark detection.
|
3. The backend runs MediaPipe hand landmark detection.
|
||||||
4. The backend returns hand data including landmarks, handedness, score, center point, and `isFist`.
|
4. The backend returns hand data including landmarks, handedness, score, center point, and `isFist`.
|
||||||
@@ -46,7 +46,7 @@ The backend sends normalized hand coordinates and landmarks. The frontend treats
|
|||||||
|
|
||||||
## Frontend Data Shape
|
## Frontend Data Shape
|
||||||
|
|
||||||
The shared types live in `src/types/handTracking.ts`.
|
The shared types live in `src/types/handTracking/handTracking.ts`.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
interface HandTrackingHand {
|
interface HandTrackingHand {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
PLAYER_EYE_HEIGHT,
|
PLAYER_EYE_HEIGHT,
|
||||||
PLAYER_SPAWN_POSITION_GAME,
|
PLAYER_SPAWN_POSITION_GAME,
|
||||||
} from "@/data/player/playerConfig";
|
} from "@/data/player/playerConfig";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
const DEBUG_CAMERA_TARGET: Vector3Tuple = [
|
const DEBUG_CAMERA_TARGET: Vector3Tuple = [
|
||||||
PLAYER_SPAWN_POSITION_GAME[0],
|
PLAYER_SPAWN_POSITION_GAME[0],
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
Save,
|
Save,
|
||||||
Undo2,
|
Undo2,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import type { MapNode, TransformMode } from "@/types/editor";
|
import type { MapNode, TransformMode } from "@/types/editor/editor";
|
||||||
|
|
||||||
interface EditorControlsProps {
|
interface EditorControlsProps {
|
||||||
transformMode: TransformMode;
|
transformMode: TransformMode;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Grid, TransformControls, useGLTF } from "@react-three/drei";
|
|||||||
import type { ThreeEvent } from "@react-three/fiber";
|
import type { ThreeEvent } from "@react-three/fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
|
|
||||||
import type { SceneData, MapNode, TransformMode } from "@/types/editor";
|
import type { SceneData, MapNode, TransformMode } from "@/types/editor/editor";
|
||||||
|
|
||||||
interface EditorMapProps {
|
interface EditorMapProps {
|
||||||
sceneData: SceneData;
|
sceneData: SceneData;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useEffect } from "react";
|
|||||||
import { OrbitControls } from "@react-three/drei";
|
import { OrbitControls } from "@react-three/drei";
|
||||||
import { EditorMap } from "@/components/editor/scene/EditorMap";
|
import { EditorMap } from "@/components/editor/scene/EditorMap";
|
||||||
import { FlyController } from "@/controls/editor/FlyController";
|
import { FlyController } from "@/controls/editor/FlyController";
|
||||||
import type { MapNode, TransformMode, SceneData } from "@/types/editor";
|
import type { MapNode, TransformMode, SceneData } from "@/types/editor/editor";
|
||||||
|
|
||||||
interface EditorSceneProps {
|
interface EditorSceneProps {
|
||||||
sceneData: SceneData;
|
sceneData: SceneData;
|
||||||
|
|||||||
+2
-2
@@ -14,8 +14,8 @@ import {
|
|||||||
REPAIR_CASE_OPEN_ROTATION_OFFSET_DEGREES,
|
REPAIR_CASE_OPEN_ROTATION_OFFSET_DEGREES,
|
||||||
REPAIR_CASE_ROTATION_AMPLITUDE_DEGREES,
|
REPAIR_CASE_ROTATION_AMPLITUDE_DEGREES,
|
||||||
REPAIR_CASE_ROTATION_RESET_SPEED,
|
REPAIR_CASE_ROTATION_RESET_SPEED,
|
||||||
} from "@/data/repairGame/repairCaseConfig";
|
} from "@/data/gameplay/repairCaseConfig";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
interface RepairCaseModelProps {
|
interface RepairCaseModelProps {
|
||||||
modelPath: string;
|
modelPath: string;
|
||||||
+3
-3
@@ -1,12 +1,12 @@
|
|||||||
import { TriggerObject } from "@/components/three/interaction/TriggerObject";
|
import { TriggerObject } from "@/components/three/interaction/TriggerObject";
|
||||||
import { RepairCaseModel } from "@/components/three/gameplay/repairGame/RepairCaseModel";
|
import { RepairCaseModel } from "@/components/three/gameplay/RepairCaseModel";
|
||||||
import {
|
import {
|
||||||
REPAIR_CASE_CLOSE_SOUND_PATH,
|
REPAIR_CASE_CLOSE_SOUND_PATH,
|
||||||
REPAIR_CASE_MODEL_PATH,
|
REPAIR_CASE_MODEL_PATH,
|
||||||
REPAIR_CASE_OPEN_SOUND_PATH,
|
REPAIR_CASE_OPEN_SOUND_PATH,
|
||||||
} from "@/data/repairGame/repairCaseConfig";
|
} from "@/data/gameplay/repairCaseConfig";
|
||||||
import { AudioManager } from "@/managers/AudioManager";
|
import { AudioManager } from "@/managers/AudioManager";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
interface RepairCaseObjectProps {
|
interface RepairCaseObjectProps {
|
||||||
position: Vector3Tuple;
|
position: Vector3Tuple;
|
||||||
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Text } from "@react-three/drei";
|
import { Text } from "@react-three/drei";
|
||||||
import { RepairCaseObject } from "@/components/three/gameplay/repairGame/RepairCaseObject";
|
import { RepairCaseObject } from "@/components/three/gameplay/RepairCaseObject";
|
||||||
import { RepairModuleSlot } from "@/components/three/gameplay/repairGame/RepairModuleSlot";
|
import { RepairModuleSlot } from "@/components/three/gameplay/RepairModuleSlot";
|
||||||
import {
|
import {
|
||||||
REPAIR_GAME_MODULE_SLOTS,
|
REPAIR_GAME_MODULE_SLOTS,
|
||||||
REPAIR_GAME_ZONE_LABEL,
|
REPAIR_GAME_ZONE_LABEL,
|
||||||
REPAIR_GAME_ZONE_ORIGIN,
|
REPAIR_GAME_ZONE_ORIGIN,
|
||||||
REPAIR_GAME_ZONE_RADIUS,
|
REPAIR_GAME_ZONE_RADIUS,
|
||||||
} from "@/data/repairGame/repairGameConfig";
|
} from "@/data/gameplay/repairGameConfig";
|
||||||
|
|
||||||
export function RepairGameZone(): React.JSX.Element {
|
export function RepairGameZone(): React.JSX.Element {
|
||||||
const [caseOpen, setCaseOpen] = useState(false);
|
const [caseOpen, setCaseOpen] = useState(false);
|
||||||
+4
-4
@@ -2,10 +2,10 @@ import { Html } from "@react-three/drei";
|
|||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { TriggerObject } from "@/components/three/interaction/TriggerObject";
|
import { TriggerObject } from "@/components/three/interaction/TriggerObject";
|
||||||
import { ExplodableModel } from "@/components/three/models/ExplodableModel";
|
import { ExplodableModel } from "@/components/three/models/ExplodableModel";
|
||||||
import { REPAIR_GAME_MODEL_CATALOG } from "@/data/repairGame/repairGameModelCatalog";
|
import { REPAIR_GAME_MODEL_CATALOG } from "@/data/gameplay/repairGameModelCatalog";
|
||||||
import type { ModelCatalogItem } from "@/data/repairGame/repairGameModelCatalog";
|
import type { ModelCatalogItem } from "@/data/gameplay/repairGameModelCatalog";
|
||||||
import { useModelSelection } from "@/hooks/useModelSelection";
|
import { useModelSelection } from "@/hooks/gameplay/useModelSelection";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
interface RepairModuleSlotProps {
|
interface RepairModuleSlotProps {
|
||||||
position: Vector3Tuple;
|
position: Vector3Tuple;
|
||||||
@@ -22,13 +22,13 @@ import {
|
|||||||
} from "@/data/interaction/grabConfig";
|
} from "@/data/interaction/grabConfig";
|
||||||
import { INTERACTION_RADIUS } from "@/data/interaction/interactionConfig";
|
import { INTERACTION_RADIUS } from "@/data/interaction/interactionConfig";
|
||||||
import { useDebugFolder } from "@/hooks/debug/useDebugFolder";
|
import { useDebugFolder } from "@/hooks/debug/useDebugFolder";
|
||||||
import { useHandTrackingSnapshot } from "@/hooks/useHandTrackingSnapshot";
|
import { useHandTrackingSnapshot } from "@/hooks/handTracking/useHandTrackingSnapshot";
|
||||||
import { InteractionManager } from "@/managers/InteractionManager";
|
import { InteractionManager } from "@/managers/InteractionManager";
|
||||||
import type {
|
import type {
|
||||||
HandTrackingHand,
|
HandTrackingHand,
|
||||||
HandTrackingLandmark,
|
HandTrackingLandmark,
|
||||||
} from "@/types/handTracking";
|
} from "@/types/handTracking/handTracking";
|
||||||
import type { ColliderShape, Vector3Tuple } from "@/types/three";
|
import type { ColliderShape, Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
interface GrabbableObjectProps {
|
interface GrabbableObjectProps {
|
||||||
position: Vector3Tuple;
|
position: Vector3Tuple;
|
||||||
@@ -38,7 +38,6 @@ interface GrabbableObjectProps {
|
|||||||
handControlled?: boolean;
|
handControlled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shared params let one debug folder drive every instance.
|
|
||||||
const grabDebugParams = {
|
const grabDebugParams = {
|
||||||
stiffness: GRAB_STIFFNESS_DEFAULT,
|
stiffness: GRAB_STIFFNESS_DEFAULT,
|
||||||
throwBoost: GRAB_THROW_BOOST_DEFAULT,
|
throwBoost: GRAB_THROW_BOOST_DEFAULT,
|
||||||
@@ -74,10 +73,10 @@ function getHandCenterPoint(hand: HandTrackingHand): HandTrackingLandmark {
|
|||||||
return { x: hand.x, y: hand.y, z: hand.z };
|
return { x: hand.x, y: hand.y, z: hand.z };
|
||||||
}
|
}
|
||||||
|
|
||||||
let minX = landmarks[0].x;
|
let minX = landmarks[0]!.x;
|
||||||
let maxX = landmarks[0].x;
|
let maxX = landmarks[0]!.x;
|
||||||
let minY = landmarks[0].y;
|
let minY = landmarks[0]!.y;
|
||||||
let maxY = landmarks[0].y;
|
let maxY = landmarks[0]!.y;
|
||||||
|
|
||||||
landmarks.forEach((landmark) => {
|
landmarks.forEach((landmark) => {
|
||||||
minX = Math.min(minX, landmark.x);
|
minX = Math.min(minX, landmark.x);
|
||||||
@@ -112,7 +111,7 @@ function getHandHit(
|
|||||||
_handRaycaster.far = INTERACTION_RADIUS;
|
_handRaycaster.far = INTERACTION_RADIUS;
|
||||||
|
|
||||||
const hits = _handRaycaster.intersectObject(group, true);
|
const hits = _handRaycaster.intersectObject(group, true);
|
||||||
if (hits.length > 0) return hits[0];
|
if (hits?.length > 0) return hits[0] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import { Debug } from "@/utils/debug/Debug";
|
|||||||
import { useDebugFolder } from "@/hooks/debug/useDebugFolder";
|
import { useDebugFolder } from "@/hooks/debug/useDebugFolder";
|
||||||
import { InteractionManager } from "@/managers/InteractionManager";
|
import { InteractionManager } from "@/managers/InteractionManager";
|
||||||
import { INTERACTION_RADIUS } from "@/data/interaction/interactionConfig";
|
import { INTERACTION_RADIUS } from "@/data/interaction/interactionConfig";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { InteractableHandle } from "@/types/interaction/interaction";
|
||||||
import type { InteractableHandle } from "@/types/interaction";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
interface InteractableObjectBaseProps {
|
interface InteractableObjectBaseProps {
|
||||||
label: string;
|
label: string;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
TRIGGER_DEFAULT_SPAWN_OFFSET,
|
TRIGGER_DEFAULT_SPAWN_OFFSET,
|
||||||
} from "@/data/interaction/triggerConfig";
|
} from "@/data/interaction/triggerConfig";
|
||||||
import { AudioManager } from "@/managers/AudioManager";
|
import { AudioManager } from "@/managers/AudioManager";
|
||||||
import type { ColliderShape, Vector3Tuple } from "@/types/three";
|
import type { ColliderShape, Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
interface SpawnedModel {
|
interface SpawnedModel {
|
||||||
id: number;
|
id: number;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
AnimatedModelContext,
|
AnimatedModelContext,
|
||||||
type AnimatedModelContextValue,
|
type AnimatedModelContextValue,
|
||||||
} from "@/components/three/models/useAnimatedModel";
|
} from "@/components/three/models/useAnimatedModel";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
export interface AnimatedModelConfig {
|
export interface AnimatedModelConfig {
|
||||||
modelPath: string;
|
modelPath: string;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import type { ReactNode } from "react";
|
|||||||
import { Component, useEffect, useMemo } from "react";
|
import { Component, useEffect, useMemo } from "react";
|
||||||
import { useFrame } from "@react-three/fiber";
|
import { useFrame } from "@react-three/fiber";
|
||||||
import { useGLTF } from "@react-three/drei";
|
import { useGLTF } from "@react-three/drei";
|
||||||
import { ExplodedModel } from "@/utils/ExplodedModel";
|
import { ExplodedModel } from "@/utils/three/ExplodedModel";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
interface ModelErrorBoundaryProps {
|
interface ModelErrorBoundaryProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@@ -52,7 +52,7 @@ export function ExplodableModel(
|
|||||||
return (
|
return (
|
||||||
<ModelErrorBoundary
|
<ModelErrorBoundary
|
||||||
key={props.modelPath}
|
key={props.modelPath}
|
||||||
fallback={<MissingModelFallback position={props.position} />}
|
fallback={<MissingModelFallback position={props.position ?? [0, 0, 0]} />}
|
||||||
>
|
>
|
||||||
<ExplodableModelInner {...props} />
|
<ExplodableModelInner {...props} />
|
||||||
</ModelErrorBoundary>
|
</ModelErrorBoundary>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { useGLTF } from "@react-three/drei";
|
import { useGLTF } from "@react-three/drei";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
export interface SimpleModelConfig {
|
export interface SimpleModelConfig {
|
||||||
modelPath: string;
|
modelPath: string;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCameraMode } from "@/hooks/debug/useCameraMode";
|
import { useCameraMode } from "@/hooks/debug/useCameraMode";
|
||||||
import { useInteraction } from "@/hooks/useInteraction";
|
import { useInteraction } from "@/hooks/interaction/useInteraction";
|
||||||
|
|
||||||
export function Crosshair(): React.JSX.Element | null {
|
export function Crosshair(): React.JSX.Element | null {
|
||||||
const cameraMode = useCameraMode();
|
const cameraMode = useCameraMode();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useHandTrackingSnapshot } from "@/hooks/useHandTrackingSnapshot";
|
import { useHandTrackingSnapshot } from "@/hooks/handTracking/useHandTrackingSnapshot";
|
||||||
import type { HandTrackingStatus } from "@/types/handTracking";
|
import type { HandTrackingStatus } from "@/types/handTracking/handTracking";
|
||||||
|
|
||||||
const STATUS_LABELS: Record<HandTrackingStatus, string> = {
|
const STATUS_LABELS: Record<HandTrackingStatus, string> = {
|
||||||
idle: "Idle",
|
idle: "Idle",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useHandTrackingSnapshot } from "@/hooks/useHandTrackingSnapshot";
|
import { useHandTrackingSnapshot } from "@/hooks/handTracking/useHandTrackingSnapshot";
|
||||||
|
|
||||||
const HAND_CONNECTIONS: Array<[number, number]> = [
|
const HAND_CONNECTIONS: Array<[number, number]> = [
|
||||||
[0, 1],
|
[0, 1],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { INTERACT_KEY } from "@/data/input/keybindings";
|
import { INTERACT_KEY } from "@/data/input/keybindings";
|
||||||
import { useCameraMode } from "@/hooks/debug/useCameraMode";
|
import { useCameraMode } from "@/hooks/debug/useCameraMode";
|
||||||
import { useInteraction } from "@/hooks/useInteraction";
|
import { useInteraction } from "@/hooks/interaction/useInteraction";
|
||||||
|
|
||||||
export function InteractPrompt(): React.JSX.Element | null {
|
export function InteractPrompt(): React.JSX.Element | null {
|
||||||
const cameraMode = useCameraMode();
|
const cameraMode = useCameraMode();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
export const TEST_SCENE_FLOOR_POSITION: Vector3Tuple = [0, -0.5, 0];
|
export const TEST_SCENE_FLOOR_POSITION: Vector3Tuple = [0, -0.5, 0];
|
||||||
export const TEST_SCENE_FLOOR_SIZE: Vector3Tuple = [200, 1, 200];
|
export const TEST_SCENE_FLOOR_SIZE: Vector3Tuple = [200, 1, 200];
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ Ce document décrit le code réellement présent aujourd'hui dans le dépôt.
|
|||||||
- \`src/components/three/interaction/InteractableObject.tsx\` gère la détection de focus par distance et raycasting.
|
- \`src/components/three/interaction/InteractableObject.tsx\` gère la détection de focus par distance et raycasting.
|
||||||
- \`src/components/three/interaction/TriggerObject.tsx\` implémente les interactions de type trigger.
|
- \`src/components/three/interaction/TriggerObject.tsx\` implémente les interactions de type trigger.
|
||||||
- \`src/components/three/interaction/GrabbableObject.tsx\` implémente les interactions saisir / relâcher.
|
- \`src/components/three/interaction/GrabbableObject.tsx\` implémente les interactions saisir / relâcher.
|
||||||
- \`src/hooks/useInteraction.ts\` expose un snapshot d'interaction à l'UI React.
|
- \`src/hooks/interaction/useInteraction.ts\` expose un snapshot d'interaction à l'UI React.
|
||||||
- \`src/components/ui/InteractPrompt.tsx\` affiche le prompt \`E\` pour les interactions trigger.
|
- \`src/components/ui/InteractPrompt.tsx\` affiche le prompt \`E\` pour les interactions trigger.
|
||||||
|
|
||||||
## Audio
|
## Audio
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
export const REPAIR_GAME_ZONE_ORIGIN: Vector3Tuple = [10, 0.4, -8];
|
export const REPAIR_GAME_ZONE_ORIGIN: Vector3Tuple = [10, 0.4, -8];
|
||||||
export const REPAIR_GAME_ZONE_RADIUS = 4.2;
|
export const REPAIR_GAME_ZONE_RADIUS = 4.2;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
export const TRIGGER_DEFAULT_COLLIDERS = "ball";
|
export const TRIGGER_DEFAULT_COLLIDERS = "ball";
|
||||||
export const TRIGGER_DEFAULT_LABEL = "Interagir";
|
export const TRIGGER_DEFAULT_LABEL = "Interagir";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
export const PLAYER_EYE_HEIGHT = 1.75;
|
export const PLAYER_EYE_HEIGHT = 1.75;
|
||||||
export const PLAYER_CAPSULE_RADIUS = 0.35;
|
export const PLAYER_CAPSULE_RADIUS = 0.35;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { CameraMode } from "@/types/debug";
|
import type { CameraMode } from "@/types/debug/debug";
|
||||||
import { useDebugStore } from "@/hooks/debug/useDebugStore";
|
import { useDebugStore } from "@/hooks/debug/useDebugStore";
|
||||||
|
|
||||||
export function useCameraMode(): CameraMode {
|
export function useCameraMode(): CameraMode {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { SceneMode } from "@/types/debug";
|
import type { SceneMode } from "@/types/debug/debug";
|
||||||
import { useDebugStore } from "@/hooks/debug/useDebugStore";
|
import { useDebugStore } from "@/hooks/debug/useDebugStore";
|
||||||
|
|
||||||
export function useSceneMode(): SceneMode {
|
export function useSceneMode(): SceneMode {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useRef, useState } from "react";
|
import { useCallback, useRef, useState } from "react";
|
||||||
import type { MapNode, SceneData } from "@/types/editor";
|
import type { MapNode, SceneData } from "@/types/editor/editor";
|
||||||
|
|
||||||
interface ObjectTransform {
|
interface ObjectTransform {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { createSceneDataFromFiles } from "@/utils/editor/loadEditorScene";
|
import { createSceneDataFromFiles } from "@/utils/editor/loadEditorScene";
|
||||||
import { loadMapSceneData } from "@/utils/loadMapSceneData";
|
import { loadMapSceneData } from "@/utils/map/loadMapSceneData";
|
||||||
import type { SceneData } from "@/types/editor";
|
import type { SceneData } from "@/types/editor/editor";
|
||||||
|
|
||||||
interface UseEditorSceneDataResult {
|
interface UseEditorSceneDataResult {
|
||||||
hasMapJson: boolean;
|
hasMapJson: boolean;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import type { ModelCatalogItem } from "@/data/repairGame/repairGameModelCatalog";
|
import type { ModelCatalogItem } from "@/data/gameplay/repairGameModelCatalog";
|
||||||
|
|
||||||
interface UseModelSelectionResult {
|
interface UseModelSelectionResult {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { createContext, useContext } from "react";
|
import { createContext, useContext } from "react";
|
||||||
import type { HandTrackingSnapshot } from "@/types/handTracking";
|
import type { HandTrackingSnapshot } from "@/types/handTracking/handTracking";
|
||||||
|
|
||||||
export const HAND_TRACKING_IDLE_SNAPSHOT: HandTrackingSnapshot = {
|
export const HAND_TRACKING_IDLE_SNAPSHOT: HandTrackingSnapshot = {
|
||||||
hands: [],
|
hands: [],
|
||||||
+1
-1
@@ -12,7 +12,7 @@ import type {
|
|||||||
HandTrackingFrameMessage,
|
HandTrackingFrameMessage,
|
||||||
HandTrackingServerMessage,
|
HandTrackingServerMessage,
|
||||||
HandTrackingSnapshot,
|
HandTrackingSnapshot,
|
||||||
} from "@/types/handTracking";
|
} from "@/types/handTracking/handTracking";
|
||||||
|
|
||||||
interface UseRemoteHandTrackingOptions {
|
interface UseRemoteHandTrackingOptions {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useSyncExternalStore } from "react";
|
import { useSyncExternalStore } from "react";
|
||||||
import { InteractionManager } from "@/managers/InteractionManager";
|
import { InteractionManager } from "@/managers/InteractionManager";
|
||||||
import type { InteractionSnapshot } from "@/types/interaction";
|
import type { InteractionSnapshot } from "@/types/interaction/interaction";
|
||||||
|
|
||||||
const manager = InteractionManager.getInstance();
|
const manager = InteractionManager.getInstance();
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@ import { useEffect, useRef } from "react";
|
|||||||
import type { RefObject } from "react";
|
import type { RefObject } from "react";
|
||||||
import type { Object3D } from "three";
|
import type { Object3D } from "three";
|
||||||
import { Octree } from "three/addons/math/Octree.js";
|
import { Octree } from "three/addons/math/Octree.js";
|
||||||
import type { OctreeReadyHandler } from "@/types/three";
|
import type { OctreeReadyHandler } from "@/types/three/three";
|
||||||
|
|
||||||
export function useOctreeGraphNode(
|
export function useOctreeGraphNode(
|
||||||
graphNodeRef: RefObject<Object3D | null>,
|
graphNodeRef: RefObject<Object3D | null>,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { logger } from "@/utils/logger";
|
import { logger } from "@/utils/core/logger";
|
||||||
|
|
||||||
interface PlaySoundOptions {
|
interface PlaySoundOptions {
|
||||||
playbackRate?: number;
|
playbackRate?: number;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import type {
|
|||||||
GrabInteractableHandle,
|
GrabInteractableHandle,
|
||||||
InteractableHandle,
|
InteractableHandle,
|
||||||
InteractionSnapshot,
|
InteractionSnapshot,
|
||||||
} from "@/types/interaction";
|
} from "@/types/interaction/interaction";
|
||||||
|
|
||||||
export class InteractionManager {
|
export class InteractionManager {
|
||||||
private static _instance: InteractionManager | null = null;
|
private static _instance: InteractionManager | null = null;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { EditorControls } from "@/components/editor/EditorControls";
|
|||||||
import { EditorScene } from "@/components/editor/scene/EditorScene";
|
import { EditorScene } from "@/components/editor/scene/EditorScene";
|
||||||
import { useEditorHistory } from "@/hooks/editor/useEditorHistory";
|
import { useEditorHistory } from "@/hooks/editor/useEditorHistory";
|
||||||
import { useEditorSceneData } from "@/hooks/editor/useEditorSceneData";
|
import { useEditorSceneData } from "@/hooks/editor/useEditorSceneData";
|
||||||
import type { MapNode, SceneData, TransformMode } from "@/types/editor";
|
import type { MapNode, SceneData, TransformMode } from "@/types/editor/editor";
|
||||||
|
|
||||||
const SAVE_ERROR_MESSAGE = "Erreur lors de l'enregistrement";
|
const SAVE_ERROR_MESSAGE = "Erreur lors de l'enregistrement";
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ import { Suspense } from "react";
|
|||||||
import { Canvas } from "@react-three/fiber";
|
import { Canvas } from "@react-three/fiber";
|
||||||
import { Crosshair } from "@/components/ui/Crosshair";
|
import { Crosshair } from "@/components/ui/Crosshair";
|
||||||
import { HandTrackingOverlay } from "@/components/ui/HandTrackingOverlay";
|
import { HandTrackingOverlay } from "@/components/ui/HandTrackingOverlay";
|
||||||
import { HandTrackingProvider } from "@/components/ui/HandTrackingProvider";
|
import { HandTrackingProvider } from "@/providers/gameplay/HandTrackingProvider";
|
||||||
import { HandTrackingVisualizer } from "@/components/ui/HandTrackingVisualizer";
|
import { HandTrackingVisualizer } from "@/components/ui/HandTrackingVisualizer";
|
||||||
import { InteractPrompt } from "@/components/ui/InteractPrompt";
|
import { InteractPrompt } from "@/components/ui/InteractPrompt";
|
||||||
import { DebugPerf } from "@/components/debug/DebugPerf";
|
import { DebugPerf } from "@/components/debug/DebugPerf";
|
||||||
|
|||||||
+3
-3
@@ -1,11 +1,11 @@
|
|||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useSceneMode } from "@/hooks/debug/useSceneMode";
|
import { useSceneMode } from "@/hooks/debug/useSceneMode";
|
||||||
import { useInteraction } from "@/hooks/useInteraction";
|
import { useInteraction } from "@/hooks/interaction/useInteraction";
|
||||||
import {
|
import {
|
||||||
HAND_TRACKING_IDLE_SNAPSHOT,
|
HAND_TRACKING_IDLE_SNAPSHOT,
|
||||||
HandTrackingContext,
|
HandTrackingContext,
|
||||||
} from "@/hooks/useHandTrackingSnapshot";
|
} from "@/hooks/handTracking/useHandTrackingSnapshot";
|
||||||
import { useRemoteHandTracking } from "@/hooks/useRemoteHandTracking";
|
import { useRemoteHandTracking } from "@/hooks/handTracking/useRemoteHandTracking";
|
||||||
|
|
||||||
export function HandTrackingProvider({
|
export function HandTrackingProvider({
|
||||||
children,
|
children,
|
||||||
+1
-1
@@ -17,7 +17,7 @@ import {
|
|||||||
DocsReadmeRoute,
|
DocsReadmeRoute,
|
||||||
DocsTargetArchitectureRoute,
|
DocsTargetArchitectureRoute,
|
||||||
DocsTechnicalEditorRoute,
|
DocsTechnicalEditorRoute,
|
||||||
} from "@/routes/docs/DocsRouteComponents";
|
} from "@/routes/DocsRoute";
|
||||||
|
|
||||||
const rootRoute = createRootRoute({
|
const rootRoute = createRootRoute({
|
||||||
component: Outlet,
|
component: Outlet,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Vector3Tuple } from "./three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
export interface MapNode {
|
export interface MapNode {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -3,7 +3,7 @@ import type {
|
|||||||
LogEntry,
|
LogEntry,
|
||||||
LogLevel,
|
LogLevel,
|
||||||
LoggerConfig,
|
LoggerConfig,
|
||||||
} from "@/types/logger";
|
} from "@/types/logger/logger";
|
||||||
import { isDebugEnabled } from "@/utils/debug/isDebugEnabled";
|
import { isDebugEnabled } from "@/utils/debug/isDebugEnabled";
|
||||||
|
|
||||||
const LEVEL_PRIORITY: Record<LogLevel, number> = {
|
const LEVEL_PRIORITY: Record<LogLevel, number> = {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import GUI from "lil-gui";
|
import GUI from "lil-gui";
|
||||||
import type { CameraMode, SceneMode } from "@/types/debug";
|
import type { CameraMode, SceneMode } from "@/types/debug/debug";
|
||||||
import { isDebugEnabled } from "@/utils/debug/isDebugEnabled";
|
import { isDebugEnabled } from "@/utils/debug/isDebugEnabled";
|
||||||
|
|
||||||
const DEBUG_CONTROLS_STORAGE_KEY = "la-fabrik-debug-controls";
|
const DEBUG_CONTROLS_STORAGE_KEY = "la-fabrik-debug-controls";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { SceneData } from "@/types/editor";
|
import type { SceneData } from "@/types/editor/editor";
|
||||||
import { parseMapNodes } from "@/utils/mapNodeValidation";
|
import { parseMapNodes } from "@/utils/map/mapNodeValidation";
|
||||||
|
|
||||||
const MAP_JSON_PATH = "/map.json";
|
const MAP_JSON_PATH = "/map.json";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { MapNode, SceneData } from "@/types/editor";
|
import type { MapNode, SceneData } from "@/types/editor/editor";
|
||||||
import { parseMapNodes } from "@/utils/mapNodeValidation";
|
import { parseMapNodes } from "@/utils/map/mapNodeValidation";
|
||||||
|
|
||||||
const MAP_JSON_PATH = "/map.json";
|
const MAP_JSON_PATH = "/map.json";
|
||||||
const MODEL_FILE_NAMES = ["model.glb", "model.gltf"];
|
const MODEL_FILE_NAMES = ["model.glb", "model.gltf"];
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { MapNode } from "../types/editor";
|
import type { MapNode } from "@/types/editor/editor";
|
||||||
|
|
||||||
function isVector3Tuple(value: unknown): value is [number, number, number] {
|
function isVector3Tuple(value: unknown): value is [number, number, number] {
|
||||||
return (
|
return (
|
||||||
@@ -2,10 +2,10 @@ import type { ReactNode } from "react";
|
|||||||
import { Component, useEffect, useMemo, useRef, useState } from "react";
|
import { Component, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { useGLTF } from "@react-three/drei";
|
import { useGLTF } from "@react-three/drei";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useOctreeGraphNode } from "@/hooks/useOctreeGraphNode";
|
import { useOctreeGraphNode } from "@/hooks/three/useOctreeGraphNode";
|
||||||
import { loadMapSceneData } from "@/utils/loadMapSceneData";
|
import { loadMapSceneData } from "@/utils/map/loadMapSceneData";
|
||||||
import type { OctreeReadyHandler } from "@/types/three";
|
import type { MapNode } from "@/types/editor/editor";
|
||||||
import type { MapNode } from "@/types/editor";
|
import type { OctreeReadyHandler } from "@/types/three/three";
|
||||||
|
|
||||||
interface LoadedMapNode {
|
interface LoadedMapNode {
|
||||||
node: MapNode;
|
node: MapNode;
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ import {
|
|||||||
TEST_SCENE_TRIGGER_SEGMENTS,
|
TEST_SCENE_TRIGGER_SEGMENTS,
|
||||||
TEST_SCENE_TRIGGER_SOUND_PATH,
|
TEST_SCENE_TRIGGER_SOUND_PATH,
|
||||||
} from "@/data/debug/testSceneConfig";
|
} from "@/data/debug/testSceneConfig";
|
||||||
import { useOctreeGraphNode } from "@/hooks/useOctreeGraphNode";
|
import { useOctreeGraphNode } from "@/hooks/three/useOctreeGraphNode";
|
||||||
import type { OctreeReadyHandler } from "@/types/three";
|
import type { OctreeReadyHandler } from "@/types/three/three";
|
||||||
|
|
||||||
interface TestMapProps {
|
interface TestMapProps {
|
||||||
onOctreeReady: OctreeReadyHandler;
|
onOctreeReady: OctreeReadyHandler;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useThree } from "@react-three/fiber";
|
import { useThree } from "@react-three/fiber";
|
||||||
import type { Octree } from "three/addons/math/Octree.js";
|
import type { Octree } from "three/addons/math/Octree.js";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
import { PlayerCamera } from "@/world/player/PlayerCamera";
|
import { PlayerCamera } from "@/world/player/PlayerCamera";
|
||||||
import { PlayerController } from "@/world/player/PlayerController";
|
import { PlayerController } from "@/world/player/PlayerController";
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import {
|
|||||||
PLAYER_XZ_DAMPING_FACTOR,
|
PLAYER_XZ_DAMPING_FACTOR,
|
||||||
} from "@/data/player/playerConfig";
|
} from "@/data/player/playerConfig";
|
||||||
import { InteractionManager } from "@/managers/InteractionManager";
|
import { InteractionManager } from "@/managers/InteractionManager";
|
||||||
import type { Vector3Tuple } from "@/types/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
|
|
||||||
type Keys = {
|
type Keys = {
|
||||||
forward: boolean;
|
forward: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user