UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

128 lines (127 loc) 3.9 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import { Vec3 } from "../math/vec3.js"; class Plane { /** * Create a new Plane instance. * * @param {Vec3} [normal] - Normal of the plane. The constructor copies this parameter. Defaults * to {@link Vec3.UP}. * @param {number} [distance] - The distance from the plane to the origin, along its normal. * Defaults to 0. */ constructor(normal = Vec3.UP, distance = 0) { /** * The normal of the plane. */ __publicField(this, "normal", new Vec3()); /** * The distance from the plane to the origin, along its normal. * * @type {number} */ __publicField(this, "distance"); this.normal.copy(normal); this.distance = distance; } /** * Returns a clone of the specified plane. * * @returns {this} A duplicate plane. */ clone() { const cstr = this.constructor; return new cstr().copy(this); } /** * Copies the contents of a source plane to a destination plane. * * @param {Plane} src - A source plane to copy to the destination plane. * @returns {Plane} Self for chaining. */ copy(src) { this.normal.copy(src.normal); this.distance = src.distance; return this; } /** * Test if the plane intersects between two points. * * @param {Vec3} start - Start position of line. * @param {Vec3} end - End position of line. * @param {Vec3} [point] - If there is an intersection, the intersection point will be copied * into here. * @returns {boolean} True if there is an intersection. */ intersectsLine(start, end, point) { const d = this.distance; const d0 = this.normal.dot(start) + d; const d1 = this.normal.dot(end) + d; const t = d0 / (d0 - d1); const intersects = t >= 0 && t <= 1; if (intersects && point) { point.lerp(start, end, t); } return intersects; } /** * Test if a ray intersects with the infinite plane. * * @param {Ray} ray - Ray to test against (direction must be normalized). * @param {Vec3} [point] - If there is an intersection, the intersection point will be copied * into here. * @returns {boolean} True if there is an intersection. */ intersectsRay(ray, point) { const denominator = this.normal.dot(ray.direction); if (denominator === 0) { return false; } const t = -(this.normal.dot(ray.origin) + this.distance) / denominator; if (t >= 0 && point) { point.copy(ray.direction).mulScalar(t).add(ray.origin); } return t >= 0; } /** * Normalize the plane. * * @returns {Plane} Self for chaining. */ normalize() { const invLength = 1 / this.normal.length(); this.normal.mulScalar(invLength); this.distance *= invLength; return this; } /** * Sets the plane based on a normal and a distance from the origin. * * @param {number} nx - The x-component of the normal. * @param {number} ny - The y-component of the normal. * @param {number} nz - The z-component of the normal. * @param {number} d - The distance from the origin. * @returns {Plane} Self for chaining. */ set(nx, ny, nz, d) { this.normal.set(nx, ny, nz); this.distance = d; return this; } /** * Sets the plane based on a specified normal and a point on the plane. * * @param {Vec3} point - The point on the plane. * @param {Vec3} normal - The normal of the plane. * @returns {Plane} Self for chaining. */ setFromPointNormal(point, normal) { this.normal.copy(normal); this.distance = -this.normal.dot(point); return this; } } export { Plane };