2025-05-30 10:57:28 +00:00
|
|
|
import { useCallback } from 'react';
|
|
|
|
import { useAisleStore } from '../../../../store/builder/useAisleStore';
|
|
|
|
import * as THREE from 'three';
|
2025-06-04 04:53:22 +00:00
|
|
|
import { useWallStore } from '../../../../store/builder/useWallStore';
|
2025-05-30 10:57:28 +00:00
|
|
|
|
|
|
|
const SNAP_THRESHOLD = 0.5; // Distance threshold for snapping in meters
|
|
|
|
|
|
|
|
const CAN_SNAP = true; // Whether snapping is enabled or not
|
|
|
|
|
|
|
|
export const usePointSnapping = (currentPoint: { uuid: string, pointType: string, position: [number, number, number] } | null) => {
|
|
|
|
const { aisles } = useAisleStore();
|
2025-06-04 04:53:22 +00:00
|
|
|
const { walls } = useWallStore();
|
2025-05-30 10:57:28 +00:00
|
|
|
|
2025-06-04 04:53:22 +00:00
|
|
|
const getAllOtherAislePoints = useCallback(() => {
|
2025-05-30 10:57:28 +00:00
|
|
|
if (!currentPoint) return [];
|
|
|
|
|
|
|
|
return aisles.flatMap(aisle =>
|
2025-06-03 07:21:04 +00:00
|
|
|
aisle.points.filter(point => point.pointUuid !== currentPoint.uuid)
|
2025-05-30 10:57:28 +00:00
|
|
|
);
|
|
|
|
}, [aisles, currentPoint]);
|
|
|
|
|
2025-06-04 04:53:22 +00:00
|
|
|
const getAllOtherWallPoints = useCallback(() => {
|
|
|
|
if (!currentPoint) return [];
|
|
|
|
return walls.flatMap(wall =>
|
|
|
|
wall.points.filter(point => point.pointUuid !== currentPoint.uuid)
|
|
|
|
);
|
|
|
|
}, [walls, currentPoint]);
|
|
|
|
|
2025-05-30 10:57:28 +00:00
|
|
|
const checkSnapForAisle = useCallback((position: [number, number, number]) => {
|
|
|
|
if (!currentPoint || !CAN_SNAP) return { position: position, isSnapped: false, snappedPoint: null };
|
|
|
|
|
2025-06-04 04:53:22 +00:00
|
|
|
const otherPoints = getAllOtherAislePoints();
|
2025-05-30 10:57:28 +00:00
|
|
|
const currentVec = new THREE.Vector3(...position);
|
|
|
|
|
|
|
|
for (const point of otherPoints) {
|
|
|
|
const pointVec = new THREE.Vector3(...point.position);
|
|
|
|
const distance = currentVec.distanceTo(pointVec);
|
|
|
|
|
|
|
|
if (distance <= SNAP_THRESHOLD && currentPoint.pointType === 'Aisle') {
|
|
|
|
return { position: point.position, isSnapped: true, snappedPoint: point };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return { position: position, isSnapped: false, snappedPoint: null };
|
2025-06-04 04:53:22 +00:00
|
|
|
}, [currentPoint, getAllOtherAislePoints]);
|
|
|
|
|
|
|
|
const checkSnapForWall = useCallback((position: [number, number, number]) => {
|
|
|
|
if (!currentPoint || !CAN_SNAP) return { position: position, isSnapped: false, snappedPoint: null };
|
|
|
|
|
|
|
|
const otherPoints = getAllOtherWallPoints();
|
|
|
|
const currentVec = new THREE.Vector3(...position);
|
|
|
|
for (const point of otherPoints) {
|
|
|
|
const pointVec = new THREE.Vector3(...point.position);
|
|
|
|
const distance = currentVec.distanceTo(pointVec);
|
|
|
|
if (distance <= SNAP_THRESHOLD && currentPoint.pointType === 'Wall') {
|
|
|
|
return { position: point.position, isSnapped: true, snappedPoint: point };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return { position: position, isSnapped: false, snappedPoint: null };
|
|
|
|
}, [currentPoint, getAllOtherWallPoints]);
|
2025-05-30 10:57:28 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
checkSnapForAisle,
|
2025-06-04 04:53:22 +00:00
|
|
|
checkSnapForWall,
|
2025-05-30 10:57:28 +00:00
|
|
|
};
|
|
|
|
};
|