diff --git a/optuna_dashboard/ts/components/ThreejsArtifactViewer.tsx b/optuna_dashboard/ts/components/ThreejsArtifactViewer.tsx index 2a4249d8..f04a269e 100644 --- a/optuna_dashboard/ts/components/ThreejsArtifactViewer.tsx +++ b/optuna_dashboard/ts/components/ThreejsArtifactViewer.tsx @@ -34,7 +34,7 @@ const CustomGizmoHelper: React.FC = () => { ) } -const calculateBoundingBox = (geometries: THREE.BufferGeometry[]) => { +const computeBoundingBox = (geometries: THREE.BufferGeometry[]) => { const boundingBox = new THREE.Box3() geometries.forEach((geometry) => { const mesh = new THREE.Mesh(geometry) @@ -47,8 +47,11 @@ export const ThreejsArtifactViewer: React.FC = ( props ) => { const [geometry, setGeometry] = useState([]) - const [modelSize, setModelSize] = useState( - new THREE.Vector3(10, 10, 10) + const [boundingBox, setBoundingBox] = useState( + new THREE.Box3( + new THREE.Vector3(-10, -10, -10), + new THREE.Vector3(10, 10, 10) + ) ) const [cameraSettings, setCameraSettings] = useState( new THREE.PerspectiveCamera() @@ -56,11 +59,11 @@ export const ThreejsArtifactViewer: React.FC = ( const handleLoadedGeometries = (geometries: THREE.BufferGeometry[]) => { setGeometry(geometries) - const boundingBox = calculateBoundingBox(geometries) + const boundingBox = computeBoundingBox(geometries) if (boundingBox !== null) { - const size = boundingBox.getSize(new THREE.Vector3()) - setModelSize(size) + setBoundingBox(boundingBox) } + return boundingBox } useEffect(() => { @@ -83,20 +86,30 @@ export const ThreejsArtifactViewer: React.FC = ( } }) } - const maxModelSize = Math.max(modelSize.x, modelSize.y, modelSize.z) - const cameraSet = new THREE.PerspectiveCamera( - modelSize - ? Math.min( - 45, - Math.atan(modelSize.y / modelSize.z) * (180 / Math.PI) * 2 - ) - : 45, - window.innerWidth / window.innerHeight - ) - cameraSet.position.set(maxModelSize * 2, maxModelSize * 2, maxModelSize * 2) - setCameraSettings(cameraSet) }, []) + useEffect(() => { + const cameraSet = new THREE.PerspectiveCamera( + 50, + window.innerWidth / window.innerHeight, + 0.1, + boundingBox.getSize(new THREE.Vector3()).length() * 100 + ) + const maxPosition = Math.max( + boundingBox.max.x, + boundingBox.max.y, + boundingBox.max.z + ) + cameraSet.position.set( + maxPosition * 1.5, + maxPosition * 1.5, + maxPosition * 1.5 + ) + const center = boundingBox.getCenter(new THREE.Vector3()) + cameraSet.lookAt(center.x, center.y, center.z) + setCameraSettings(cameraSet) + }, [boundingBox]) + return ( = ( > - + {props.hasGizmo && } {geometry.length > 0 &&