Options
All
  • Public
  • Public/Protected
  • All
Menu

External module geometry

几何工具模块

Index

Variables

Const LOOK_FORWARD

LOOK_FORWARD: 3 = 3

Const WrapMode

WrapMode: object = Enum({Default: 0,Once: 1,Loop: 2,PingPong: 3,ClampForever: 4,})

Type declaration

  • ClampForever: number
  • Default: number
  • Loop: number
  • Once: number
  • PingPong: number

Const X

X: Vec3 = new Vec3()

Const Y

Y: Vec3 = new Vec3()

Const Z

Z: Vec3 = new Vec3()

Const _m3_tmp

_m3_tmp: Mat3 = new Mat3()

Const _m3_tmp

_m3_tmp: Mat3 = new Mat3()

Const _v

_v: any[] = new Array(8)

Const _v3_tmp

_v3_tmp: Vec3 = new Vec3()

Const _v3_tmp

_v3_tmp: Vec3 = new Vec3()

Const _v3_tmp

_v3_tmp: Vec3 = new Vec3()

Const _v3_tmp2

_v3_tmp2: Vec3 = new Vec3()

Const _v3_tmp2

_v3_tmp2: Vec3 = new Vec3()

Const _v3_tmp3

_v3_tmp3: Vec3 = new Vec3()

Const _v3_tmp4

_v3_tmp4: Vec3 = new Vec3()

Const aabb_aabb

aabb_aabb: (Anonymous function) = (function () {const aMin = new Vec3();const aMax = new Vec3();const bMin = new Vec3();const bMax = new Vec3();return function (aabb1: aabb, aabb2: aabb) {Vec3.subtract(aMin, aabb1.center, aabb1.halfExtents);Vec3.add(aMax, aabb1.center, aabb1.halfExtents);Vec3.subtract(bMin, aabb2.center, aabb2.halfExtents);Vec3.add(bMax, aabb2.center, aabb2.halfExtents);return (aMin.x <= bMax.x && aMax.x >= bMin.x) &&(aMin.y <= bMax.y && aMax.y >= bMin.y) &&(aMin.z <= bMax.z && aMax.z >= bMin.z);};})()

aabb-aabb intersect
轴对齐包围盒和轴对齐包围盒的相交性检测。

param

轴对齐包围盒1

param

轴对齐包围盒2

returns

0 或 非 0

Const aabb_frustum_accurate

aabb_frustum_accurate: (Anonymous function) = (function () {const tmp = new Array(8);let out1 = 0, out2 = 0;for (let i = 0; i < tmp.length; i++) {tmp[i] = new Vec3(0, 0, 0);}return function (aabb: aabb, frustum: frustum): number {let result = 0, intersects = false;// 1. aabb inside/outside frustum testfor (let i = 0; i < frustum.planes.length; i++) {result = aabb_plane(aabb, frustum.planes[i]);// frustum plane normal points to the insideif (result === -1) { return 0; } // completely outsideelse if (result === 1) { intersects = true; }}if (!intersects) { return 1; } // completely inside// in case of false positives// 2. frustum inside/outside aabb testfor (let i = 0; i < frustum.vertices.length; i++) {Vec3.subtract(tmp[i], frustum.vertices[i], aabb.center);}out1 = 0, out2 = 0;for (let i = 0; i < frustum.vertices.length; i++) {if (tmp[i].x > aabb.halfExtents.x) { out1++; }else if (tmp[i].x < -aabb.halfExtents.x) { out2++; }}if (out1 === frustum.vertices.length || out2 === frustum.vertices.length) { return 0; }out1 = 0; out2 = 0;for (let i = 0; i < frustum.vertices.length; i++) {if (tmp[i].y > aabb.halfExtents.y) { out1++; }else if (tmp[i].y < -aabb.halfExtents.y) { out2++; }}if (out1 === frustum.vertices.length || out2 === frustum.vertices.length) { return 0; }out1 = 0; out2 = 0;for (let i = 0; i < frustum.vertices.length; i++) {if (tmp[i].z > aabb.halfExtents.z) { out1++; }else if (tmp[i].z < -aabb.halfExtents.z) { out2++; }}if (out1 === frustum.vertices.length || out2 === frustum.vertices.length) { return 0; }return 1;};})()

aabb-frustum intersect, handles most of the false positives correctly
轴对齐包围盒和锥台相交性检测,正确处理大多数错误情况。

param

轴对齐包围盒

param

锥台

returns

Const aabb_obb

aabb_obb: (Anonymous function) = (function () {const test = new Array(15);for (let i = 0; i < 15; i++) {test[i] = new Vec3(0, 0, 0);}const vertices = new Array(8);const vertices2 = new Array(8);for (let i = 0; i < 8; i++) {vertices[i] = new Vec3(0, 0, 0);vertices2[i] = new Vec3(0, 0, 0);}const min = new Vec3();const max = new Vec3();return function (aabb: aabb, obb: obb): number {Vec3.set(test[0], 1, 0, 0);Vec3.set(test[1], 0, 1, 0);Vec3.set(test[2], 0, 0, 1);Vec3.set(test[3], obb.orientation.m00, obb.orientation.m01, obb.orientation.m02);Vec3.set(test[4], obb.orientation.m03, obb.orientation.m04, obb.orientation.m05);Vec3.set(test[5], obb.orientation.m06, obb.orientation.m07, obb.orientation.m08);for (let i = 0; i < 3; ++i) { // Fill out rest of axisVec3.cross(test[6 + i * 3 + 0], test[i], test[0]);Vec3.cross(test[6 + i * 3 + 1], test[i], test[1]);Vec3.cross(test[6 + i * 3 + 1], test[i], test[2]);}Vec3.subtract(min, aabb.center, aabb.halfExtents);Vec3.add(max, aabb.center, aabb.halfExtents);getAABBVertices(min, max, vertices);getOBBVertices(obb.center, obb.halfExtents, test[3], test[4], test[5], vertices2);for (let j = 0; j < 15; ++j) {const a = getInterval(vertices, test[j]);const b = getInterval(vertices2, test[j]);if (b[0] > a[1] || a[0] > b[1]) {return 0; // Seperating axis found}}return 1;};})()

aabb-obb intersect
轴对齐包围盒和方向包围盒的相交性检测。

param

轴对齐包围盒

param

方向包围盒

returns

0 或 非 0

Const capsule_capsule

capsule_capsule: capsule_capsule = (function () {const v3_0 = new Vec3();const v3_1 = new Vec3();const v3_2 = new Vec3();const v3_3 = new Vec3();const v3_4 = new Vec3();const v3_5 = new Vec3();return function capsule_capsule (capsuleA: capsule, capsuleB: capsule) {const u = Vec3.subtract(v3_0, capsuleA.ellipseCenter1, capsuleA.ellipseCenter0);const v = Vec3.subtract(v3_1, capsuleB.ellipseCenter1, capsuleB.ellipseCenter0);const w = Vec3.subtract(v3_2, capsuleA.ellipseCenter0, capsuleB.ellipseCenter0);const a = Vec3.dot(u, u); // always >= 0const b = Vec3.dot(u, v);const c = Vec3.dot(v, v); // always >= 0const d = Vec3.dot(u, w);const e = Vec3.dot(v, w);const D = a * c - b * b; // always >= 0let sc: number;let sN: number;let sD = D; // sc = sN / sD, default sD = D >= 0let tc: number;let tN: number;let tD = D; // tc = tN / tD, default tD = D >= 0// compute the line parameters of the two closest pointsif (D < EPSILON) { // the lines are almost parallelsN = 0.0; // force using point P0 on segment S1sD = 1.0; // to prevent possible division by 0.0 latertN = e;tD = c;}else { // get the closest points on the infinite linessN = (b * e - c * d);tN = (a * e - b * d);if (sN < 0.0) { // sc < 0 => the s=0 edge is visiblesN = 0.0;tN = e;tD = c;}else if (sN > sD) { // sc > 1 => the s=1 edge is visiblesN = sD;tN = e + b;tD = c;}}if (tN < 0.0) { // tc < 0 => the t=0 edge is visibletN = 0.0;// recompute sc for this edgeif (-d < 0.0) {sN = 0.0;}else if (-d > a) {sN = sD;}else {sN = -d;sD = a;}}else if (tN > tD) { // tc > 1 => the t=1 edge is visibletN = tD;// recompute sc for this edgeif ((-d + b) < 0.0) {sN = 0;}else if ((-d + b) > a) {sN = sD;}else {sN = (-d + b);sD = a;}}// finally do the division to get sc and tcsc = (Math.abs(sN) < EPSILON ? 0.0 : sN / sD);tc = (Math.abs(tN) < EPSILON ? 0.0 : tN / tD);// get the difference of the two closest pointsconst dP = v3_3;dP.set(w);dP.add(Vec3.multiplyScalar(v3_4, u, sc));dP.subtract(Vec3.multiplyScalar(v3_5, v, tc));const radius = capsuleA.radius + capsuleB.radius;return dP.lengthSqr() < radius * radius;};})()

Const d

d: Vec3 = new Vec3()

Const e

e: any[] = new Array(3)

Const line_plane

line_plane: (Anonymous function) = (function () {const ab = new Vec3(0, 0, 0);return function (line: line, plane: plane): number {Vec3.subtract(ab, line.e, line.s);const t = (plane.d - Vec3.dot(line.s, plane.n)) / Vec3.dot(ab, plane.n);if (t < 0 || t > 1) { return 0; }return t;};})()

line-plane intersect
线段与平面的相交性检测。

param

线段

param

平面

returns

0 或 非 0

Const line_triangle

line_triangle: (Anonymous function) = (function () {const ab = new Vec3(0, 0, 0);const ac = new Vec3(0, 0, 0);const qp = new Vec3(0, 0, 0);const ap = new Vec3(0, 0, 0);const n = new Vec3(0, 0, 0);const e = new Vec3(0, 0, 0);return function (line: line, triangle: triangle, outPt?: Vec3): number {Vec3.subtract(ab, triangle.b, triangle.a);Vec3.subtract(ac, triangle.c, triangle.a);Vec3.subtract(qp, line.s, line.e);Vec3.cross(n, ab, ac);const det = Vec3.dot(qp, n);if (det <= 0.0) {return 0;}Vec3.subtract(ap, line.s, triangle.a);const t = Vec3.dot(ap, n);if (t < 0 || t > det) {return 0;}Vec3.cross(e, qp, ap);let v = Vec3.dot(ac, e);if (v < 0 || v > det) {return 0;}let w = -Vec3.dot(ab, e);if (w < 0.0 || v + w > det) {return 0;}if (outPt) {const invDet = 1.0 / det;v *= invDet;w *= invDet;const u = 1.0 - v - w;// outPt = u*a + v*d + w*c;Vec3.set(outPt,triangle.a.x * u + triangle.b.x * v + triangle.c.x * w,triangle.a.y * u + triangle.b.y * v + triangle.c.y * w,triangle.a.z * u + triangle.b.z * v + triangle.c.z * w,);}return 1;};})()

line-triangle intersect
线段与三角形的相交性检测。

param

线段

param

三角形

param

可选,相交点

returns

0 或 非 0

Const max

max: Vec3 = new Vec3()

Const min

min: Vec3 = new Vec3()

Const obb_capsule

obb_capsule: (Anonymous function) = (function () {const sphere_0 = new sphere();const v3_0 = new Vec3();const v3_1 = new Vec3();const v3_2 = new Vec3();const v3_verts8 = new Array<Vec3>(8);for (let i = 0; i < 8; i++) { v3_verts8[i] = new Vec3(); }const v3_axis8 = new Array<Vec3>(8);for (let i = 0; i < 8; i++) { v3_axis8[i] = new Vec3(); }return function (obb: obb, capsule: capsule) {const h = Vec3.squaredDistance(capsule.ellipseCenter0, capsule.ellipseCenter1);if (h === 0) {sphere_0.radius = capsule.radius;sphere_0.center.set(capsule.ellipseCenter0);return intersect.sphere_obb(sphere_0, obb);} else {v3_0.x = obb.orientation.m00;v3_0.y = obb.orientation.m01;v3_0.z = obb.orientation.m02;v3_1.x = obb.orientation.m03;v3_1.y = obb.orientation.m04;v3_1.z = obb.orientation.m05;v3_2.x = obb.orientation.m06;v3_2.y = obb.orientation.m07;v3_2.z = obb.orientation.m08;getOBBVertices(obb.center, obb.halfExtents, v3_0, v3_1, v3_2, v3_verts8);const axes = v3_axis8;const a0 = Vec3.copy(axes[0], v3_0);const a1 = Vec3.copy(axes[1], v3_1);const a2 = Vec3.copy(axes[2], v3_2);const C = Vec3.subtract(axes[3], capsule.center, obb.center);C.normalize();const B = Vec3.subtract(axes[4], capsule.ellipseCenter0, capsule.ellipseCenter1);B.normalize();Vec3.cross(axes[5], a0, B);Vec3.cross(axes[6], a1, B);Vec3.cross(axes[7], a2, B);for (let i = 0; i < 8; ++i) {const a = getInterval(v3_verts8, axes[i]);const d0 = Vec3.dot(axes[i], capsule.ellipseCenter0);const d1 = Vec3.dot(axes[i], capsule.ellipseCenter1);const max_d = Math.max(d0, d1);const min_d = Math.min(d0, d1);const d_min = min_d - capsule.radius;const d_max = max_d + capsule.radius;if (d_min > a[1] || a[0] > d_max) {return 0; // Seperating axis found}}return 1;}};})()

方向包围盒和胶囊体的重叠检测

param

方向包围盒

param

胶囊体

Const obb_frustum_accurate

obb_frustum_accurate: (Anonymous function) = (function () {const tmp = new Array(8);let dist = 0, out1 = 0, out2 = 0;for (let i = 0; i < tmp.length; i++) {tmp[i] = new Vec3(0, 0, 0);}const dot = function (n: Vec3, x: number, y: number, z: number): number {return n.x * x + n.y * y + n.z * z;};return function (obb: obb, frustum: frustum): number {let result = 0, intersects = false;// 1. obb inside/outside frustum testfor (let i = 0; i < frustum.planes.length; i++) {result = obb_plane(obb, frustum.planes[i]);// frustum plane normal points to the insideif (result === -1) { return 0; } // completely outsideelse if (result === 1) { intersects = true; }}if (!intersects) { return 1; } // completely inside// in case of false positives// 2. frustum inside/outside obb testfor (let i = 0; i < frustum.vertices.length; i++) {Vec3.subtract(tmp[i], frustum.vertices[i], obb.center);}out1 = 0, out2 = 0;for (let i = 0; i < frustum.vertices.length; i++) {dist = dot(tmp[i], obb.orientation.m00, obb.orientation.m01, obb.orientation.m02);if (dist > obb.halfExtents.x) { out1++; }else if (dist < -obb.halfExtents.x) { out2++; }}if (out1 === frustum.vertices.length || out2 === frustum.vertices.length) { return 0; }out1 = 0; out2 = 0;for (let i = 0; i < frustum.vertices.length; i++) {dist = dot(tmp[i], obb.orientation.m03, obb.orientation.m04, obb.orientation.m05);if (dist > obb.halfExtents.y) { out1++; }else if (dist < -obb.halfExtents.y) { out2++; }}if (out1 === frustum.vertices.length || out2 === frustum.vertices.length) { return 0; }out1 = 0; out2 = 0;for (let i = 0; i < frustum.vertices.length; i++) {dist = dot(tmp[i], obb.orientation.m06, obb.orientation.m07, obb.orientation.m08);if (dist > obb.halfExtents.z) { out1++; }else if (dist < -obb.halfExtents.z) { out2++; }}if (out1 === frustum.vertices.length || out2 === frustum.vertices.length) { return 0; }return 1;};})()

obb-frustum intersect, handles most of the false positives correctly
方向包围盒和锥台相交性检测,正确处理大多数错误情况。

param

方向包围盒

param

锥台

returns

0 或 非 0

Const obb_obb

obb_obb: (Anonymous function) = (function () {const test = new Array(15);for (let i = 0; i < 15; i++) {test[i] = new Vec3(0, 0, 0);}const vertices = new Array(8);const vertices2 = new Array(8);for (let i = 0; i < 8; i++) {vertices[i] = new Vec3(0, 0, 0);vertices2[i] = new Vec3(0, 0, 0);}return function (obb1: obb, obb2: obb): number {Vec3.set(test[0], obb1.orientation.m00, obb1.orientation.m01, obb1.orientation.m02);Vec3.set(test[1], obb1.orientation.m03, obb1.orientation.m04, obb1.orientation.m05);Vec3.set(test[2], obb1.orientation.m06, obb1.orientation.m07, obb1.orientation.m08);Vec3.set(test[3], obb2.orientation.m00, obb2.orientation.m01, obb2.orientation.m02);Vec3.set(test[4], obb2.orientation.m03, obb2.orientation.m04, obb2.orientation.m05);Vec3.set(test[5], obb2.orientation.m06, obb2.orientation.m07, obb2.orientation.m08);for (let i = 0; i < 3; ++i) { // Fill out rest of axisVec3.cross(test[6 + i * 3 + 0], test[i], test[0]);Vec3.cross(test[6 + i * 3 + 1], test[i], test[1]);Vec3.cross(test[6 + i * 3 + 1], test[i], test[2]);}getOBBVertices(obb1.center, obb1.halfExtents, test[0], test[1], test[2], vertices);getOBBVertices(obb2.center, obb2.halfExtents, test[3], test[4], test[5], vertices2);for (let i = 0; i < 15; ++i) {const a = getInterval(vertices, test[i]);const b = getInterval(vertices2, test[i]);if (b[0] > a[1] || a[0] > b[1]) {return 0; // Seperating axis found}}return 1;};})()

obb-obb intersect
方向包围盒和方向包围盒的相交性检测。

param

方向包围盒1

param

方向包围盒2

returns

0 或 非 0

Const obb_plane

obb_plane: (Anonymous function) = (function () {const absDot = function (n: Vec3, x: number, y: number, z: number) {return Math.abs(n.x * x + n.y * y + n.z * z);};return function (obb: obb, plane: plane): number {// Real-Time Collision Detection, Christer Ericson, p. 163.const r = obb.halfExtents.x * absDot(plane.n, obb.orientation.m00, obb.orientation.m01, obb.orientation.m02) +obb.halfExtents.y * absDot(plane.n, obb.orientation.m03, obb.orientation.m04, obb.orientation.m05) +obb.halfExtents.z * absDot(plane.n, obb.orientation.m06, obb.orientation.m07, obb.orientation.m08);const dot = Vec3.dot(plane.n, obb.center);if (dot + r < plane.d) { return -1; }else if (dot - r > plane.d) { return 0; }return 1;};})()

obb-plane intersect
方向包围盒和平面的相交性检测。

param

方向包围盒

param

平面

returns

inside(back) = -1, outside(front) = 0, intersect = 1

Const obb_point

obb_point: (Anonymous function) = (function () {const tmp = new Vec3(0, 0, 0), m3 = new Mat3();const lessThan = function (a: Vec3, b: Vec3): boolean { return Math.abs(a.x) < b.x && Math.abs(a.y) < b.y && Math.abs(a.z) < b.z; };return function (obb: obb, point: Vec3): boolean {Vec3.subtract(tmp, point, obb.center);Vec3.transformMat3(tmp, tmp, Mat3.transpose(m3, obb.orientation));return lessThan(tmp, obb.halfExtents);};})()

obb-point intersect
方向包围盒和点的相交性检测。

param

方向包围盒

param

returns

true or false

Const r_t

r_t: ray = new ray()

Const ray_aabb

ray_aabb: (Anonymous function) = (function () {const min = new Vec3();const max = new Vec3();return function (ray: ray, aabb: aabb): number {const o = ray.o, d = ray.d;const ix = 1 / d.x, iy = 1 / d.y, iz = 1 / d.z;Vec3.subtract(min, aabb.center, aabb.halfExtents);Vec3.add(max, aabb.center, aabb.halfExtents);const t1 = (min.x - o.x) * ix;const t2 = (max.x - o.x) * ix;const t3 = (min.y - o.y) * iy;const t4 = (max.y - o.y) * iy;const t5 = (min.z - o.z) * iz;const t6 = (max.z - o.z) * iz;const tmin = Math.max(Math.max(Math.min(t1, t2), Math.min(t3, t4)), Math.min(t5, t6));const tmax = Math.min(Math.min(Math.max(t1, t2), Math.max(t3, t4)), Math.max(t5, t6));if (tmax < 0 || tmin > tmax) { return 0; }return tmin > 0 ? tmin : tmax; // ray origin inside aabb};})()

ray-aabb intersect
射线和轴对齐包围盒的相交性检测。

param

射线

param

轴对齐包围盒

returns

0 或 非 0

Const ray_capsule

ray_capsule: (Anonymous function) = (function () {const v3_0 = new Vec3();const v3_1 = new Vec3();const v3_2 = new Vec3();const v3_3 = new Vec3();const v3_4 = new Vec3();const v3_5 = new Vec3();const v3_6 = new Vec3();const sphere_0 = new sphere();return function (ray: ray, capsule: capsule) {const radiusSqr = capsule.radius * capsule.radius;const vRayNorm = Vec3.normalize(v3_0, ray.d);const A = capsule.ellipseCenter0;const B = capsule.ellipseCenter1;const BA = Vec3.subtract(v3_1, B, A);if (BA.equals(Vec3.ZERO)) {sphere_0.radius = capsule.radius;sphere_0.center.set(capsule.ellipseCenter0);return intersect.ray_sphere(ray, sphere_0);}const O = ray.o;const OA = Vec3.subtract(v3_2, O, A);const VxBA = Vec3.cross(v3_3, vRayNorm, BA);const a = VxBA.lengthSqr();if (a === 0) {sphere_0.radius = capsule.radius;const BO = Vec3.subtract(v3_4, B, O);if (OA.lengthSqr() < BO.lengthSqr()) {sphere_0.center.set(capsule.ellipseCenter0);} else {sphere_0.center.set(capsule.ellipseCenter1);}return intersect.ray_sphere(ray, sphere_0);}const OAxBA = Vec3.cross(v3_4, OA, BA);const ab2 = BA.lengthSqr();const b = 2 * Vec3.dot(VxBA, OAxBA);const c = OAxBA.lengthSqr() - (radiusSqr * ab2);const d = b * b - 4 * a * c;if (d < 0) { return 0; }const t = (-b - Math.sqrt(d)) / (2 * a);if (t < 0) {sphere_0.radius = capsule.radius;const BO = Vec3.subtract(v3_5, B, O);if (OA.lengthSqr() < BO.lengthSqr()) {sphere_0.center.set(capsule.ellipseCenter0);} else {sphere_0.center.set(capsule.ellipseCenter1);}return intersect.ray_sphere(ray, sphere_0);} else {// Limit intersection between the bounds of the cylinder's end caps.const iPos = Vec3.scaleAndAdd(v3_5, ray.o, vRayNorm, t);const iPosLen = Vec3.subtract(v3_6, iPos, A);const tLimit = Vec3.dot(iPosLen, BA) / ab2;if (tLimit >= 0 && tLimit <= 1) {return t;} else if (tLimit < 0) {sphere_0.radius = capsule.radius;sphere_0.center.set(capsule.ellipseCenter0);return intersect.ray_sphere(ray, sphere_0);} else if (tLimit > 1) {sphere_0.radius = capsule.radius;sphere_0.center.set(capsule.ellipseCenter1);return intersect.ray_sphere(ray, sphere_0);} else {return 0;}}};})()

Const ray_obb

ray_obb: (Anonymous function) = (function () {let center = new Vec3();let o = new Vec3();let d = new Vec3();const X = new Vec3();const Y = new Vec3();const Z = new Vec3();const p = new Vec3();const size = new Array(3);const f = new Array(3);const e = new Array(3);const t = new Array(6);return function (ray: ray, obb: obb): number {size[0] = obb.halfExtents.x;size[1] = obb.halfExtents.y;size[2] = obb.halfExtents.z;center = obb.center;o = ray.o;d = ray.d;Vec3.set(X, obb.orientation.m00, obb.orientation.m01, obb.orientation.m02);Vec3.set(Y, obb.orientation.m03, obb.orientation.m04, obb.orientation.m05);Vec3.set(Z, obb.orientation.m06, obb.orientation.m07, obb.orientation.m08);Vec3.subtract(p, center, o);// The cos values of the ray on the X, Y, Zf[0] = Vec3.dot(X, d);f[1] = Vec3.dot(Y, d);f[2] = Vec3.dot(Z, d);// The projection length of P on X, Y, Ze[0] = Vec3.dot(X, p);e[1] = Vec3.dot(Y, p);e[2] = Vec3.dot(Z, p);for (let i = 0; i < 3; ++i) {if (f[i] === 0) {if (-e[i] - size[i] > 0 || -e[i] + size[i] < 0) {return 0;}// Avoid div by 0!f[i] = 0.0000001;}// mint[i * 2 + 0] = (e[i] + size[i]) / f[i];// maxt[i * 2 + 1] = (e[i] - size[i]) / f[i];}const tmin = Math.max(Math.max(Math.min(t[0], t[1]),Math.min(t[2], t[3])),Math.min(t[4], t[5]),);const tmax = Math.min(Math.min(Math.max(t[0], t[1]),Math.max(t[2], t[3])),Math.max(t[4], t[5]),);if (tmax < 0 || tmin > tmax) {return 0;}return tmin > 0 ? tmin : tmax; // ray origin inside aabb};})()

ray-obb intersect
射线和方向包围盒的相交性检测。

param

射线

param

方向包围盒

returns

0 或 非 0

Const ray_plane

ray_plane: (Anonymous function) = (function () {const pt = new Vec3(0, 0, 0);return function (ray: ray, plane: plane): number {const denom = Vec3.dot(ray.d, plane.n);if (Math.abs(denom) < Number.EPSILON) { return 0; }Vec3.multiplyScalar(pt, plane.n, plane.d);const t = Vec3.dot(Vec3.subtract(pt, pt, ray.o), plane.n) / denom;if (t < 0) { return 0; }return t;};})()

ray-plane intersect
射线与平面的相交性检测。

param

射线

param

平面

returns

0 或 非 0

Const ray_sphere

ray_sphere: (Anonymous function) = (function () {const e = new Vec3(0, 0, 0);return function (ray: ray, sphere: sphere): number {const r = sphere.radius;const c = sphere.center;const o = ray.o;const d = ray.d;const rSq = r * r;Vec3.subtract(e, c, o);const eSq = e.lengthSqr();const aLength = Vec3.dot(e, d); // assume ray direction already normalizedconst fSq = rSq - (eSq - aLength * aLength);if (fSq < 0) { return 0; }const f = Math.sqrt(fSq);const t = eSq < rSq ? aLength + f : aLength - f;if (t < 0) { return 0; }return t;};})()

ray-sphere intersect
射线和球的相交性检测。

param

射线

param

returns

0 或 非 0

Const ray_triangle

ray_triangle: (Anonymous function) = (function () {const ab = new Vec3(0, 0, 0);const ac = new Vec3(0, 0, 0);const pvec = new Vec3(0, 0, 0);const tvec = new Vec3(0, 0, 0);const qvec = new Vec3(0, 0, 0);return function (ray: ray, triangle: triangle, doubleSided?: boolean) {Vec3.subtract(ab, triangle.b, triangle.a);Vec3.subtract(ac, triangle.c, triangle.a);Vec3.cross(pvec, ray.d, ac);const det = Vec3.dot(ab, pvec);if (det < Number.EPSILON && (!doubleSided || det > -Number.EPSILON)) { return 0; }const inv_det = 1 / det;Vec3.subtract(tvec, ray.o, triangle.a);const u = Vec3.dot(tvec, pvec) * inv_det;if (u < 0 || u > 1) { return 0; }Vec3.cross(qvec, tvec, ab);const v = Vec3.dot(ray.d, qvec) * inv_det;if (v < 0 || u + v > 1) { return 0; }const t = Vec3.dot(ac, qvec) * inv_det;return t < 0 ? 0 : t;};})()

ray-triangle intersect
射线与三角形的相交性检测。

param

射线

param

三角形

param

三角形是否为双面

returns

0 或 非 0

Const sphere_aabb

sphere_aabb: (Anonymous function) = (function () {const pt = new Vec3();return function (sphere: sphere, aabb: aabb): boolean {distance.pt_point_aabb(pt, sphere.center, aabb);return Vec3.squaredDistance(sphere.center, pt) < sphere.radius * sphere.radius;};})()

sphere-aabb intersect
球和轴对齐包围盒的相交性检测。

param

param

轴对齐包围盒

returns

true or false

Const sphere_capsule

sphere_capsule: (Anonymous function) = (function () {const v3_0 = new Vec3();const v3_1 = new Vec3();return function (sphere: sphere, capsule: capsule) {const r = sphere.radius + capsule.radius;const squaredR = r * r;const h = Vec3.squaredDistance(capsule.ellipseCenter0, capsule.ellipseCenter1);if (h === 0) {return Vec3.squaredDistance(sphere.center, capsule.center) < squaredR;} else {Vec3.subtract(v3_0, sphere.center, capsule.ellipseCenter0);Vec3.subtract(v3_1, capsule.ellipseCenter1, capsule.ellipseCenter0);const t = Vec3.dot(v3_0, v3_1) / h;if (t < 0) {return Vec3.squaredDistance(sphere.center, capsule.ellipseCenter0) < squaredR;} else if (t > 1) {return Vec3.squaredDistance(sphere.center, capsule.ellipseCenter1) < squaredR;} else {Vec3.scaleAndAdd(v3_0, capsule.ellipseCenter0, v3_1, t);return Vec3.squaredDistance(sphere.center, v3_0) < squaredR;}}};})()

Const sphere_frustum_accurate

sphere_frustum_accurate: (Anonymous function) = (function () {const pt = new Vec3(0, 0, 0), map = [1, -1, 1, -1, 1, -1];return function (sphere: sphere, frustum: frustum): number {for (let i = 0; i < 6; i++) {const plane = frustum.planes[i];const r = sphere.radius, c = sphere.center;const n = plane.n, d = plane.d;const dot = Vec3.dot(n, c);// frustum plane normal points to the insideif (dot + r < d) { return 0; } // completely outsideelse if (dot - r > d) { continue; }// in case of false positives// has false negatives, still working on itVec3.add(pt, c, Vec3.multiplyScalar(pt, n, r));for (let j = 0; j < 6; j++) {if (j === i || j === i + map[i]) { continue; }const test = frustum.planes[j];if (Vec3.dot(test.n, pt) < test.d) { return 0; }}}return 1;};})()

sphere-frustum intersect, handles the false positives correctly
球和锥台的相交性检测,正确处理大多数错误情况。

param

param

锥台

returns

0 或 非 0

Const sphere_obb

sphere_obb: (Anonymous function) = (function () {const pt = new Vec3();return function (sphere: sphere, obb: obb): boolean {distance.pt_point_obb(pt, sphere.center, obb);return Vec3.squaredDistance(sphere.center, pt) < sphere.radius * sphere.radius;};})()

sphere-obb intersect
球和方向包围盒的相交性检测。

param

param

方向包围盒

returns

true or false

Const temp_mat

temp_mat: any = cc.mat4()

Const temp_vec4

temp_vec4: any = cc.v4()

Const u

u: any[] = new Array(3)

Const v1

v1: Vec3 = new Vec3(0, 0, 0)

Const v2

v2: Vec3 = new Vec3(0, 0, 0)

Functions

Const aabbfrustum

  • aabb-frustum intersect, faster but has false positive corner cases
    轴对齐包围盒和锥台相交性检测,速度快,但有错误情况。

    Parameters

    • aabb: aabb

      轴对齐包围盒

    • frustum: frustum

      锥台

    Returns number

    0 或 非 0

Const aabbplane

  • aabbplane(aabb: aabb, plane: plane): number
  • aabb-plane intersect
    轴对齐包围盒和平面的相交性检测。

    Parameters

    • aabb: aabb

      轴对齐包围盒

    • plane: plane

      平面

    Returns number

    inside(back) = -1, outside(front) = 0, intersect = 1

evalOptCurve

  • evalOptCurve(t: number, coefs: Float32Array | number[]): number

getAABBVertices

getInterval

  • getInterval(vertices: any[] | Vec3[], axis: Vec3): number[]

getOBBVertices

lineaabb

  • lineaabb(line: line, aabb: aabb): number

lineobb

  • lineobb(line: line, obb: obb): number

linesphere

maxComponent

  • maxComponent(v: Vec3): number

Const obbfrustum

  • obb-frustum intersect, faster but has false positive corner cases
    方向包围盒和锥台相交性检测,速度快,但有错误情况。

    Parameters

    • obb: obb

      方向包围盒

    • frustum: frustum

      锥台

    Returns number

    0 或 非 0

pointplane

  • pointplane(point: Vec3, plane_: plane): number

ptpointaabb

ptpointline

ptpointobb

ptpointplane

Const spherefrustum

  • sphere-frustum intersect, faster but has false positive corner cases
    球和锥台的相交性检测,速度快,但有错误情况。

    Parameters

    Returns number

    0 或 非 0

Const sphereplane

  • sphere-plane intersect, not necessarily faster than obb-plane
    due to the length calculation of the plane normal to factor out
    the unnomalized plane distance
    球与平面的相交性检测。

    Parameters

    Returns number

    inside(back) = -1, outside(front) = 0, intersect = 1

Const spheresphere

Const transformextentm3

  • transformextentm3(out: Vec3, extent: Vec3, m3: Mat3): void

Const transformextentm4

  • transformextentm4(out: Vec3, extent: Vec3, m4: Mat4): void

Object literals

Const intersect

intersect: object

aabb_aabb

aabb_aabb: (Anonymous function)

aabb_frustum

aabb_frustum: aabbfrustum

aabb_frustum_accurate

aabb_frustum_accurate: (Anonymous function)

aabb_obb

aabb_obb: (Anonymous function)

aabb_plane

aabb_plane: aabbplane

capsule_capsule

capsule_capsule: capsule_capsule

line_aabb

line_aabb: lineaabb

line_obb

line_obb: lineobb

line_plane

line_plane: (Anonymous function)

line_sphere

line_sphere: linesphere

line_triangle

line_triangle: (Anonymous function)

obb_capsule

obb_capsule: (Anonymous function)

obb_frustum

obb_frustum: obbfrustum

obb_frustum_accurate

obb_frustum_accurate: (Anonymous function)

obb_obb

obb_obb: (Anonymous function)

obb_plane

obb_plane: (Anonymous function)

obb_point

obb_point: (Anonymous function)

ray_aabb

ray_aabb: (Anonymous function)

ray_capsule

ray_capsule: (Anonymous function)

ray_obb

ray_obb: (Anonymous function)

ray_plane

ray_plane: (Anonymous function)

ray_sphere

ray_sphere: (Anonymous function)

ray_triangle

ray_triangle: (Anonymous function)

sphere_aabb

sphere_aabb: (Anonymous function)

sphere_capsule

sphere_capsule: (Anonymous function)

sphere_frustum

sphere_frustum: spherefrustum

sphere_frustum_accurate

sphere_frustum_accurate: (Anonymous function)

sphere_obb

sphere_obb: (Anonymous function)

sphere_plane

sphere_plane: sphereplane

sphere_sphere

sphere_sphere: spheresphere

resolve

  • resolve(g1: any, g2: any, outPt?: null): any
  • g1 和 g2 的相交性检测,可填入基础几何中的形状。

    Parameters

    • g1: any

      几何1

    • g2: any

      几何2

    • Default value outPt: null = null

      可选,相交点。(注:仅部分形状的检测带有这个返回值)

    Returns any

Generated using TypeDoc