Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
@@ -443,6 +443,16 @@ const _ab = new THREE.Vector3();
|
||||
const _ap = new THREE.Vector3();
|
||||
const _closest = new THREE.Vector3();
|
||||
|
||||
function closestPointOnSegment3D(p: THREE.Vector3, a: THREE.Vector3, b: THREE.Vector3, target: THREE.Vector3): THREE.Vector3 {
|
||||
_ab.subVectors(b, a);
|
||||
_ap.subVectors(p, a);
|
||||
const abLenSq = _ab.lengthSq();
|
||||
if (abLenSq < 1e-6) return target.copy(a);
|
||||
|
||||
const t = THREE.MathUtils.clamp(_ap.dot(_ab) / abLenSq, 0, 1);
|
||||
return target.copy(a).addScaledVector(_ab, t);
|
||||
}
|
||||
|
||||
function pointToSegmentDistSq3D(p: THREE.Vector3, a: THREE.Vector3, b: THREE.Vector3): number {
|
||||
_ab.subVectors(b, a);
|
||||
_ap.subVectors(p, a);
|
||||
@@ -503,7 +513,7 @@ export function findNearestEdgeSegment3D(
|
||||
mesh: THREE.Mesh,
|
||||
worldPoint: THREE.Vector3,
|
||||
thresholdMeters: number = 0.05
|
||||
): { midpoint: THREE.Vector3; lengthMM: number; a: THREE.Vector3; b: THREE.Vector3 } | null {
|
||||
): { midpoint: THREE.Vector3; snapPoint: THREE.Vector3; lengthMM: number; a: THREE.Vector3; b: THREE.Vector3 } | null {
|
||||
let edgeLines: THREE.LineSegments | null = null;
|
||||
mesh.children.forEach(c => {
|
||||
if (c.userData.__edgeLine && c instanceof THREE.LineSegments) {
|
||||
@@ -529,6 +539,7 @@ export function findNearestEdgeSegment3D(
|
||||
|
||||
let bestDistSq = Infinity;
|
||||
let bestIndex = -1;
|
||||
const bestClosestLocal = new THREE.Vector3();
|
||||
const thresholdSq = thresholdMeters * thresholdMeters;
|
||||
|
||||
const segCount = posAttr.count / 2;
|
||||
@@ -539,11 +550,13 @@ export function findNearestEdgeSegment3D(
|
||||
aLocal.fromBufferAttribute(posAttr, i * 2);
|
||||
bLocal.fromBufferAttribute(posAttr, i * 2 + 1);
|
||||
|
||||
const distSq = pointToSegmentDistSq3D(localPoint, aLocal, bLocal);
|
||||
closestPointOnSegment3D(localPoint, aLocal, bLocal, _closest);
|
||||
const distSq = localPoint.distanceToSquared(_closest);
|
||||
|
||||
if (distSq < bestDistSq) {
|
||||
bestDistSq = distSq;
|
||||
bestIndex = i;
|
||||
bestClosestLocal.copy(_closest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,8 +564,9 @@ export function findNearestEdgeSegment3D(
|
||||
const a = new THREE.Vector3().fromBufferAttribute(posAttr, bestIndex * 2).applyMatrix4(matrix);
|
||||
const b = new THREE.Vector3().fromBufferAttribute(posAttr, bestIndex * 2 + 1).applyMatrix4(matrix);
|
||||
const midpoint = a.clone().add(b).multiplyScalar(0.5);
|
||||
const snapPoint = bestClosestLocal.clone().applyMatrix4(matrix);
|
||||
const lengthMM = a.distanceTo(b) * 1000;
|
||||
return { midpoint, lengthMM, a, b };
|
||||
return { midpoint, snapPoint, lengthMM, a, b };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -652,6 +666,6 @@ export function resolveSnap3D(
|
||||
const v = findNearestVertex3D(mesh, hitPoint, vertexThresholdMeters);
|
||||
if (v) return { point: v, type: 'vertex' };
|
||||
const e = findNearestEdgeSegment3D(mesh, hitPoint, edgeThresholdMeters);
|
||||
if (e) return { point: e.midpoint, type: 'edge' };
|
||||
if (e) return { point: e.snapPoint, type: 'edge' };
|
||||
return { point: hitPoint.clone(), type: 'surface' };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user