diff --git a/app/web/src/components/IdeViewer/IdeViewer.tsx b/app/web/src/components/IdeViewer/IdeViewer.tsx index a9ef95f..4a03670 100644 --- a/app/web/src/components/IdeViewer/IdeViewer.tsx +++ b/app/web/src/components/IdeViewer/IdeViewer.tsx @@ -19,17 +19,66 @@ import type { ArtifactTypes } from 'src/helpers/cadPackages/common' const thresholdAngle = 12 -function Asset({ geometry: incomingGeo }) { +function Asset({ + geometry: incomingGeo, + dataType, + controlsRef, +}: { + geometry: any + dataType: 'INIT' | ArtifactTypes + controlsRef: React.MutableRefObject +}) { + const threeInstance = useThree() + const [initZoom, setInitZoom] = useState(true) const mesh = useEdgeSplit((thresholdAngle * Math.PI) / 180, true, incomingGeo) const edges = React.useMemo( () => - incomingGeo.length + incomingGeo.length || dataType !== 'geometry' ? null : new THREE.EdgesGeometry(incomingGeo, thresholdAngle), - [incomingGeo] + [incomingGeo, dataType] + ) + React.useEffect(() => { + const getBoundingSphere = () => { + if (dataType === 'geometry') { + return incomingGeo.boundingSphere + } + const group = new THREE.Group() + incomingGeo.forEach((mesh) => group.add(mesh)) + const bbox = new THREE.Box3().setFromObject(group) + return bbox.getBoundingSphere(new THREE.Sphere()) + } + const bSphere = getBoundingSphere() + + const zoomToFit = () => { + const { center, radius } = bSphere + const { camera } = threeInstance + const offset = 4 + controlsRef.current.reset() + controlsRef.current.target.copy(center) + + camera.position.copy(center.clone().add(new THREE.Vector3(offset * radius, -offset * radius, offset * radius))) + camera.updateProjectionMatrix() + } + if(initZoom){ + zoomToFit() + setInitZoom(false) + } + + }, [incomingGeo, dataType]) + const PrimitiveArray = React.useMemo( + () => + dataType === 'primitive-array' && + incomingGeo?.map((mesh) => mesh.clone()), + [dataType, incomingGeo] ) const colorMap = useTexture(texture) + if (!incomingGeo) return null + if (PrimitiveArray) + return PrimitiveArray.map((mesh, index) => ( + + )) return ( @@ -53,8 +102,7 @@ function Asset({ geometry: incomingGeo }) { } let debounceTimeoutId -function Controls({ onCameraChange, onDragStart, onInit }) { - const controls = useRef() +function Controls({ onCameraChange, onDragStart, onInit, controlsRef }) { const threeInstance = useThree() const { camera, gl } = threeInstance useEffect(() => { @@ -93,7 +141,7 @@ function Controls({ onCameraChange, onDragStart, onInit }) { } } - if (controls.current) { + if (controlsRef.current) { const dragCallback = () => { clearTimeout(debounceTimeoutId) debounceTimeoutId = setTimeout(() => { @@ -111,19 +159,19 @@ function Controls({ onCameraChange, onDragStart, onInit }) { onDragStart() clearTimeout(debounceTimeoutId) } - controls?.current?.addEventListener('end', dragCallback) - controls?.current?.addEventListener('start', dragStart) - const oldCurrent = controls.current + controlsRef?.current?.addEventListener('end', dragCallback) + controlsRef?.current?.addEventListener('start', dragStart) + const oldCurrent = controlsRef.current dragCallback() return () => { oldCurrent.removeEventListener('end', dragCallback) oldCurrent.removeEventListener('start', dragStart) } } - }, [camera, controls]) + }, [camera, controlsRef]) return ( - + ) } @@ -167,22 +215,18 @@ export function PureIdeViewer({ }) { const [isDragging, setIsDragging] = useState(false) const [image, setImage] = useState() + const controlsRef = useRef() useEffect(() => { setImage(dataType === 'png' && artifact) setIsDragging(false) }, [dataType, artifact]) - const PrimitiveArray = React.useMemo( - () => - dataType === 'primitive-array' && artifact?.map((mesh) => mesh.clone()), - [dataType, artifact] - ) // the following are tailwind colors in hex, can't use these classes to color three.js meshes. const pink400 = '#F472B6' const indigo300 = '#A5B4FC' const indigo900 = '#312E81' - const jscadLightIntensity = PrimitiveArray ? 0.5 : 1.1 + const jscadLightIntensity = dataType === 'primitive-array' ? 0.5 : 1.1 return (
{image && ( @@ -217,6 +261,7 @@ export function PureIdeViewer({ onDragStart={() => setIsDragging(true)} onInit={onInit} onCameraChange={onCameraChange} + controlsRef={controlsRef} /> )} - {dataType === 'geometry' && artifact && ( + {dataType !== 'png' && artifact && ( - + )} - {PrimitiveArray && - PrimitiveArray.map((mesh, index) => ( - - ))}