<!-- NEW6 — TEST 6 · THE FIVE SHORES · part 124 -->
y - origin.y ) * invdiry;

		}

		if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;

		if ( tymin > tmin || isNaN( tmin ) ) tmin = tymin;

		if ( tymax < tmax || isNaN( tmax ) ) tmax = tymax;

		if ( invdirz >= 0 ) {

			tzmin = ( box.min.z - origin.z ) * invdirz;
			tzmax = ( box.max.z - origin.z ) * invdirz;

		} else {

			tzmin = ( box.max.z - origin.z ) * invdirz;
			tzmax = ( box.min.z - origin.z ) * invdirz;

		}

		if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;

		if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;

		if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;

		//return point closest to the ray (positive side)

		if ( tmax < 0 ) return null;

		return this.at( tmin >= 0 ? tmin : tmax, target );

	}

	/**
	 * Returns `true` if this ray intersects with the given box.
	 *
	 * @param {Box3} box - The box to intersect.
	 * @return {boolean} Whether this ray intersects with the given box or not.
	 */
	intersectsBox( box ) {

		return this.intersectBox( box, _vector$7 ) !== null;

	}

	/**
	 * Intersects this ray with the given triangle, returning the intersection
	 * point or `null` if there is no intersection.
	 *
	 * @param {Vector3} a - The first vertex of the triangle.
	 * @param {Vector3} b - The second vertex of the triangle.
	 * @param {Vector3} c - The third vertex of the triangle.
	 * @param {boolean} backfaceCulling - Whether to use backface culling or not.
	 * @param {Vector3} target - The target vector that is used to store the method's result.
	 * @return {?Vector3} The intersection point.
	 */
	intersectTriangle( a, b, c, backfaceCulling, target ) {

		// Watertight ray/triangle intersection. Reference: Woop, Benthin, Wald,
		// "Watertight Ray/Triangle Intersection", JCGT vol. 2 no. 1 (2013), Appendix A.
		// https://jcgt.org/published/0002/01/05/

		const origin = this.origin;
		const direction = this.direction;

		const dx = direction.x;
		const dy = direction.y;
		const dz = direction.z;

		// triangle vertices relative to the ray origin

		const aox = a.x - origin.x, aoy = a.y - origin.y, aoz = a.z - origin.z;
		const box = b.x - origin.x, boy = b.y - origin.y, boz = b.z - origin.z;
		const cox = c.x - origin.x, coy = c.y - origin.y, coz = c.z - origin.z;

		// Use the dimension where the ray direction is maximal as the projection
		// axis (kz) and read every component already permuted into (kx, ky, kz).
		// kx and ky are swapped when the direction's kz component is negative, to
		// preserve the winding order of triangles.

		const adx = Math.abs( dx ), ady = Math.abs( dy ), adz = Math.abs( dz );

		let dkx, dky, dkz;
		let akx, aky, akz, bkx, bky, bkz, ckx, cky, ckz;

		if ( adx >= ady && adx >= adz ) {

			dkz = dx; akz = aox; bkz = box; ckz = cox;

			if ( dx >= 0 ) {

				dkx = dy; dky = dz;
				akx = aoy; aky = aoz; bkx = boy; bky = boz; ckx = coy; cky = coz;

			} else {

				dkx = dz; dky = dy;
				akx = aoz; aky = aoy; bkx = boz; bky = boy; ckx = coz; cky = coy;

			}

		} else if ( ady >= adz ) {

			dkz = dy; akz = aoy; bkz = boy; ckz = coy;

			if ( dy >= 0 ) {

				dkx = dz; dky = dx;
				akx = aoz; aky = aox; bkx = boz; bky = box; ckx = coz; cky = cox;

			} else {

				dkx = dx; dky = dz;
				akx = aox; aky = aoz; bkx = box; bky = boz; ckx = cox; cky = coz;

			}

		} else {

			dkz = dz; akz = aoz; bkz = boz; ckz = coz;

			if ( dz >= 0 ) {

				dkx = dx; dky = dy;
				akx = aox; aky = aoy; bkx = box; bky = boy; ckx = cox; cky = coy;

			} else {

				dkx = dy; dky = dx;
				akx = aoy; aky = aox; bkx = boy; bky = box; ckx = coy; cky = cox;

			}

		}

		// a zero direction has no maximal axis and cannot intersect

		if ( dkz === 0 ) return null;

		// shear constants that align the ray with the +kz axis

		const sx = dkx / dkz, sy = dky / dkz, sz = 1 / dkz;

		// sheared and scaled vertices

		const ax = akx - sx * akz, ay = aky - sy * akz;
		const bx = bkx - sx * bkz, by = bky - sy * bkz;
		const cx = ckx - sx * ckz, cy = cky - sy * ckz;

		// scaled barycentric coordinates (signed edge functions); the shear makes a
		// shared edge evaluate identically for both adjacent triangles, so the ray
		// can never fall between them

		const u = cx * by - cy * bx;
		const v = ax * cy - ay * cx;
		const w = bx * ay - by * ax;

		if ( backfaceCulling ) {

			if ( u < 0 || v < 0 || w < 0 ) return null;

		} else {

			if ( ( u < 0 || v < 0 || w < 0 ) && ( u > 0 || v > 0 || w > 0 ) ) return null;

		}

		const det = u + v + w;

		// ray is co-planar with the triangle

		if ( det === 0 ) return null;

		// scaled hit distance; t = tScaled / det must lie in front of the origin

		const tScaled = sz * ( u * akz + v * bkz + w * ckz );

		if ( det > 0 ? tScaled < 0 : tScaled > 0 ) return null;

		return this.at( tScaled / det, target );

	}

	/**
	 * Transforms this ray with the given 4x4 transformation matrix.
	 *
	 * @param {Matrix4} matrix4 - The transformation matrix.
	 * @return {Ray} A reference to t