65 lines
2.3 KiB
TypeScript
65 lines
2.3 KiB
TypeScript
|
import { Line } from "@react-three/drei";
|
||
|
import { useMemo } from "react";
|
||
|
import * as THREE from "three";
|
||
|
import { useSelectedAssets } from "../../../../store/store";
|
||
|
|
||
|
const BoundingBox = ({ boundingBoxRef }: any) => {
|
||
|
const { selectedAssets } = useSelectedAssets();
|
||
|
|
||
|
const { points, boxProps } = useMemo(() => {
|
||
|
if (selectedAssets.length === 0) return { points: [], boxProps: {} };
|
||
|
|
||
|
const box = new THREE.Box3();
|
||
|
selectedAssets.forEach((obj: any) => box.expandByObject(obj.clone()));
|
||
|
|
||
|
const size = new THREE.Vector3();
|
||
|
box.getSize(size);
|
||
|
const center = new THREE.Vector3();
|
||
|
box.getCenter(center);
|
||
|
|
||
|
const halfSize = size.clone().multiplyScalar(0.5);
|
||
|
const min = center.clone().sub(halfSize);
|
||
|
const max = center.clone().add(halfSize);
|
||
|
|
||
|
const points: any = [
|
||
|
[min.x, min.y, min.z], [max.x, min.y, min.z],
|
||
|
[max.x, min.y, min.z], [max.x, max.y, min.z],
|
||
|
[max.x, max.y, min.z], [min.x, max.y, min.z],
|
||
|
[min.x, max.y, min.z], [min.x, min.y, min.z],
|
||
|
|
||
|
[min.x, min.y, max.z], [max.x, min.y, max.z],
|
||
|
[max.x, min.y, max.z], [max.x, max.y, max.z],
|
||
|
[max.x, max.y, max.z], [min.x, max.y, max.z],
|
||
|
[min.x, max.y, max.z], [min.x, min.y, max.z],
|
||
|
|
||
|
[min.x, min.y, min.z], [min.x, min.y, max.z],
|
||
|
[max.x, min.y, min.z], [max.x, min.y, max.z],
|
||
|
[max.x, max.y, min.z], [max.x, max.y, max.z],
|
||
|
[min.x, max.y, min.z], [min.x, max.y, max.z],
|
||
|
];
|
||
|
|
||
|
return {
|
||
|
points,
|
||
|
boxProps: { position: center.toArray(), args: size.toArray() }
|
||
|
};
|
||
|
}, [selectedAssets]);
|
||
|
|
||
|
const savedTheme: string | null = localStorage.getItem("theme") || "light";
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
{points.length > 0 && (
|
||
|
<>
|
||
|
<Line points={points} color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"} lineWidth={2.7} segments />
|
||
|
<mesh ref={boundingBoxRef} visible={false} position={boxProps.position}>
|
||
|
<boxGeometry args={boxProps.args} />
|
||
|
<meshBasicMaterial />
|
||
|
</mesh>
|
||
|
</>
|
||
|
)}
|
||
|
</>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export default BoundingBox;
|