Refactor AssetBoundingBox to use cylinders for edges and improve bounding box rendering logic; update Model component to adjust line width for better visibility; enhance distanceWorker to utilize Vector3 for distance calculations.
This commit is contained in:
@@ -1,47 +1,67 @@
|
||||
import { Line } from "@react-three/drei";
|
||||
import { Box3, Vector3 } from "three";
|
||||
import { Box3, Vector3, Quaternion } from "three";
|
||||
import { useMemo } from "react";
|
||||
import { Cylinder } from "@react-three/drei";
|
||||
|
||||
export const AssetBoundingBox = ({ name, boundingBox, color, lineWidth }: { name: string; boundingBox: Box3 | null; color: string; lineWidth: number; }) => {
|
||||
const { points, size, center } = useMemo(() => {
|
||||
if (!boundingBox) { return { points: [], center: new Vector3(), size: new Vector3(), }; }
|
||||
export const AssetBoundingBox = ({ name, boundingBox, color, lineWidth, }: { name: string; boundingBox: Box3 | null; color: string; lineWidth: number; }) => {
|
||||
const { edgeCylinders, center, size } = useMemo(() => {
|
||||
if (!boundingBox) return { edgeCylinders: [], center: new Vector3(), size: new Vector3() };
|
||||
|
||||
const min = boundingBox.min;
|
||||
const max = boundingBox.max;
|
||||
const center = boundingBox.getCenter(new Vector3());
|
||||
const size = boundingBox.getSize(new Vector3());
|
||||
|
||||
const edges: Array<[number, number, number]> = [
|
||||
[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],
|
||||
const corners = [
|
||||
new Vector3(min.x, min.y, min.z),
|
||||
new Vector3(max.x, min.y, min.z),
|
||||
new Vector3(max.x, max.y, min.z),
|
||||
new Vector3(min.x, max.y, min.z),
|
||||
new Vector3(min.x, min.y, max.z),
|
||||
new Vector3(max.x, min.y, max.z),
|
||||
new Vector3(max.x, max.y, max.z),
|
||||
new Vector3(min.x, max.y, max.z),
|
||||
];
|
||||
|
||||
return { points: edges, center, size };
|
||||
}, [boundingBox]);
|
||||
const edgeIndices: [number, number][] = [
|
||||
[0, 1], [1, 2], [2, 3], [3, 0],
|
||||
[4, 5], [5, 6], [6, 7], [7, 4],
|
||||
[0, 4], [1, 5], [2, 6], [3, 7],
|
||||
];
|
||||
|
||||
const radius = 0.005 * lineWidth;
|
||||
|
||||
const edgeCylinders = edgeIndices.map(([startIdx, endIdx], i) => {
|
||||
const start = corners[startIdx];
|
||||
const end = corners[endIdx];
|
||||
const direction = new Vector3().subVectors(end, start);
|
||||
const length = direction.length();
|
||||
const midPoint = new Vector3().addVectors(start, end).multiplyScalar(0.5);
|
||||
const quaternion = new Quaternion().setFromUnitVectors(
|
||||
new Vector3(0, 1, 0),
|
||||
direction.clone().normalize()
|
||||
);
|
||||
|
||||
return {
|
||||
key: `edge-cylinder-${i}`,
|
||||
position: midPoint,
|
||||
rotation: quaternion,
|
||||
length,
|
||||
radius,
|
||||
};
|
||||
});
|
||||
|
||||
return { edgeCylinders, center, size };
|
||||
}, [boundingBox, lineWidth]);
|
||||
|
||||
if (!boundingBox) return null;
|
||||
|
||||
return (
|
||||
<group name={name}>
|
||||
<Line
|
||||
segments
|
||||
depthWrite={false}
|
||||
points={points}
|
||||
color={color}
|
||||
lineWidth={lineWidth}
|
||||
/>
|
||||
{edgeCylinders.map(({ key, position, rotation, length, radius }) => (
|
||||
<Cylinder key={key} args={[radius, radius, length, 6]} position={position} quaternion={rotation} >
|
||||
<meshBasicMaterial color={color} depthWrite={false} />
|
||||
</Cylinder>
|
||||
))}
|
||||
|
||||
<mesh visible={false} position={center}>
|
||||
<boxGeometry args={[size.x, size.y, size.z]} />
|
||||
|
||||
@@ -21,6 +21,8 @@ import { upsertProductOrEventApi } from '../../../../../services/simulation/prod
|
||||
import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs';
|
||||
import { ModelAnimator } from './animator/modelAnimator';
|
||||
|
||||
const distanceWorker = new Worker(new URL("../../../../../services/factoryBuilder/webWorkers/distanceWorker.js", import.meta.url));
|
||||
|
||||
function Model({ asset }: { readonly asset: Asset }) {
|
||||
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
const savedTheme: string = localStorage.getItem("theme") || "light";
|
||||
@@ -59,6 +61,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { selectedAssets } = useSelectedAssets();
|
||||
const intervalRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
@@ -474,7 +477,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
|
||||
</>
|
||||
) : (
|
||||
<AssetBoundingBox name='Asset Fallback' boundingBox={boundingBox} color='gray' lineWidth={1} />
|
||||
<AssetBoundingBox name='Asset Fallback' boundingBox={boundingBox} color='gray' lineWidth={2.5} />
|
||||
)}
|
||||
{isSelected &&
|
||||
<AssetBoundingBox name='Asset BBox' boundingBox={boundingBox} color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"} lineWidth={2.7} />
|
||||
|
||||
Reference in New Issue
Block a user