154 lines
3.6 KiB
JavaScript
154 lines
3.6 KiB
JavaScript
import { Vector3, Vector2, Triangle, DoubleSide, BackSide, REVISION } from 'three';
|
|
|
|
const IS_GT_REVISION_169 = parseInt( REVISION ) >= 169;
|
|
|
|
// Ripped and modified From THREE.js Mesh raycast
|
|
// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L115
|
|
const _vA = /* @__PURE__ */ new Vector3();
|
|
const _vB = /* @__PURE__ */ new Vector3();
|
|
const _vC = /* @__PURE__ */ new Vector3();
|
|
|
|
const _uvA = /* @__PURE__ */ new Vector2();
|
|
const _uvB = /* @__PURE__ */ new Vector2();
|
|
const _uvC = /* @__PURE__ */ new Vector2();
|
|
|
|
const _normalA = /* @__PURE__ */ new Vector3();
|
|
const _normalB = /* @__PURE__ */ new Vector3();
|
|
const _normalC = /* @__PURE__ */ new Vector3();
|
|
|
|
const _intersectionPoint = /* @__PURE__ */ new Vector3();
|
|
function checkIntersection( ray, pA, pB, pC, point, side, near, far ) {
|
|
|
|
let intersect;
|
|
if ( side === BackSide ) {
|
|
|
|
intersect = ray.intersectTriangle( pC, pB, pA, true, point );
|
|
|
|
} else {
|
|
|
|
intersect = ray.intersectTriangle( pA, pB, pC, side !== DoubleSide, point );
|
|
|
|
}
|
|
|
|
if ( intersect === null ) return null;
|
|
|
|
const distance = ray.origin.distanceTo( point );
|
|
|
|
if ( distance < near || distance > far ) return null;
|
|
|
|
return {
|
|
|
|
distance: distance,
|
|
point: point.clone(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
function checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far ) {
|
|
|
|
_vA.fromBufferAttribute( position, a );
|
|
_vB.fromBufferAttribute( position, b );
|
|
_vC.fromBufferAttribute( position, c );
|
|
|
|
const intersection = checkIntersection( ray, _vA, _vB, _vC, _intersectionPoint, side, near, far );
|
|
|
|
if ( intersection ) {
|
|
|
|
const barycoord = new Vector3();
|
|
Triangle.getBarycoord( _intersectionPoint, _vA, _vB, _vC, barycoord );
|
|
|
|
if ( uv ) {
|
|
|
|
_uvA.fromBufferAttribute( uv, a );
|
|
_uvB.fromBufferAttribute( uv, b );
|
|
_uvC.fromBufferAttribute( uv, c );
|
|
|
|
intersection.uv = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
|
|
|
|
}
|
|
|
|
if ( uv1 ) {
|
|
|
|
_uvA.fromBufferAttribute( uv1, a );
|
|
_uvB.fromBufferAttribute( uv1, b );
|
|
_uvC.fromBufferAttribute( uv1, c );
|
|
|
|
intersection.uv1 = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
|
|
|
|
}
|
|
|
|
if ( normal ) {
|
|
|
|
_normalA.fromBufferAttribute( normal, a );
|
|
_normalB.fromBufferAttribute( normal, b );
|
|
_normalC.fromBufferAttribute( normal, c );
|
|
|
|
intersection.normal = Triangle.getInterpolation( _intersectionPoint, _vA, _vB, _vC, _normalA, _normalB, _normalC, new Vector3() );
|
|
if ( intersection.normal.dot( ray.direction ) > 0 ) {
|
|
|
|
intersection.normal.multiplyScalar( - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const face = {
|
|
a: a,
|
|
b: b,
|
|
c: c,
|
|
normal: new Vector3(),
|
|
materialIndex: 0
|
|
};
|
|
|
|
Triangle.getNormal( _vA, _vB, _vC, face.normal );
|
|
|
|
intersection.face = face;
|
|
intersection.faceIndex = a;
|
|
|
|
if ( IS_GT_REVISION_169 ) {
|
|
|
|
intersection.barycoord = barycoord;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return intersection;
|
|
|
|
}
|
|
|
|
// https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L258
|
|
function intersectTri( geo, side, ray, tri, intersections, near, far ) {
|
|
|
|
const triOffset = tri * 3;
|
|
let a = triOffset + 0;
|
|
let b = triOffset + 1;
|
|
let c = triOffset + 2;
|
|
|
|
const index = geo.index;
|
|
if ( geo.index ) {
|
|
|
|
a = index.getX( a );
|
|
b = index.getX( b );
|
|
c = index.getX( c );
|
|
|
|
}
|
|
|
|
const { position, normal, uv, uv1 } = geo.attributes;
|
|
const intersection = checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side, near, far );
|
|
|
|
if ( intersection ) {
|
|
|
|
intersection.faceIndex = tri;
|
|
if ( intersections ) intersections.push( intersection );
|
|
return intersection;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
export { intersectTri };
|