cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
203 lines (202 loc) • 5.64 kB
JavaScript
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 };