refacto : cleaning the codebasebase again
This commit is contained in:
+4
-14
@@ -2,35 +2,25 @@ import { useEffect, useRef } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { useGLTF } from "@react-three/drei";
|
||||
import * as THREE from "three";
|
||||
import { Octree } from "three/addons/math/Octree.js";
|
||||
import { MAP_DEBUG_BOX_HELPER_COLOR } from "@/data/debugConfig";
|
||||
import { useOctreeGraphNode } from "@/hooks/useOctreeGraphNode";
|
||||
import type { OctreeReadyHandler } from "@/types/3d";
|
||||
import { Debug } from "@/utils/debug/Debug";
|
||||
|
||||
const MAP_PATH = "/models/map/model.gltf";
|
||||
|
||||
interface MapProps {
|
||||
onOctreeReady: (octree: Octree) => void;
|
||||
onOctreeReady: OctreeReadyHandler;
|
||||
}
|
||||
|
||||
export function Map({ onOctreeReady }: MapProps): React.JSX.Element {
|
||||
const { scene: gltfScene } = useGLTF(MAP_PATH);
|
||||
const groupRef = useRef<THREE.Group>(null);
|
||||
const octreeBuilt = useRef(false);
|
||||
const boxHelpersRef = useRef<THREE.BoxHelper[]>([]);
|
||||
const { scene } = useThree();
|
||||
|
||||
useEffect(() => {
|
||||
if (octreeBuilt.current || !groupRef.current) return;
|
||||
octreeBuilt.current = true;
|
||||
useOctreeGraphNode(groupRef, onOctreeReady);
|
||||
|
||||
groupRef.current.updateMatrixWorld(true);
|
||||
|
||||
const octree = new Octree();
|
||||
octree.fromGraphNode(groupRef.current);
|
||||
onOctreeReady(octree);
|
||||
}, [onOctreeReady]);
|
||||
|
||||
// BoxHelper wireframes in debug mode — one per mesh in the model
|
||||
useEffect(() => {
|
||||
const debug = Debug.getInstance();
|
||||
if (!debug.active || !groupRef.current) return;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useRef } from "react";
|
||||
import { Physics, RigidBody, CuboidCollider } from "@react-three/rapier";
|
||||
import * as THREE from "three";
|
||||
import { Octree } from "three/addons/math/Octree.js";
|
||||
import { GrabbableObject } from "@/components/3d/GrabbableObject";
|
||||
import { TriggerObject } from "@/components/3d/TriggerObject";
|
||||
import {
|
||||
@@ -21,27 +20,19 @@ import {
|
||||
TEST_SCENE_TRIGGER_SEGMENTS,
|
||||
TEST_SCENE_TRIGGER_SOUND_PATH,
|
||||
} from "@/data/testSceneConfig";
|
||||
import { useOctreeGraphNode } from "@/hooks/useOctreeGraphNode";
|
||||
import type { OctreeReadyHandler } from "@/types/3d";
|
||||
|
||||
interface TestSceneProps {
|
||||
onOctreeReady: (octree: Octree) => void;
|
||||
onOctreeReady: OctreeReadyHandler;
|
||||
}
|
||||
|
||||
export function TestScene({
|
||||
onOctreeReady,
|
||||
}: TestSceneProps): React.JSX.Element {
|
||||
const floorRef = useRef<THREE.Group>(null);
|
||||
const octreeBuilt = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (octreeBuilt.current || !floorRef.current) return;
|
||||
octreeBuilt.current = true;
|
||||
|
||||
floorRef.current.updateMatrixWorld(true);
|
||||
|
||||
const octree = new Octree();
|
||||
octree.fromGraphNode(floorRef.current);
|
||||
onOctreeReady(octree);
|
||||
}, [onOctreeReady]);
|
||||
useOctreeGraphNode(floorRef, onOctreeReady);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
import { useEffect } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import type { Octree } from "three/addons/math/Octree.js";
|
||||
import {
|
||||
PLAYER_SPAWN_X,
|
||||
PLAYER_SPAWN_Y_DEFAULT,
|
||||
PLAYER_SPAWN_Z,
|
||||
} from "@/data/playerConfig";
|
||||
import { PLAYER_SPAWN_X, PLAYER_SPAWN_Z } from "@/data/playerConfig";
|
||||
import { PlayerCamera } from "@/world/player/PlayerCamera";
|
||||
import { PlayerController } from "@/world/player/PlayerController";
|
||||
|
||||
interface PlayerComponentProps {
|
||||
octree?: Octree | null;
|
||||
spawnY?: number;
|
||||
spawnY: number;
|
||||
}
|
||||
|
||||
export function PlayerComponent({
|
||||
octree = null,
|
||||
spawnY = PLAYER_SPAWN_Y_DEFAULT,
|
||||
spawnY,
|
||||
}: PlayerComponentProps): React.JSX.Element {
|
||||
const camera = useThree((state) => state.camera);
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ export function PlayerController({ octree }: PlayerControllerProps): null {
|
||||
const onFloor = useRef(false);
|
||||
const wantsJump = useRef(false);
|
||||
|
||||
// Capsule: start = feet, end = eyes
|
||||
const capsule = useRef(
|
||||
new Capsule(
|
||||
new THREE.Vector3(0, PLAYER_CAPSULE_RADIUS, 0),
|
||||
@@ -69,7 +68,6 @@ export function PlayerController({ octree }: PlayerControllerProps): null {
|
||||
),
|
||||
);
|
||||
|
||||
// Sync capsule to camera spawn position on mount
|
||||
useEffect(() => {
|
||||
const spawnY = camera.position.y;
|
||||
capsule.current.start.set(
|
||||
@@ -78,8 +76,7 @@ export function PlayerController({ octree }: PlayerControllerProps): null {
|
||||
PLAYER_SPAWN_Z,
|
||||
);
|
||||
capsule.current.end.set(PLAYER_SPAWN_X, spawnY, PLAYER_SPAWN_Z);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [camera]);
|
||||
|
||||
useEffect(() => {
|
||||
const interaction = InteractionManager.getInstance();
|
||||
@@ -168,7 +165,6 @@ export function PlayerController({ octree }: PlayerControllerProps): null {
|
||||
useFrame((_, delta) => {
|
||||
const dt = Math.min(delta, PLAYER_MAX_DELTA);
|
||||
|
||||
// Compute wish direction from camera yaw (XZ only)
|
||||
camera.getWorldDirection(_forward);
|
||||
_forward.setY(0);
|
||||
if (_forward.lengthSq() > 0) {
|
||||
@@ -183,7 +179,6 @@ export function PlayerController({ octree }: PlayerControllerProps): null {
|
||||
if (keys.current.right) _wishDir.add(_right);
|
||||
if (_wishDir.lengthSq() > 0) _wishDir.normalize();
|
||||
|
||||
// Accelerate horizontally
|
||||
const accel = onFloor.current
|
||||
? PLAYER_WALK_SPEED
|
||||
: PLAYER_WALK_SPEED * PLAYER_AIR_CONTROL_FACTOR;
|
||||
@@ -196,7 +191,6 @@ export function PlayerController({ octree }: PlayerControllerProps): null {
|
||||
velocity.current.x *= damping;
|
||||
velocity.current.z *= damping;
|
||||
|
||||
// Gravity + jump
|
||||
if (onFloor.current) {
|
||||
velocity.current.y = Math.max(0, velocity.current.y);
|
||||
if (wantsJump.current) {
|
||||
@@ -208,11 +202,9 @@ export function PlayerController({ octree }: PlayerControllerProps): null {
|
||||
}
|
||||
wantsJump.current = false;
|
||||
|
||||
// Move capsule
|
||||
_translateVec.copy(velocity.current).multiplyScalar(dt);
|
||||
capsule.current.translate(_translateVec);
|
||||
|
||||
// Resolve collisions against octree
|
||||
if (octree) {
|
||||
const result = octree.capsuleIntersect(capsule.current);
|
||||
onFloor.current = false;
|
||||
@@ -221,21 +213,18 @@ export function PlayerController({ octree }: PlayerControllerProps): null {
|
||||
onFloor.current = result.normal.y > 0;
|
||||
|
||||
if (!onFloor.current) {
|
||||
// Cancel velocity component going into the wall
|
||||
const vn = result.normal.dot(velocity.current);
|
||||
velocity.current.addScaledVector(result.normal, -vn);
|
||||
} else {
|
||||
velocity.current.y = Math.max(0, velocity.current.y);
|
||||
}
|
||||
|
||||
// Push capsule out of geometry
|
||||
capsule.current.translate(
|
||||
result.normal.clone().multiplyScalar(result.depth),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Sync camera to capsule top (eye position)
|
||||
camera.position.copy(capsule.current.end);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user