Reputation: 121
I want to resize a certain object in react three fiber based upon the size of another object. I have loaded the 2 objects using the STL loader and wanna use these.
const geomUpper = useLoader(STLLoader, upperUrl)
const geomLower = useLoader(STLLoader, lowerUrl)
Then I want to use the size of geomUpper to resize geomLower but I don't know how to get the size of geomUpper. Is there a way to get its size?
Upvotes: 1
Views: 4053
Reputation: 106
Another way, maybe simpler to use is to compute the bounding box of the object and to get the size.
// Compute the bounding box
const bbox = new THREE.Box3().setFromObject(objectRef.current)
// Init your size variable
const bboxSize = new THREE.Vector3(bbox)
// Get the size
bbox.getSize(bboxSize)
// Now use bboxSize (x,y,z)
Upvotes: 1
Reputation: 700
UPDATED
Inside of an effect hook, you can get the size of geomUpper
and use it to scale geomLower
.
function Scene() {
const geomUpper = useLoader( STLLoader, '/upper.stl' );
const geomLower = useLoader( STLLoader, '/lower.stl' );
useEffect(() => {
if ( ! geomUpper.boundingSphere ) {
geomUpper.computeBoundingSphere();
}
console.log( 'geomUpper radius',
geomUpper.boundingSphere.radius );
if( ! geomLower.boundingSphere ) {
geomLower.computeBoundingSphere();
}
console.log( 'geomLower radius',
geomLower.boundingSphere.radius );
const scale = geomUpper.boundingSphere.radius /
geomLower.boundingSphere.radius;
geomLower.scale( scale, scale, scale );
console.log( 'geomLower radius (after scaling)',
geomLower.boundingSphere.radius );
})
return (
<Suspense>
<mesh geometry={geomUpper} />
<mesh geometry={geomLower} />
</Suspense>
)
}
I'm using the radius of the boundingShere
here as a proxy for the size, but that's just for brevity. You could use the x, y, and z dimensions of the boundingBox
with more advanced logic that suits your needs. My console.log()
calls are just sanity checks and can be removed.
ORIGINAL ANSWER (won't work with React Three Fiber, but should work with vanilla Three.js)
This should work if geomUpper's position is inside its mesh(es).
// create a Box3 to hold the dimensions
// initialize it to a zero-size box at geomUpper's position
const bbox = new THREE.Box3(geomUpper.position, geomUpper.position);
// expand the box to include geomUpper's children
// expandByObject mutates bbox
bbox.expandByObject(geomUpper);
// get the size of bbox
let size = new THREE.Vector3();
bbox.getSize(size);
Upvotes: 2