MCPcopy Create free account
hub / github.com/ColmapView/Colmapview.github.io / usePointPicking

Function usePointPicking

src/hooks/pointCloud/usePointPicking.ts:42–207  ·  view source on GitHub ↗
(params: UsePointPickingParams)

Source from the content-addressed store, hash-verified

40 * @returns Refs and handlers for point picking
41 */
42export function usePointPicking(params: UsePointPickingParams): UsePointPickingResult {
43 const {
44 pickingMode,
45 selectedPointsLength,
46 pointSize,
47 indexToPoint3DIdRef,
48 addSelectedPoint,
49 setHoveredPoint,
50 } = params;
51
52 const { camera, gl, raycaster } = useThree();
53 const pointsRef = useRef<THREE.Points>(null);
54
55 // Manual raycasting state (avoids Three.js auto-raycasting on every pointer move)
56 const mouseRef = useRef(new THREE.Vector2());
57 const lastHoverTimeRef = useRef(0);
58 const hoverDirtyRef = useRef(false);
59
60 // Reusable ref for result (avoid allocations in hot path)
61 const resultWorldPosRef = useRef(new THREE.Vector3());
62 const lastHoverPosRef = useRef<THREE.Vector3 | null>(null);
63
64 // Calculate max points based on picking mode
65 const maxPoints = getRequiredPointCount(pickingMode);
66 const needsMorePoints = needsMoreSelectedPoints(selectedPointsLength, pickingMode);
67
68 // Find nearest point from intersections using pre-computed distanceToRay
69 const findNearestPoint = useCallback(
70 (intersections: THREE.Intersection[]): NearestPointResult | null => {
71 const points = pointsRef.current;
72 if (!points || intersections.length === 0) return null;
73
74 let closestIdx = -1;
75 let closestDist = Infinity;
76 let closestWorldPos: THREE.Vector3 | null = null;
77
78 // Must check all intersections - they're sorted by camera distance, not by distanceToRay
79 for (let i = 0; i < intersections.length; i++) {
80 const hit = intersections[i];
81 if (hit.object !== points || hit.index === undefined) continue;
82
83 const dist = hit.distanceToRay ?? Infinity;
84 if (dist < closestDist) {
85 closestDist = dist;
86 closestIdx = hit.index;
87 closestWorldPos = hit.point;
88 }
89 }
90
91 if (closestIdx === -1 || !closestWorldPos) return null;
92 resultWorldPosRef.current.copy(closestWorldPos);
93 return { index: closestIdx, worldPos: resultWorldPosRef.current };
94 },
95 []
96 );
97
98 // DOM event listener for mouse tracking (no raycasting - just stores position)
99 useEffect(() => {

Callers 1

PointCloudFunction · 0.90

Calls 6

getRequiredPointCountFunction · 0.90
needsMoreSelectedPointsFunction · 0.90
getMethod · 0.80
stopPropagationMethod · 0.65
cloneMethod · 0.45

Tested by

no test coverage detected