UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

87 lines (72 loc) 2.63 kB
import { v4_dot } from "../../vec4/v4_dot.js"; import Vector3 from "../../Vector3.js"; const V1 = new Vector3(); const V2 = new Vector3(); /** * 2,0,or -2; 2: above, -2 : below, 0 : intersects plane * NOTE: used an article by Bart Wronski https://bartwronski.com/2017/04/13/cull-that-cone/ * @param {number} plane_normal_x * @param {number} plane_normal_y * @param {number} plane_normal_z * @param {number} plane_constant * @param {number} originX * @param {number} originY * @param {number} originZ * @param {number} directionX * @param {number} directionY * @param {number} directionZ * @param {number} angle * @param {number} length * @returns {number} */ export function computeConePlaneSide( plane_normal_x, plane_normal_y, plane_normal_z, plane_constant, originX, originY, originZ, directionX, directionY, directionZ, angle, length ) { /* ORIGINAL HLSL: bool TestConeVsPlane(in float3 origin, in float3 forward, in float size, in float angle, in float4 testPlane) { const float3 V1 = cross(testPlane.xyz, forward); const float3 V2 = cross(V1, forward); const float3 capRimPoint = origin + size * cos(angle) * forward + size * sin(angle) * V2; return dot(float4(capRimPoint, 1.0f), testPlane) >= 0.0f || dot(float4(origin, 1.0f), testPlane) >= 0.0f; } */ V1._crossVectors(plane_normal_x, plane_normal_y, plane_normal_z, directionX, directionY, directionZ); V2._crossVectors(V1.x, V1.y, V1.z, directionX, directionY, directionZ); const scaled_cos = length * Math.cos(angle); const scaled_sin = length * Math.sin(angle); // compute cap rim point (closest point to the plane on the wide side of the cone) V1.set( originX + scaled_cos * directionX + scaled_sin * V2.x, originY + scaled_cos * directionY + scaled_sin * V2.y, originZ + scaled_cos * directionZ + scaled_sin * V2.z ); const rim_point_side = v4_dot( V1.x, V1.y, V1.z, 1, plane_normal_x, plane_normal_y, plane_normal_z, plane_constant ); const origin_point_side = v4_dot( originX, originY, originZ, 1, plane_normal_x, plane_normal_y, plane_normal_z, plane_constant ); let result = 0; if (rim_point_side >= 0) { result += 1; } else { result -= 1; } if (origin_point_side >= 0) { result += 1; } else { result -= 1; } return result; }