Initial project import
This commit is contained in:
243
node_modules/three-stdlib/math/OBB.js
generated
vendored
Normal file
243
node_modules/three-stdlib/math/OBB.js
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
import { Vector3, Matrix3, MathUtils, Box3, Matrix4, Ray } from "three";
|
||||
const a = {
|
||||
c: null,
|
||||
// center
|
||||
u: [/* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3()],
|
||||
// basis vectors
|
||||
e: []
|
||||
// half width
|
||||
};
|
||||
const b = {
|
||||
c: null,
|
||||
// center
|
||||
u: [/* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3()],
|
||||
// basis vectors
|
||||
e: []
|
||||
// half width
|
||||
};
|
||||
const R = [[], [], []];
|
||||
const AbsR = [[], [], []];
|
||||
const t = [];
|
||||
const xAxis = /* @__PURE__ */ new Vector3();
|
||||
const yAxis = /* @__PURE__ */ new Vector3();
|
||||
const zAxis = /* @__PURE__ */ new Vector3();
|
||||
const v1 = /* @__PURE__ */ new Vector3();
|
||||
const size = /* @__PURE__ */ new Vector3();
|
||||
const closestPoint = /* @__PURE__ */ new Vector3();
|
||||
const rotationMatrix = /* @__PURE__ */ new Matrix3();
|
||||
const aabb = /* @__PURE__ */ new Box3();
|
||||
const matrix = /* @__PURE__ */ new Matrix4();
|
||||
const inverse = /* @__PURE__ */ new Matrix4();
|
||||
const localRay = /* @__PURE__ */ new Ray();
|
||||
class OBB {
|
||||
constructor(center = new Vector3(), halfSize = new Vector3(), rotation = new Matrix3()) {
|
||||
this.center = center;
|
||||
this.halfSize = halfSize;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
set(center, halfSize, rotation) {
|
||||
this.center = center;
|
||||
this.halfSize = halfSize;
|
||||
this.rotation = rotation;
|
||||
return this;
|
||||
}
|
||||
copy(obb2) {
|
||||
this.center.copy(obb2.center);
|
||||
this.halfSize.copy(obb2.halfSize);
|
||||
this.rotation.copy(obb2.rotation);
|
||||
return this;
|
||||
}
|
||||
clone() {
|
||||
return new this.constructor().copy(this);
|
||||
}
|
||||
getSize(result) {
|
||||
return result.copy(this.halfSize).multiplyScalar(2);
|
||||
}
|
||||
/**
|
||||
* Reference: Closest Point on OBB to Point in Real-Time Collision Detection
|
||||
* by Christer Ericson (chapter 5.1.4)
|
||||
*/
|
||||
clampPoint(point, result) {
|
||||
const halfSize = this.halfSize;
|
||||
v1.subVectors(point, this.center);
|
||||
this.rotation.extractBasis(xAxis, yAxis, zAxis);
|
||||
result.copy(this.center);
|
||||
const x = MathUtils.clamp(v1.dot(xAxis), -halfSize.x, halfSize.x);
|
||||
result.add(xAxis.multiplyScalar(x));
|
||||
const y = MathUtils.clamp(v1.dot(yAxis), -halfSize.y, halfSize.y);
|
||||
result.add(yAxis.multiplyScalar(y));
|
||||
const z = MathUtils.clamp(v1.dot(zAxis), -halfSize.z, halfSize.z);
|
||||
result.add(zAxis.multiplyScalar(z));
|
||||
return result;
|
||||
}
|
||||
containsPoint(point) {
|
||||
v1.subVectors(point, this.center);
|
||||
this.rotation.extractBasis(xAxis, yAxis, zAxis);
|
||||
return Math.abs(v1.dot(xAxis)) <= this.halfSize.x && Math.abs(v1.dot(yAxis)) <= this.halfSize.y && Math.abs(v1.dot(zAxis)) <= this.halfSize.z;
|
||||
}
|
||||
intersectsBox3(box3) {
|
||||
return this.intersectsOBB(obb.fromBox3(box3));
|
||||
}
|
||||
intersectsSphere(sphere) {
|
||||
this.clampPoint(sphere.center, closestPoint);
|
||||
return closestPoint.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius;
|
||||
}
|
||||
/**
|
||||
* Reference: OBB-OBB Intersection in Real-Time Collision Detection
|
||||
* by Christer Ericson (chapter 4.4.1)
|
||||
*
|
||||
*/
|
||||
intersectsOBB(obb2, epsilon = Number.EPSILON) {
|
||||
a.c = this.center;
|
||||
a.e[0] = this.halfSize.x;
|
||||
a.e[1] = this.halfSize.y;
|
||||
a.e[2] = this.halfSize.z;
|
||||
this.rotation.extractBasis(a.u[0], a.u[1], a.u[2]);
|
||||
b.c = obb2.center;
|
||||
b.e[0] = obb2.halfSize.x;
|
||||
b.e[1] = obb2.halfSize.y;
|
||||
b.e[2] = obb2.halfSize.z;
|
||||
obb2.rotation.extractBasis(b.u[0], b.u[1], b.u[2]);
|
||||
for (let i = 0; i < 3; i++) {
|
||||
for (let j = 0; j < 3; j++) {
|
||||
R[i][j] = a.u[i].dot(b.u[j]);
|
||||
}
|
||||
}
|
||||
v1.subVectors(b.c, a.c);
|
||||
t[0] = v1.dot(a.u[0]);
|
||||
t[1] = v1.dot(a.u[1]);
|
||||
t[2] = v1.dot(a.u[2]);
|
||||
for (let i = 0; i < 3; i++) {
|
||||
for (let j = 0; j < 3; j++) {
|
||||
AbsR[i][j] = Math.abs(R[i][j]) + epsilon;
|
||||
}
|
||||
}
|
||||
let ra, rb;
|
||||
for (let i = 0; i < 3; i++) {
|
||||
ra = a.e[i];
|
||||
rb = b.e[0] * AbsR[i][0] + b.e[1] * AbsR[i][1] + b.e[2] * AbsR[i][2];
|
||||
if (Math.abs(t[i]) > ra + rb)
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < 3; i++) {
|
||||
ra = a.e[0] * AbsR[0][i] + a.e[1] * AbsR[1][i] + a.e[2] * AbsR[2][i];
|
||||
rb = b.e[i];
|
||||
if (Math.abs(t[0] * R[0][i] + t[1] * R[1][i] + t[2] * R[2][i]) > ra + rb)
|
||||
return false;
|
||||
}
|
||||
ra = a.e[1] * AbsR[2][0] + a.e[2] * AbsR[1][0];
|
||||
rb = b.e[1] * AbsR[0][2] + b.e[2] * AbsR[0][1];
|
||||
if (Math.abs(t[2] * R[1][0] - t[1] * R[2][0]) > ra + rb)
|
||||
return false;
|
||||
ra = a.e[1] * AbsR[2][1] + a.e[2] * AbsR[1][1];
|
||||
rb = b.e[0] * AbsR[0][2] + b.e[2] * AbsR[0][0];
|
||||
if (Math.abs(t[2] * R[1][1] - t[1] * R[2][1]) > ra + rb)
|
||||
return false;
|
||||
ra = a.e[1] * AbsR[2][2] + a.e[2] * AbsR[1][2];
|
||||
rb = b.e[0] * AbsR[0][1] + b.e[1] * AbsR[0][0];
|
||||
if (Math.abs(t[2] * R[1][2] - t[1] * R[2][2]) > ra + rb)
|
||||
return false;
|
||||
ra = a.e[0] * AbsR[2][0] + a.e[2] * AbsR[0][0];
|
||||
rb = b.e[1] * AbsR[1][2] + b.e[2] * AbsR[1][1];
|
||||
if (Math.abs(t[0] * R[2][0] - t[2] * R[0][0]) > ra + rb)
|
||||
return false;
|
||||
ra = a.e[0] * AbsR[2][1] + a.e[2] * AbsR[0][1];
|
||||
rb = b.e[0] * AbsR[1][2] + b.e[2] * AbsR[1][0];
|
||||
if (Math.abs(t[0] * R[2][1] - t[2] * R[0][1]) > ra + rb)
|
||||
return false;
|
||||
ra = a.e[0] * AbsR[2][2] + a.e[2] * AbsR[0][2];
|
||||
rb = b.e[0] * AbsR[1][1] + b.e[1] * AbsR[1][0];
|
||||
if (Math.abs(t[0] * R[2][2] - t[2] * R[0][2]) > ra + rb)
|
||||
return false;
|
||||
ra = a.e[0] * AbsR[1][0] + a.e[1] * AbsR[0][0];
|
||||
rb = b.e[1] * AbsR[2][2] + b.e[2] * AbsR[2][1];
|
||||
if (Math.abs(t[1] * R[0][0] - t[0] * R[1][0]) > ra + rb)
|
||||
return false;
|
||||
ra = a.e[0] * AbsR[1][1] + a.e[1] * AbsR[0][1];
|
||||
rb = b.e[0] * AbsR[2][2] + b.e[2] * AbsR[2][0];
|
||||
if (Math.abs(t[1] * R[0][1] - t[0] * R[1][1]) > ra + rb)
|
||||
return false;
|
||||
ra = a.e[0] * AbsR[1][2] + a.e[1] * AbsR[0][2];
|
||||
rb = b.e[0] * AbsR[2][1] + b.e[1] * AbsR[2][0];
|
||||
if (Math.abs(t[1] * R[0][2] - t[0] * R[1][2]) > ra + rb)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Reference: Testing Box Against Plane in Real-Time Collision Detection
|
||||
* by Christer Ericson (chapter 5.2.3)
|
||||
*/
|
||||
intersectsPlane(plane) {
|
||||
this.rotation.extractBasis(xAxis, yAxis, zAxis);
|
||||
const r = this.halfSize.x * Math.abs(plane.normal.dot(xAxis)) + this.halfSize.y * Math.abs(plane.normal.dot(yAxis)) + this.halfSize.z * Math.abs(plane.normal.dot(zAxis));
|
||||
const d = plane.normal.dot(this.center) - plane.constant;
|
||||
return Math.abs(d) <= r;
|
||||
}
|
||||
/**
|
||||
* Performs a ray/OBB intersection test and stores the intersection point
|
||||
* to the given 3D vector. If no intersection is detected, *null* is returned.
|
||||
*/
|
||||
intersectRay(ray, result) {
|
||||
this.getSize(size);
|
||||
aabb.setFromCenterAndSize(v1.set(0, 0, 0), size);
|
||||
matrix.setFromMatrix3(this.rotation);
|
||||
matrix.setPosition(this.center);
|
||||
inverse.copy(matrix).invert();
|
||||
localRay.copy(ray).applyMatrix4(inverse);
|
||||
if (localRay.intersectBox(aabb, result)) {
|
||||
return result.applyMatrix4(matrix);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Performs a ray/OBB intersection test. Returns either true or false if
|
||||
* there is a intersection or not.
|
||||
*/
|
||||
intersectsRay(ray) {
|
||||
return this.intersectRay(ray, v1) !== null;
|
||||
}
|
||||
fromBox3(box3) {
|
||||
box3.getCenter(this.center);
|
||||
box3.getSize(this.halfSize).multiplyScalar(0.5);
|
||||
this.rotation.identity();
|
||||
return this;
|
||||
}
|
||||
equals(obb2) {
|
||||
return obb2.center.equals(this.center) && obb2.halfSize.equals(this.halfSize) && obb2.rotation.equals(this.rotation);
|
||||
}
|
||||
applyMatrix4(matrix2) {
|
||||
const e = matrix2.elements;
|
||||
let sx = v1.set(e[0], e[1], e[2]).length();
|
||||
const sy = v1.set(e[4], e[5], e[6]).length();
|
||||
const sz = v1.set(e[8], e[9], e[10]).length();
|
||||
const det = matrix2.determinant();
|
||||
if (det < 0)
|
||||
sx = -sx;
|
||||
rotationMatrix.setFromMatrix4(matrix2);
|
||||
const invSX = 1 / sx;
|
||||
const invSY = 1 / sy;
|
||||
const invSZ = 1 / sz;
|
||||
rotationMatrix.elements[0] *= invSX;
|
||||
rotationMatrix.elements[1] *= invSX;
|
||||
rotationMatrix.elements[2] *= invSX;
|
||||
rotationMatrix.elements[3] *= invSY;
|
||||
rotationMatrix.elements[4] *= invSY;
|
||||
rotationMatrix.elements[5] *= invSY;
|
||||
rotationMatrix.elements[6] *= invSZ;
|
||||
rotationMatrix.elements[7] *= invSZ;
|
||||
rotationMatrix.elements[8] *= invSZ;
|
||||
this.rotation.multiply(rotationMatrix);
|
||||
this.halfSize.x *= sx;
|
||||
this.halfSize.y *= sy;
|
||||
this.halfSize.z *= sz;
|
||||
v1.setFromMatrixPosition(matrix2);
|
||||
this.center.add(v1);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
const obb = /* @__PURE__ */ new OBB();
|
||||
export {
|
||||
OBB
|
||||
};
|
||||
//# sourceMappingURL=OBB.js.map
|
||||
Reference in New Issue
Block a user