아래 함수의 point 파라메터는 어떤 위치이고 mesh 파라메터가 대상 메시입니다. point에서 가장 가까운 매시 표면의 좌표가 변환됩니다.
findClosestPointOnMesh(/* Vector3 */ point, /* Mesh */ mesh) { const geometry = mesh.geometry; const vertices = geometry.attributes.position; const indices = geometry.index ? geometry.index.array : null; let closestPoint = new THREE.Vector3(); let minDistance = Infinity; const localPoint = mesh.worldToLocal(point); if (indices) { for (let i = 0; i < indices.length; i += 3) { const a = new THREE.Vector3().fromBufferAttribute(vertices, indices[i]); const b = new THREE.Vector3().fromBufferAttribute(vertices, indices[i + 1]); const c = new THREE.Vector3().fromBufferAttribute(vertices, indices[i + 2]); const tempPoint = new THREE.Vector3(); const triangle = new THREE.Triangle(a, b, c); triangle.closestPointToPoint(localPoint, tempPoint); const distance = localPoint.distanceTo(tempPoint); if (distance < minDistance) { minDistance = distance; closestPoint.copy(tempPoint); } } } else { for (let i = 0; i < vertices.count; i += 3) { const a = new THREE.Vector3().fromBufferAttribute(vertices, i); const b = new THREE.Vector3().fromBufferAttribute(vertices, i + 1); const c = new THREE.Vector3().fromBufferAttribute(vertices, i + 2); const tempPoint = new THREE.Vector3(); const triangle = new THREE.Triangle(a, b, c); triangle.closestPointToPoint(localPoint, tempPoint); const distance = localPoint.distanceTo(tempPoint); if (distance < minDistance) { minDistance = distance; closestPoint.copy(tempPoint); } } } return mesh.localToWorld(closestPoint); }
아래는 위의 함수가 적용된 실행 화면인데, 노란색 포인트 위치가 임의의 위치(point 파라메터)이고 빨간색이 함수의 결과 좌표입니다.