Fix 3js camera settings

This commit is contained in:
hrntsm
2023-10-19 17:30:29 +09:00
parent 3ee3dc2331
commit 7a3a287f57
@@ -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<ThreejsArtifactViewerProps> = (
props
) => {
const [geometry, setGeometry] = useState<THREE.BufferGeometry[]>([])
const [modelSize, setModelSize] = useState<THREE.Vector3>(
new THREE.Vector3(10, 10, 10)
const [boundingBox, setBoundingBox] = useState<THREE.Box3>(
new THREE.Box3(
new THREE.Vector3(-10, -10, -10),
new THREE.Vector3(10, 10, 10)
)
)
const [cameraSettings, setCameraSettings] = useState<PerspectiveCamera>(
new THREE.PerspectiveCamera()
@@ -56,11 +59,11 @@ export const ThreejsArtifactViewer: React.FC<ThreejsArtifactViewerProps> = (
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<ThreejsArtifactViewerProps> = (
}
})
}
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 (
<Canvas
camera={cameraSettings}
@@ -104,7 +117,7 @@ export const ThreejsArtifactViewer: React.FC<ThreejsArtifactViewerProps> = (
>
<ambientLight />
<OrbitControls />
<gridHelper args={[Math.max(modelSize?.x, modelSize?.y) * 5]} />
<gridHelper args={[Math.max(boundingBox.max.x, boundingBox.max.y) * 5]} />
{props.hasGizmo && <CustomGizmoHelper />}
<axesHelper />
{geometry.length > 0 &&