UNPKG

@turbox3d/math

Version:

Large-scale graphics application math library

228 lines 8.69 kB
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; import _createClass from "@babel/runtime/helpers/esm/createClass"; import { Vector3 } from './Vector3'; import { Tolerance } from './Tolerance'; import { MathUtils } from '../MathUtils'; var _points = [new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3()]; var _vector = new Vector3(); var Box3 = /*#__PURE__*/function () { function Box3(min, max) { _classCallCheck(this, Box3); this.isBox3 = true; this.min = min !== undefined ? min : new Vector3(+Infinity, +Infinity, +Infinity); this.max = max !== undefined ? max : new Vector3(-Infinity, -Infinity, -Infinity); } return _createClass(Box3, [{ key: "set", value: function set(min, max) { this.min.copy(min); this.max.copy(max); return this; } }, { key: "setFromArray", value: function setFromArray(array) { var minX = +Infinity; var minY = +Infinity; var minZ = +Infinity; var maxX = -Infinity; var maxY = -Infinity; var maxZ = -Infinity; for (var i = 0, l = array.length; i < l; i += 3) { var x = array[i]; var y = array[i + 1]; var z = array[i + 2]; if (x < minX) minX = x; if (y < minY) minY = y; if (z < minZ) minZ = z; if (x > maxX) maxX = x; if (y > maxY) maxY = y; if (z > maxZ) maxZ = z; } this.min.set(minX, minY, minZ); this.max.set(maxX, maxY, maxZ); return this; } }, { key: "setFromPoints", value: function setFromPoints(points) { this.makeEmpty(); for (var i = 0, il = points.length; i < il; i++) { this.expandByPoint(points[i]); } return this; } }, { key: "setFromCenterAndSize", value: function setFromCenterAndSize(center, size) { var halfSize = _vector.copy(size).multiplyScalar(0.5); this.min.copy(center).sub(halfSize); this.max.copy(center).add(halfSize); return this; } }, { key: "clone", value: function clone() { return new Box3().copy(this); } }, { key: "copy", value: function copy(box) { this.min.copy(box.min); this.max.copy(box.max); return this; } }, { key: "makeEmpty", value: function makeEmpty() { // eslint-disable-next-line no-multi-assign this.min.x = this.min.y = this.min.z = +Infinity; // eslint-disable-next-line no-multi-assign this.max.x = this.max.y = this.max.z = -Infinity; return this; } }, { key: "isEmpty", value: function isEmpty() { // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z; } }, { key: "getCenter", value: function getCenter(target) { return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); } }, { key: "getSize", value: function getSize(target) { return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min); } }, { key: "expandByPoint", value: function expandByPoint(point) { this.min.min(point); this.max.max(point); return this; } }, { key: "expandByVector", value: function expandByVector(vector) { this.min.sub(vector); this.max.add(vector); return this; } }, { key: "expandByScalar", value: function expandByScalar(scalar) { this.min.addScalar(-scalar); this.max.addScalar(scalar); return this; } }, { key: "containsPoint", value: function containsPoint(point) { var distTol = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Tolerance.global.distTol; return !(MathUtils.isSmaller(point.x, this.min.x, distTol) || MathUtils.isBigger(point.x, this.max.x, distTol) || MathUtils.isSmaller(point.y, this.min.y, distTol) || MathUtils.isBigger(point.y, this.max.y, distTol) || MathUtils.isSmaller(point.z, this.min.z, distTol) || MathUtils.isBigger(point.z, this.max.z, distTol)); } }, { key: "containsBox", value: function containsBox(box) { var distTol = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Tolerance.global.distTol; return MathUtils.isSmallerOrEqual(this.min.x, box.min.x, distTol) && MathUtils.isSmallerOrEqual(box.max.x, this.max.x, distTol) && MathUtils.isSmallerOrEqual(this.min.y, box.min.y, distTol) && MathUtils.isSmallerOrEqual(box.max.y, this.max.y, distTol) && MathUtils.isSmallerOrEqual(this.min.z, box.min.z, distTol) && MathUtils.isSmallerOrEqual(box.max.z, this.max.z, distTol); } }, { key: "isOverlapping", value: function isOverlapping(box) { var distTol = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Tolerance.global.distTol; if (!box.isValid()) { return false; } if (MathUtils.isSmaller(this.max.x, box.min.x, distTol) || MathUtils.isBigger(this.min.x, box.max.x, distTol)) { return false; } if (MathUtils.isSmaller(this.max.y, box.min.y, distTol) || MathUtils.isBigger(this.min.y, box.max.y, distTol)) { return false; } if (MathUtils.isSmaller(this.max.z, box.min.z, distTol) || MathUtils.isBigger(this.min.z, box.max.z, distTol)) { return false; } return true; } }, { key: "getParameter", value: function getParameter(point, target) { // This can potentially have a divide by zero if the box // has a size dimension of 0. return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y), (point.z - this.min.z) / (this.max.z - this.min.z)); } }, { key: "intersectsBox", value: function intersectsBox(box) { // using 6 splitting planes to rule out intersections. return !(box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y || box.max.z < this.min.z || box.min.z > this.max.z); } }, { key: "clampPoint", value: function clampPoint(point, target) { return target.copy(point).clamp(this.min, this.max); } }, { key: "distanceToPoint", value: function distanceToPoint(point) { var clampedPoint = _vector.copy(point).clamp(this.min, this.max); return clampedPoint.sub(point).length; } }, { key: "intersect", value: function intersect(box) { this.min.max(box.min); this.max.min(box.max); // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. if (this.isEmpty()) this.makeEmpty(); return this; } }, { key: "union", value: function union(box) { this.min.min(box.min); this.max.max(box.max); return this; } }, { key: "applyMatrix4", value: function applyMatrix4(matrix) { // transform of empty box is an empty box. if (this.isEmpty()) return this; // NOTE: I am using a binary pattern to specify all 2^3 combinations below _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); // 000 _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); // 001 _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); // 010 _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); // 011 _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); // 100 _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); // 101 _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); // 110 _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); // 111 this.setFromPoints(_points); return this; } }, { key: "translate", value: function translate(offset) { this.min.add(offset); this.max.add(offset); return this; } }, { key: "equals", value: function equals(box) { var distTol = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Tolerance.global.distTol; return box.min.equals(this.min, distTol) && box.max.equals(this.max, distTol); } }, { key: "isValid", value: function isValid() { return this.min.x <= this.max.x && this.min.y <= this.max.y && this.min.z <= this.max.z; } }]); }(); export { Box3 };