import { Bounds, useBounds } from "@react-three/drei"; import { Canvas } from "@react-three/fiber"; import { useCallback } from "react"; import type { CharacterDraft, CharacterProfile } from "../app/types"; import { CharacterModel } from "../avatar/CharacterModel"; import { ProceduralAvatar } from "../avatar/ProceduralAvatar"; import { classById, raceById } from "../app/characterCatalog"; import { numericFrameRateLimit, type PreviewFrameRateLimit, } from "../game/frameRateSettings"; import { useDocumentVisibility } from "../platform/useDocumentVisibility"; import { CappedFrameLoop } from "../scene/CappedFrameLoop"; function FittedCharacter({ characterClassColor, source, turnDegrees, }: { characterClassColor: string; source: CharacterProfile | CharacterDraft; turnDegrees: number; }) { const bounds = useBounds(); const refit = useCallback(() => { bounds.refresh().clip().fit(); }, [bounds]); return ( } /> ); } export default function CharacterPreview3D({ frameRateLimit, source }: { frameRateLimit: PreviewFrameRateLimit; source: CharacterProfile | CharacterDraft; }) { const race = raceById(source.raceId); const characterClass = classById(source.classId); const turnDegrees = "rotation" in source ? source.rotation : -8; const documentVisible = useDocumentVisibility(); const targetFps = numericFrameRateLimit(frameRateLimit); const frameloop = !documentVisible ? "demand" : targetFps === null ? "always" : "never"; return ( ); }