Buckets:
| 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 | |
Xet Storage Details
- Size:
- 8.46 kB
- Xet hash:
- e4b4236b00452a65f078d8dd23a91bfcb38d34bd79baa3d2ef0b3418e97c7a3f
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.