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:
2025-07-28 17:21:07 +05:30
parent c224d9bb3c
commit 1231bedbb1
4 changed files with 65 additions and 46 deletions

View File

@@ -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]} />

View File

@@ -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} />

View File

@@ -164,7 +164,7 @@ function MoveControls2D({
return new THREE.Vector3().subVectors(pointPosition, hitPoint);
}, []);
const movePoints = useCallback(() => {
const movePoints = (() => {
if (selectedPoints.length === 0) return;
const states: Record<string, { position: THREE.Vector3; rotation?: THREE.Euler; }> = {};
@@ -192,9 +192,9 @@ function MoveControls2D({
setMovedObjects(selectedPoints);
setIsMoving(true);
}, [selectedPoints, camera, pointer, plane, raycaster, calculateDragOffset]);
});
const resetToInitialPositions = useCallback(() => {
const resetToInitialPositions = () => {
setTimeout(() => {
movedObjects.forEach((movedPoint: THREE.Object3D) => {
if (movedPoint.userData.pointUuid && initialStates[movedPoint.uuid]) {
@@ -218,7 +218,7 @@ function MoveControls2D({
}
});
}, 0)
}, [movedObjects, initialStates, setAislePosition, setWallPosition, setFloorPosition, setZonePosition]);
};
const placeMovedAssets = () => {
if (movedObjects.length === 0) return;

View File

@@ -1,21 +1,17 @@
import { Vector3 } from "three";
onmessage = function (e) {
const { assetPosition, cameraPosition, limitDistance, renderDistance, isRendered } = e.data;
const { modelUuid, assetPosition, cameraPosition, limitDistance, renderDistance, isRendered } = e.data;
if (limitDistance && assetPosition) {
const distance = Math.sqrt(
Math.pow(assetPosition.x - cameraPosition.x, 2) +
Math.pow(assetPosition.y - cameraPosition.y, 2) +
Math.pow(assetPosition.z - cameraPosition.z, 2)
);
if (!isRendered && distance <= renderDistance) {
postMessage({ shouldRender: true });
} else if (isRendered && distance > renderDistance) {
postMessage({ shouldRender: false });
if (!isRendered && new Vector3(assetPosition.x, assetPosition.y, assetPosition.z).distanceTo(cameraPosition) <= renderDistance) {
postMessage({ shouldRender: true, modelUuid });
} else if (isRendered && new Vector3(assetPosition.x, assetPosition.y, assetPosition.z).distanceTo(cameraPosition) > renderDistance) {
postMessage({ shouldRender: false, modelUuid });
}
} else {
if (!isRendered) {
postMessage({ shouldRender: true });
postMessage({ shouldRender: true, modelUuid });
}
}
};