@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
106 lines (78 loc) • 2.77 kB
JavaScript
import { v3_distance_above_plane } from "../../../../core/geom/vec3/v3_distance_above_plane.js";
import {
plane3_three_compute_convex_3_plane_intersection
} from "../../../../core/geom/3d/plane/plane3_three_compute_convex_3_plane_intersection.js";
/**
*
* @param {function(function(Plane))} traversePlanes
* @param {number} [bias=0]
* @returns {Function}
*/
export function buildPlanarRenderLayerClipPlaneComputationMethod(traversePlanes, bias = 0) {
/**
*
* @type {number[]}
*/
const p = [];
const adjacentPlanePairs = [
[],
[],
[],
[]
];
const range = {
near: 0,
far: 0
};
let nearPlane;
/**
*
* @param {Plane} objectPlane
*/
function visitPlane(objectPlane) {
for (let i = 0; i < 4; i++) {
const pair = adjacentPlanePairs[i];
const p0 = pair[0];
const p1 = pair[1];
const planeIntersection = plane3_three_compute_convex_3_plane_intersection(p, 0, p0, p1, objectPlane);
if (!planeIntersection) {
//no intersection
continue;
}
const plane_normal = nearPlane.normal;
const distanceToNearPlane = v3_distance_above_plane(p[0], p[1], p[2], plane_normal.x, plane_normal.y, plane_normal.z, nearPlane.constant);
//update near and far plane distances
if (distanceToNearPlane > 0 && distanceToNearPlane < range.near) {
range.near = distanceToNearPlane;
}
if (distanceToNearPlane > range.far) {
range.far = distanceToNearPlane;
}
}
}
/**
*
* @param {Frustum} frustum
* @param {number} near
* @param {number} far
* @param {function(near:number, far:number)} visitor
*/
return function (frustum, near, far, visitor, thisArg) {
const frustumPlanes = frustum.planes;
nearPlane = frustumPlanes[5];
adjacentPlanePairs[0][0] = frustumPlanes[0];
adjacentPlanePairs[0][1] = frustumPlanes[2];
adjacentPlanePairs[1][0] = frustumPlanes[0];
adjacentPlanePairs[1][1] = frustumPlanes[3];
adjacentPlanePairs[2][0] = frustumPlanes[1];
adjacentPlanePairs[2][1] = frustumPlanes[2];
adjacentPlanePairs[3][0] = frustumPlanes[1];
adjacentPlanePairs[3][1] = frustumPlanes[3];
range.near = near;
range.far = far;
traversePlanes(visitPlane);
if (range.near <= range.far) {
visitor.call(thisArg, range.near - bias, range.far + bias);
}
};
}