1 | import { vec3 } from 'gl-matrix';
|
2 | var tmpVecA = vec3.create();
|
3 | var tmpVecB = vec3.create();
|
4 | var tmpVecC = vec3.create();
|
5 | var tmpVecD = vec3.create();
|
6 | var tmpVecE = vec3.create();
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | var Ray =
|
15 |
|
16 | function () {
|
17 | function Ray(origin, direction) {
|
18 | this.origin = origin || vec3.create();
|
19 | this.direction = direction || vec3.fromValues(0, 0, -1);
|
20 | }
|
21 |
|
22 | Ray.prototype.intersectsAABB = function (aabb, intersection) {
|
23 | return intersection ? this.intersectAABBWithIntersection(aabb, intersection) : this.intersectsAABBWithoutIntersection(aabb);
|
24 | };
|
25 |
|
26 | Ray.prototype.intersectsSphere = function (sphere, intersection) {
|
27 | var m = vec3.sub(tmpVecA, this.origin, sphere.center);
|
28 | vec3.normalize(tmpVecB, vec3.copy(tmpVecB, this.direction));
|
29 | var b = vec3.dot(m, tmpVecB);
|
30 | var c = vec3.dot(m, m) - sphere.radius * sphere.radius;
|
31 |
|
32 | if (c > 0 && b > 0) {
|
33 | return null;
|
34 | }
|
35 |
|
36 | var discr = b * b - c;
|
37 |
|
38 | if (discr < 0) {
|
39 | return false;
|
40 | }
|
41 |
|
42 |
|
43 | var t = Math.abs(-b - Math.sqrt(discr));
|
44 |
|
45 | if (intersection) {
|
46 | vec3.copy(intersection, this.direction);
|
47 | vec3.scaleAndAdd(intersection, this.origin, intersection, t);
|
48 | }
|
49 |
|
50 | return true;
|
51 | };
|
52 |
|
53 | Ray.prototype.intersectsPlane = function (plane, intersection) {
|
54 | var t = (plane.distance - vec3.dot(plane.normal, this.origin)) / vec3.dot(plane.normal, this.direction);
|
55 | var intersects = t >= 0;
|
56 |
|
57 | if (intersects && intersection) {
|
58 | vec3.scaleAndAdd(intersection, this.origin, this.direction, t);
|
59 | }
|
60 |
|
61 | return intersects;
|
62 | };
|
63 | |
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | Ray.prototype.intersectsAABBWithoutIntersection = function (aabb) {
|
70 | var diff = tmpVecA;
|
71 | var cross = tmpVecB;
|
72 | var prod = tmpVecC;
|
73 | var absDiff = tmpVecD;
|
74 | var absDir = tmpVecE;
|
75 | var rayDir = this.direction;
|
76 | vec3.sub(diff, this.origin, aabb.center);
|
77 | vec3.set(absDiff, Math.abs(diff[0]), Math.abs(diff[1]), Math.abs(diff[2]));
|
78 | vec3.mul(prod, diff, rayDir);
|
79 |
|
80 | if (absDiff[0] > aabb.halfExtents[0] && prod[0] >= 0 || absDiff[1] > aabb.halfExtents[1] && prod[1] >= 0 || absDiff[2] > aabb.halfExtents[2] && prod[2] >= 0) {
|
81 | return false;
|
82 | }
|
83 |
|
84 | vec3.set(absDir, Math.abs(rayDir[0]), Math.abs(rayDir[1]), Math.abs(rayDir[2]));
|
85 | vec3.cross(cross, rayDir, diff);
|
86 | vec3.set(cross, Math.abs(cross[0]), Math.abs(cross[1]), Math.abs(cross[2]));
|
87 | return !(cross[0] > aabb.halfExtents[1] * absDir[2] + aabb.halfExtents[2] * absDir[1] || cross[1] > aabb.halfExtents[0] * absDir[2] + aabb.halfExtents[2] * absDir[0] || cross[2] > aabb.halfExtents[0] * absDir[1] + aabb.halfExtents[1] * absDir[0]);
|
88 | };
|
89 |
|
90 | Ray.prototype.intersectAABBWithIntersection = function (aabb, intersection) {
|
91 | var tMin = vec3.copy(vec3.create(), aabb.getMin());
|
92 | vec3.sub(tMin, tMin, this.origin);
|
93 | var tMax = vec3.copy(vec3.create(), aabb.getMax());
|
94 | vec3.sub(tMax, tMax, this.origin);
|
95 | var dir = this.direction;
|
96 |
|
97 | if (dir[0] === 0) {
|
98 | tMin[0] = tMin[0] < 0 ? -Number.MAX_VALUE : Number.MAX_VALUE;
|
99 | tMax[0] = tMax[0] < 0 ? -Number.MAX_VALUE : Number.MAX_VALUE;
|
100 | } else {
|
101 | tMin[0] /= dir[0];
|
102 | tMax[0] /= dir[0];
|
103 | }
|
104 |
|
105 | if (dir[1] === 0) {
|
106 | tMin[1] = tMin[1] < 0 ? -Number.MAX_VALUE : Number.MAX_VALUE;
|
107 | tMax[1] = tMax[1] < 0 ? -Number.MAX_VALUE : Number.MAX_VALUE;
|
108 | } else {
|
109 | tMin[1] /= dir[1];
|
110 | tMax[1] /= dir[1];
|
111 | }
|
112 |
|
113 | if (dir[2] === 0) {
|
114 | tMin[2] = tMin[2] < 0 ? -Number.MAX_VALUE : Number.MAX_VALUE;
|
115 | tMax[2] = tMax[2] < 0 ? -Number.MAX_VALUE : Number.MAX_VALUE;
|
116 | } else {
|
117 | tMin[2] /= dir[2];
|
118 | tMax[2] /= dir[2];
|
119 | }
|
120 |
|
121 | var realMin = vec3.set(tmpVecC, Math.min(tMin[0], tMax[0]), Math.min(tMin[1], tMax[1]), Math.min(tMin[2], tMax[2]));
|
122 | var realMax = vec3.set(tmpVecD, Math.max(tMin[0], tMax[0]), Math.max(tMin[1], tMax[1]), Math.max(tMin[2], tMax[2]));
|
123 | var minMax = Math.min(Math.min(realMax[0], realMax[1]), realMax[2]);
|
124 | var maxMin = Math.max(Math.max(realMin[0], realMin[1]), realMin[2]);
|
125 | var intersects = minMax >= maxMin && maxMin >= 0;
|
126 |
|
127 | if (intersects) {
|
128 | vec3.copy(intersection, this.direction);
|
129 | vec3.scaleAndAdd(intersection, this.origin, intersection, maxMin);
|
130 | }
|
131 |
|
132 | return intersects;
|
133 | };
|
134 |
|
135 | return Ray;
|
136 | }();
|
137 |
|
138 | export { Ray }; |
\ | No newline at end of file |