import { useRef, useEffect, useState } from 'react' import { useModelingContext } from 'hooks/useModelingContext' import { cameraMouseDragGuards } from 'lib/cameraControls' import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext' import { useStore } from 'useStore' import { DEBUG_SHOW_BOTH_SCENES } from './sceneInfra' import { ReactCameraProperties } from './CameraControls' import { throttle } from 'lib/utils' import { sceneInfra } from 'lib/singletons' function useShouldHideScene(): { hideClient: boolean; hideServer: boolean } { const [isCamMoving, setIsCamMoving] = useState(false) const [isTween, setIsTween] = useState(false) const { state } = useModelingContext() useEffect(() => { sceneInfra.camControls.setIsCamMovingCallback((isMoving, isTween) => { setIsCamMoving(isMoving) setIsTween(isTween) }) }, []) if (DEBUG_SHOW_BOTH_SCENES || !isCamMoving) return { hideClient: false, hideServer: false } let hideServer = state.matches('Sketch') if (isTween) { hideServer = false } return { hideClient: !hideServer, hideServer } } export const ClientSideScene = ({ cameraControls, }: { cameraControls: ReturnType< typeof useSettingsAuthContext >['settings']['context']['modeling']['mouseControls']['current'] }) => { const canvasRef = useRef(null) const { state, send } = useModelingContext() const { hideClient, hideServer } = useShouldHideScene() const { setHighlightRange } = useStore((s) => ({ setHighlightRange: s.setHighlightRange, highlightRange: s.highlightRange, })) // Listen for changes to the camera controls setting // and update the client-side scene's controls accordingly. useEffect(() => { sceneInfra.camControls.interactionGuards = cameraMouseDragGuards[cameraControls] }, [cameraControls]) useEffect(() => { sceneInfra.updateOtherSelectionColors( state?.context?.selectionRanges?.otherSelections || [] ) }, [state?.context?.selectionRanges?.otherSelections]) useEffect(() => { if (!canvasRef.current) return const canvas = canvasRef.current canvas.appendChild(sceneInfra.renderer.domElement) sceneInfra.animate() sceneInfra.setHighlightCallback(setHighlightRange) canvas.addEventListener('mousemove', sceneInfra.onMouseMove, false) canvas.addEventListener('mousedown', sceneInfra.onMouseDown, false) canvas.addEventListener('mouseup', sceneInfra.onMouseUp, false) sceneInfra.setSend(send) return () => { canvas?.removeEventListener('mousemove', sceneInfra.onMouseMove) canvas?.removeEventListener('mousedown', sceneInfra.onMouseDown) canvas?.removeEventListener('mouseup', sceneInfra.onMouseUp) } }, []) return (
) } const throttled = throttle((a: ReactCameraProperties) => { if (a.type === 'perspective' && a.fov) { sceneInfra.camControls.dollyZoom(a.fov) } }, 1000 / 15) export const CamDebugSettings = () => { const [camSettings, setCamSettings] = useState({ type: 'perspective', fov: 12, position: [0, 0, 0], quaternion: [0, 0, 0, 1], }) const [fov, setFov] = useState(12) useEffect(() => { sceneInfra.camControls.setReactCameraPropertiesCallback(setCamSettings) }, [sceneInfra]) useEffect(() => { if (camSettings.type === 'perspective' && camSettings.fov) { setFov(camSettings.fov) } }, [(camSettings as any)?.fov]) return (

cam settings

perspective cam { if (camSettings.type === 'perspective') { sceneInfra.camControls.useOrthographicCamera() } else { sceneInfra.camControls.usePerspectiveCamera() } }} /> {camSettings.type === 'perspective' && ( { setFov(parseFloat(e.target.value)) throttled({ ...camSettings, fov: parseFloat(e.target.value), }) }} className="w-full cursor-pointer pointer-events-auto" /> )} {camSettings.type === 'perspective' && (
fov { sceneInfra.camControls.setCam({ ...camSettings, fov: parseFloat(e.target.value), }) }} />
)} {camSettings.type === 'orthographic' && ( <>
fov { sceneInfra.camControls.setCam({ ...camSettings, zoom: parseFloat(e.target.value), }) }} />
)}
Position
  • x: { sceneInfra.camControls.setCam({ ...camSettings, position: [ parseFloat(e.target.value), camSettings.position[1], camSettings.position[2], ], }) }} />
  • y: { sceneInfra.camControls.setCam({ ...camSettings, position: [ camSettings.position[0], parseFloat(e.target.value), camSettings.position[2], ], }) }} />
  • z: { sceneInfra.camControls.setCam({ ...camSettings, position: [ camSettings.position[0], camSettings.position[1], parseFloat(e.target.value), ], }) }} />
) }