mirror of https://gitee.com/cf-fz/WebCAD.git
parent
e312df83ed
commit
1c1347d462
@ -1,249 +1,15 @@
|
|||||||
import { Vector3, Matrix4 } from 'three';
|
|
||||||
|
|
||||||
// Quote from:
|
import { Matrix3, Matrix4, Vector3 } from 'three';
|
||||||
// https://github.com/Mugen87/yume/blob/master/src/javascript/engine/etc/OBB.js
|
import { OBB } from "three/examples/jsm/math/OBB";
|
||||||
// 即obb.js(本项目中已存在)
|
|
||||||
|
|
||||||
// Reference material:
|
/**
|
||||||
//https://stackoverflow.com/questions/28499800/oriented-box-intersection-in-threejs
|
* @param ocs 坐标系
|
||||||
//http://www.cnblogs.com/iamzhanglei/archive/2012/06/07/2539751.html
|
* @param size 尺寸
|
||||||
//https://github.com/Mugen87/yume/blob/master/src/javascript/engine/etc/OBB.js
|
* @returns OBB
|
||||||
|
*/
|
||||||
export class OBB
|
export function GetObbFromOcsSize(ocs: Matrix4, size: Vector3): OBB
|
||||||
{
|
{
|
||||||
_EPSILON = 1e-3;
|
size = size.clone().multiplyScalar(0.5);
|
||||||
|
let center = size.clone().applyMatrix4(ocs);
|
||||||
public center: Vector3;
|
return new OBB(center, size, new Matrix3().setFromMatrix4(ocs));
|
||||||
|
|
||||||
constructor(public ocs: Matrix4, public halfSizes: Vector3)
|
|
||||||
{
|
|
||||||
this.center = halfSizes.clone().applyMatrix4(ocs);
|
|
||||||
}
|
|
||||||
|
|
||||||
intersectsOBB(obb: OBB, is2D?: boolean, ucsInv?: Matrix4): boolean
|
|
||||||
{
|
|
||||||
let newCenter: Vector3;
|
|
||||||
let newObbCenter: Vector3;
|
|
||||||
let cs: Matrix4;
|
|
||||||
let obbcs: Matrix4;
|
|
||||||
if (is2D)
|
|
||||||
{
|
|
||||||
let mtx1 = new Matrix4().multiplyMatrices(ucsInv, this.ocs);
|
|
||||||
let mtx2 = new Matrix4().multiplyMatrices(ucsInv, obb.ocs);
|
|
||||||
cs = mtx1;
|
|
||||||
obbcs = mtx2;
|
|
||||||
cs.elements[14] = 0;
|
|
||||||
obbcs.elements[14] = 0;
|
|
||||||
newCenter = this.halfSizes.clone().applyMatrix4(cs);
|
|
||||||
newObbCenter = obb.halfSizes.clone().applyMatrix4(obbcs);
|
|
||||||
}
|
|
||||||
let xAxisA = new Vector3();
|
|
||||||
let yAxisA = new Vector3();
|
|
||||||
let zAxisA = new Vector3();
|
|
||||||
|
|
||||||
let xAxisB = new Vector3();
|
|
||||||
let yAxisB = new Vector3();
|
|
||||||
let zAxisB = new Vector3();
|
|
||||||
|
|
||||||
let translation = new Vector3();
|
|
||||||
|
|
||||||
let vector = new Vector3();
|
|
||||||
|
|
||||||
let axisA: Vector3[] = [];
|
|
||||||
let axisB: Vector3[] = [];
|
|
||||||
let rotationMatrix = [[], [], []];
|
|
||||||
let rotationMatrixAbs = [[], [], []];
|
|
||||||
|
|
||||||
let halfSizeA: number, halfSizeB: number;
|
|
||||||
let t: number, i: number;
|
|
||||||
|
|
||||||
// extract each axis
|
|
||||||
(cs ?? this.ocs).extractBasis(xAxisA, yAxisA, zAxisA);
|
|
||||||
(obbcs ?? obb.ocs).extractBasis(xAxisB, yAxisB, zAxisB);
|
|
||||||
|
|
||||||
// push basis vectors into arrays, so you can access them via indices
|
|
||||||
axisA.push(xAxisA, yAxisA, zAxisA);
|
|
||||||
axisB.push(xAxisB, yAxisB, zAxisB);
|
|
||||||
|
|
||||||
// get displacement vector
|
|
||||||
vector.subVectors(newObbCenter ?? obb.center, newCenter ?? this.center);
|
|
||||||
|
|
||||||
// express the translation vector in the coordinate frame of the current
|
|
||||||
// OBB (this)
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
translation.setComponent(i, vector.dot(axisA[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate a rotation matrix that transforms from world space to the
|
|
||||||
// OBB's coordinate space
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
for (let j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
rotationMatrix[i][j] = axisA[i].dot(axisB[j]);
|
|
||||||
rotationMatrixAbs[i][j] = Math.abs(rotationMatrix[i][j]) + this._EPSILON;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// test the three major axes of this OBB
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
vector.set(rotationMatrixAbs[i][0], rotationMatrixAbs[i][1], rotationMatrixAbs[i][2]);
|
|
||||||
|
|
||||||
halfSizeA = this.halfSizes.getComponent(i);
|
|
||||||
halfSizeB = obb.halfSizes.dot(vector);
|
|
||||||
|
|
||||||
if (Math.abs(translation.getComponent(i)) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// test the three major axes of other OBB
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
vector.set(rotationMatrixAbs[0][i], rotationMatrixAbs[1][i], rotationMatrixAbs[2][i]);
|
|
||||||
|
|
||||||
halfSizeA = this.halfSizes.dot(vector);
|
|
||||||
halfSizeB = obb.halfSizes.getComponent(i);
|
|
||||||
|
|
||||||
vector.set(rotationMatrix[0][i], rotationMatrix[1][i], rotationMatrix[2][i]);
|
|
||||||
t = translation.dot(vector);
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// test the 9 different cross-axes
|
|
||||||
|
|
||||||
// A.x <cross> B.x
|
|
||||||
halfSizeA = this.halfSizes.y * rotationMatrixAbs[2][0] + this.halfSizes.z * rotationMatrixAbs[1][0];
|
|
||||||
halfSizeB = obb.halfSizes.y * rotationMatrixAbs[0][2] + obb.halfSizes.z * rotationMatrixAbs[0][1];
|
|
||||||
|
|
||||||
t = translation.z * rotationMatrix[1][0] - translation.y * rotationMatrix[2][0];
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A.x < cross> B.y
|
|
||||||
halfSizeA = this.halfSizes.y * rotationMatrixAbs[2][1] + this.halfSizes.z * rotationMatrixAbs[1][1];
|
|
||||||
halfSizeB = obb.halfSizes.x * rotationMatrixAbs[0][2] + obb.halfSizes.z * rotationMatrixAbs[0][0];
|
|
||||||
|
|
||||||
t = translation.z * rotationMatrix[1][1] - translation.y * rotationMatrix[2][1];
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A.x <cross> B.z
|
|
||||||
halfSizeA = this.halfSizes.y * rotationMatrixAbs[2][2] + this.halfSizes.z * rotationMatrixAbs[1][2];
|
|
||||||
halfSizeB = obb.halfSizes.x * rotationMatrixAbs[0][1] + obb.halfSizes.y * rotationMatrixAbs[0][0];
|
|
||||||
|
|
||||||
t = translation.z * rotationMatrix[1][2] - translation.y * rotationMatrix[2][2];
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A.y <cross> B.x
|
|
||||||
halfSizeA = this.halfSizes.x * rotationMatrixAbs[2][0] + this.halfSizes.z * rotationMatrixAbs[0][0];
|
|
||||||
halfSizeB = obb.halfSizes.y * rotationMatrixAbs[1][2] + obb.halfSizes.z * rotationMatrixAbs[1][1];
|
|
||||||
|
|
||||||
t = translation.x * rotationMatrix[2][0] - translation.z * rotationMatrix[0][0];
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A.y <cross> B.y
|
|
||||||
halfSizeA = this.halfSizes.x * rotationMatrixAbs[2][1] + this.halfSizes.z * rotationMatrixAbs[0][1];
|
|
||||||
halfSizeB = obb.halfSizes.x * rotationMatrixAbs[1][2] + obb.halfSizes.z * rotationMatrixAbs[1][0];
|
|
||||||
|
|
||||||
t = translation.x * rotationMatrix[2][1] - translation.z * rotationMatrix[0][1];
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A.y <cross> B.z
|
|
||||||
halfSizeA = this.halfSizes.x * rotationMatrixAbs[2][2] + this.halfSizes.z * rotationMatrixAbs[0][2];
|
|
||||||
halfSizeB = obb.halfSizes.x * rotationMatrixAbs[1][1] + obb.halfSizes.y * rotationMatrixAbs[1][0];
|
|
||||||
|
|
||||||
t = translation.x * rotationMatrix[2][2] - translation.z * rotationMatrix[0][2];
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A.z <cross> B.x
|
|
||||||
halfSizeA = this.halfSizes.x * rotationMatrixAbs[1][0] + this.halfSizes.y * rotationMatrixAbs[0][0];
|
|
||||||
halfSizeB = obb.halfSizes.y * rotationMatrixAbs[2][2] + obb.halfSizes.z * rotationMatrixAbs[2][1];
|
|
||||||
|
|
||||||
t = translation.y * rotationMatrix[0][0] - translation.x * rotationMatrix[1][0];
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A.z <cross> B.y
|
|
||||||
halfSizeA = this.halfSizes.x * rotationMatrixAbs[1][1] + this.halfSizes.y * rotationMatrixAbs[0][1];
|
|
||||||
halfSizeB = obb.halfSizes.x * rotationMatrixAbs[2][2] + obb.halfSizes.z * rotationMatrixAbs[2][0];
|
|
||||||
|
|
||||||
t = translation.y * rotationMatrix[0][1] - translation.x * rotationMatrix[1][1];
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A.z <cross> B.z
|
|
||||||
halfSizeA = this.halfSizes.x * rotationMatrixAbs[1][2] + this.halfSizes.y * rotationMatrixAbs[0][2];
|
|
||||||
halfSizeB = obb.halfSizes.x * rotationMatrixAbs[2][1] + obb.halfSizes.y * rotationMatrixAbs[2][0];
|
|
||||||
|
|
||||||
t = translation.y * rotationMatrix[0][2] - translation.x * rotationMatrix[1][2];
|
|
||||||
|
|
||||||
if (Math.abs(t) > halfSizeA + halfSizeB)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no separating axis exists, so the two OBB don't intersect
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// setFromObject(obj: THREE.Mesh): OBB;
|
|
||||||
// setFromAABB(aabb: THREE.Box3): OBB;
|
|
||||||
|
|
||||||
// setFromSphere(sphere: THREE.Shape): OBB;
|
|
||||||
|
|
||||||
// closestPoint(point: THREE.Vector3): THREE.Vector3
|
|
||||||
// isPointContained(point: THREE.Vector3): boolean
|
|
||||||
// isAABBContained(aabb: THREE.Box3): boolean
|
|
||||||
// isLineContained(line: THREE.Line3): boolean
|
|
||||||
// isTriangleContained(tarianlg: THREE.Triangle): boolean
|
|
||||||
// intersectsAABB(box: THREE.Box3): boolean
|
|
||||||
// intersectsSphere(sphere: THREE.Sphere): boolean
|
|
||||||
// intersectsOBB(box: OBB): boolean;
|
|
||||||
// intersectsPlane(plane: Plane): boolean
|
|
||||||
// intersectsRay(ray: Ray): boolean
|
|
||||||
// intersectRay(ray: Ray): Vector3
|
|
||||||
// intersectSphere(sphere: Sphere): Vector3
|
|
||||||
// size(optionalTarget: Vector3): Vector3
|
|
||||||
|
|
||||||
// translate(offset: Vector3): OBB
|
|
||||||
|
|
||||||
// copy(obb: OBB): OBB
|
|
||||||
// clone(obb: OBB): OBB
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in new issue