playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
111 lines (110 loc) • 3.62 kB
JavaScript
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 { Mat4 } from "../math/mat4.js";
import { Vec3 } from "../math/vec3.js";
import { BoundingBox } from "./bounding-box.js";
import { BoundingSphere } from "./bounding-sphere.js";
import { Ray } from "./ray.js";
const tmpRay = new Ray();
const tmpVec3 = new Vec3();
const tmpSphere = new BoundingSphere();
const tmpMat4 = new Mat4();
class OrientedBox {
/**
* Create a new OrientedBox instance.
*
* @param {Mat4} [worldTransform] - Transform that has the orientation and position of the box.
* Scale is assumed to be one. Defaults to identity matrix.
* @param {Vec3} [halfExtents] - Half the distance across the box in each local axis. Defaults
* to (0.5, 0.5, 0.5).
*/
constructor(worldTransform = new Mat4(), halfExtents) {
/** @private */
__publicField(this, "halfExtents", new Vec3(0.5, 0.5, 0.5));
/**
* @type {Mat4}
* @private
*/
__publicField(this, "_modelTransform");
/**
* @type {Mat4}
* @private
*/
__publicField(this, "_worldTransform");
/**
* @type {BoundingBox}
* @private
*/
__publicField(this, "_aabb");
if (halfExtents) {
this.halfExtents.copy(halfExtents);
}
this._modelTransform = worldTransform.clone().invert();
this._worldTransform = worldTransform.clone();
this._aabb = new BoundingBox(new Vec3(), this.halfExtents);
}
/**
* Sets the world transform of the OBB.
*
* @type {Mat4}
*/
set worldTransform(value) {
this._worldTransform.copy(value);
this._modelTransform.copy(value).invert();
}
/**
* Gets the world transform of the OBB.
*
* @type {Mat4}
*/
get worldTransform() {
return this._worldTransform;
}
/**
* Test if a ray intersects with the OBB.
*
* @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) {
this._modelTransform.transformPoint(ray.origin, tmpRay.origin);
this._modelTransform.transformVector(ray.direction, tmpRay.direction);
if (point) {
const result = this._aabb._intersectsRay(tmpRay, point);
tmpMat4.copy(this._modelTransform).invert().transformPoint(point, point);
return result;
}
return this._aabb._fastIntersectsRay(tmpRay);
}
/**
* Test if a point is inside an OBB.
*
* @param {Vec3} point - Point to test.
* @returns {boolean} True if the point is inside the OBB and false otherwise.
*/
containsPoint(point) {
this._modelTransform.transformPoint(point, tmpVec3);
return this._aabb.containsPoint(tmpVec3);
}
/**
* Test if a Bounding Sphere is overlapping, enveloping, or inside this OBB.
*
* @param {BoundingSphere} sphere - Bounding Sphere to test.
* @returns {boolean} True if the Bounding Sphere is overlapping, enveloping or inside this OBB
* and false otherwise.
*/
intersectsBoundingSphere(sphere) {
this._modelTransform.transformPoint(sphere.center, tmpSphere.center);
tmpSphere.radius = sphere.radius;
if (this._aabb.intersectsBoundingSphere(tmpSphere)) {
return true;
}
return false;
}
}
export {
OrientedBox
};