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} />
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user