UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

203 lines (202 loc) 5.64 kB
import Vector3 from "./Vector3.mjs"; import vec3 from "../glmatrix/vec3.mjs"; var EPSILON = 1e-5; var Ray = function(origin, direction) { this.origin = origin || new Vector3(); this.direction = direction || new Vector3(); }; Ray.prototype = { constructor: Ray, intersectPlane: function(plane, out) { var pn = plane.normal.array; var d = plane.distance; var ro = this.origin.array; var rd = this.direction.array; var divider = vec3.dot(pn, rd); if (divider === 0) { return null; } if (!out) { out = new Vector3(); } var t = (vec3.dot(pn, ro) - d) / divider; vec3.scaleAndAdd(out.array, ro, rd, -t); out._dirty = true; return out; }, mirrorAgainstPlane: function(plane) { var d = vec3.dot(plane.normal.array, this.direction.array); vec3.scaleAndAdd(this.direction.array, this.direction.array, plane.normal.array, -d * 2); this.direction._dirty = true; }, distanceToPoint: function() { var v = vec3.create(); return function(point) { vec3.sub(v, point, this.origin.array); var b = vec3.dot(v, this.direction.array); if (b < 0) { return vec3.distance(this.origin.array, point); } var c2 = vec3.lenSquared(v); return Math.sqrt(c2 - b * b); }; }(), intersectSphere: function() { var v = vec3.create(); return function(center, radius, out) { var origin = this.origin.array; var direction = this.direction.array; center = center.array; vec3.sub(v, center, origin); var b = vec3.dot(v, direction); var c2 = vec3.squaredLength(v); var d2 = c2 - b * b; var r2 = radius * radius; if (d2 > r2) { return; } var a = Math.sqrt(r2 - d2); var t0 = b - a; var t1 = b + a; if (!out) { out = new Vector3(); } if (t0 < 0) { if (t1 < 0) { return null; } else { vec3.scaleAndAdd(out.array, origin, direction, t1); return out; } } else { vec3.scaleAndAdd(out.array, origin, direction, t0); return out; } }; }(), intersectBoundingBox: function(bbox, out) { var dir = this.direction.array; var origin = this.origin.array; var min = bbox.min.array; var max = bbox.max.array; var invdirx = 1 / dir[0]; var invdiry = 1 / dir[1]; var invdirz = 1 / dir[2]; var tmin, tmax, tymin, tymax, tzmin, tzmax; if (invdirx >= 0) { tmin = (min[0] - origin[0]) * invdirx; tmax = (max[0] - origin[0]) * invdirx; } else { tmax = (min[0] - origin[0]) * invdirx; tmin = (max[0] - origin[0]) * invdirx; } if (invdiry >= 0) { tymin = (min[1] - origin[1]) * invdiry; tymax = (max[1] - origin[1]) * invdiry; } else { tymax = (min[1] - origin[1]) * invdiry; tymin = (max[1] - origin[1]) * invdiry; } if (tmin > tymax || tymin > tmax) { return null; } if (tymin > tmin || tmin !== tmin) { tmin = tymin; } if (tymax < tmax || tmax !== tmax) { tmax = tymax; } if (invdirz >= 0) { tzmin = (min[2] - origin[2]) * invdirz; tzmax = (max[2] - origin[2]) * invdirz; } else { tzmax = (min[2] - origin[2]) * invdirz; tzmin = (max[2] - origin[2]) * invdirz; } if (tmin > tzmax || tzmin > tmax) { return null; } if (tzmin > tmin || tmin !== tmin) { tmin = tzmin; } if (tzmax < tmax || tmax !== tmax) { tmax = tzmax; } if (tmax < 0) { return null; } var t = tmin >= 0 ? tmin : tmax; if (!out) { out = new Vector3(); } vec3.scaleAndAdd(out.array, origin, dir, t); return out; }, intersectTriangle: function() { var eBA = vec3.create(); var eCA = vec3.create(); var AO = vec3.create(); var vCross = vec3.create(); return function(a, b, c, singleSided, out, barycenteric) { var dir = this.direction.array; var origin = this.origin.array; a = a.array; b = b.array; c = c.array; vec3.sub(eBA, b, a); vec3.sub(eCA, c, a); vec3.cross(vCross, eCA, dir); var det = vec3.dot(eBA, vCross); if (singleSided) { if (det > -EPSILON) { return null; } } else { if (det > -EPSILON && det < EPSILON) { return null; } } vec3.sub(AO, origin, a); var u = vec3.dot(vCross, AO) / det; if (u < 0 || u > 1) { return null; } vec3.cross(vCross, eBA, AO); var v = vec3.dot(dir, vCross) / det; if (v < 0 || v > 1 || u + v > 1) { return null; } vec3.cross(vCross, eBA, eCA); var t = -vec3.dot(AO, vCross) / det; if (t < 0) { return null; } if (!out) { out = new Vector3(); } if (barycenteric) { Vector3.set(barycenteric, 1 - u - v, u, v); } vec3.scaleAndAdd(out.array, origin, dir, t); return out; }; }(), applyTransform: function(matrix) { Vector3.add(this.direction, this.direction, this.origin); Vector3.transformMat4(this.origin, this.origin, matrix); Vector3.transformMat4(this.direction, this.direction, matrix); Vector3.sub(this.direction, this.direction, this.origin); Vector3.normalize(this.direction, this.direction); }, copy: function(ray) { Vector3.copy(this.origin, ray.origin); Vector3.copy(this.direction, ray.direction); }, clone: function() { var ray = new Ray(); ray.copy(this); return ray; } }; var Ray$1 = Ray; export { Ray$1 as default };