fixed hit test on large faces
This commit is contained in:
parent
cf45752848
commit
7d3b8ca232
|
|
@ -110,12 +110,7 @@ export class CircularFrustumIntersection {
|
|||
: 'NOT_INTERSECTED';
|
||||
}
|
||||
|
||||
// ─── Local frustum construction ──────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Transform a world-space CircularFrustum into an object's local space.
|
||||
* Note: halfAngle is only preserved exactly under uniform scale.
|
||||
*/
|
||||
//world-space to an object's local space
|
||||
private toObjectLocalSpace(invWorldMatrix: THREE.Matrix4): CircularFrustum {
|
||||
return this.frustum.transform(invWorldMatrix);
|
||||
}
|
||||
|
|
@ -140,6 +135,8 @@ export class CircularFrustumIntersection {
|
|||
if (this.insersectsSphere(boundingSphere) === 'NOT_INTERSECTED')
|
||||
return [];
|
||||
|
||||
const axisRay = new THREE.Ray(localFrustum.apex, localFrustum.axisNormalized);
|
||||
|
||||
const results: HitResult[] = [];
|
||||
|
||||
if (!geometry.boundsTree)
|
||||
|
|
@ -208,12 +205,19 @@ export class CircularFrustumIntersection {
|
|||
tryPoint(a.clone().addScaledVector(edge, tApex));
|
||||
}
|
||||
|
||||
// 3. Closest point on the triangle face to the apex
|
||||
// 3. Closest point on triangle face to the apex (using THREE.Triangle, not ExtendedTriangle)
|
||||
const threeTri = new THREE.Triangle(tri.a, tri.b, tri.c);
|
||||
const closestOnFace = new THREE.Vector3();
|
||||
tri.closestPointToPoint(localFrustum.apex, closestOnFace);
|
||||
threeTri.closestPointToPoint(localFrustum.apex, closestOnFace);
|
||||
if (!isNaN(closestOnFace.x))
|
||||
tryPoint(closestOnFace);
|
||||
|
||||
// 4. Axis ray through the face — catches large faces the cone passes through
|
||||
const faceHit = new THREE.Vector3();
|
||||
if (axisRay.intersectTriangle(tri.a, tri.b, tri.c, false, faceHit)) {
|
||||
tryPoint(faceHit);
|
||||
}
|
||||
|
||||
if (bestLocal !== undefined) {
|
||||
const worldPoint = (bestLocal as THREE.Vector3).clone().applyMatrix4(mesh.matrixWorld);
|
||||
const worldDepth = worldFrustum.axisNormalized.dot(worldPoint.clone().sub(worldFrustum.apex));
|
||||
|
|
|
|||
Loading…
Reference in New Issue