import { useRef, useState } from "react"; import { RigidBody } from "@react-three/rapier"; import type { RapierRigidBody } from "@react-three/rapier"; import { InteractableObject } from "@/components/three/interaction/InteractableObject"; import { useClonedObject } from "@/hooks/three/useClonedObject"; import { useLoggedGLTF } from "@/hooks/three/useLoggedGLTF"; import { INTERACTION_RADIUS } from "@/data/interaction/interactionConfig"; import { TRIGGER_DEFAULT_COLLIDERS, TRIGGER_DEFAULT_LABEL, TRIGGER_DEFAULT_SOUND_VOLUME, TRIGGER_DEFAULT_SPAWN_OFFSET, } from "@/data/interaction/triggerConfig"; import { AudioManager } from "@/managers/AudioManager"; import type { ColliderShape, Vector3Tuple } from "@/types/three/three"; interface SpawnedModel { id: number; position: Vector3Tuple; } interface TriggerObjectProps { position: Vector3Tuple; children: React.ReactNode; colliders?: ColliderShape; label?: string; radius?: number; soundPath?: string; soundVolume?: number; spawnModel?: string; spawnOffset?: Vector3Tuple; onTrigger?: () => void; } let spawnCounter = 0; function SpawnedModelInstance({ path, position, }: { path: string; position: Vector3Tuple; }): React.JSX.Element { const { scene } = useLoggedGLTF(path, { scope: "TriggerObject.SpawnedModel", position, }); const model = useClonedObject(scene); return ; } export function TriggerObject({ position, children, colliders = TRIGGER_DEFAULT_COLLIDERS, label = TRIGGER_DEFAULT_LABEL, radius = INTERACTION_RADIUS, soundPath, soundVolume = TRIGGER_DEFAULT_SOUND_VOLUME, spawnModel, spawnOffset = TRIGGER_DEFAULT_SPAWN_OFFSET, onTrigger, }: TriggerObjectProps): React.JSX.Element { const [spawned, setSpawned] = useState([]); const rbRef = useRef(null); return ( <> { if (soundPath) { AudioManager.getInstance().playSound(soundPath, soundVolume, { category: "sfx", }); } onTrigger?.(); if (spawnModel) { const spawnPos: Vector3Tuple = [ position[0] + spawnOffset[0], position[1] + spawnOffset[1], position[2] + spawnOffset[2], ]; setSpawned((prev) => [ ...prev, { id: ++spawnCounter, position: spawnPos }, ]); } }} > {children} {spawnModel && spawned.map((s) => ( ))} ); }