@carbonenginejs/core-math 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +24 -0
- package/README.md +110 -0
- package/THIRD-PARTY-NOTICES.md +38 -0
- package/package.json +74 -0
- package/src/box3.js +1329 -0
- package/src/constants.js +16 -0
- package/src/curve.js +390 -0
- package/src/geometry/box.js +132 -0
- package/src/geometry/cylinder.js +234 -0
- package/src/geometry/helpers/LICENSE +15 -0
- package/src/geometry/helpers/earcut.js +766 -0
- package/src/geometry/helpers/misc.js +103 -0
- package/src/geometry/index.js +7 -0
- package/src/geometry/json.js +115 -0
- package/src/geometry/lathe.js +148 -0
- package/src/geometry/octahedron.js +0 -0
- package/src/geometry/plane.js +76 -0
- package/src/geometry/shape.js +95 -0
- package/src/geometry/sphere.js +116 -0
- package/src/geometry/torus.js +88 -0
- package/src/index.js +29 -0
- package/src/lne3.js +488 -0
- package/src/mat3.js +131 -0
- package/src/mat4.js +600 -0
- package/src/mesh.js +298 -0
- package/src/noise.js +225 -0
- package/src/num.js +735 -0
- package/src/pln.js +740 -0
- package/src/pool.js +160 -0
- package/src/quat.js +110 -0
- package/src/ray3.js +1056 -0
- package/src/sph3.js +718 -0
- package/src/tangent.js +256 -0
- package/src/tri3.js +650 -0
- package/src/utils.js +15 -0
- package/src/vec2.js +229 -0
- package/src/vec3.js +1116 -0
- package/src/vec4.js +315 -0
- package/src/vertex.js +109 -0
package/src/ray3.js
ADDED
|
@@ -0,0 +1,1056 @@
|
|
|
1
|
+
import { vec3 } from "./vec3.js";
|
|
2
|
+
import { pln } from "./pln.js";
|
|
3
|
+
import { sph3 } from "./sph3.js";
|
|
4
|
+
import { box3 } from "./box3.js";
|
|
5
|
+
import { tri3 } from "./tri3.js";
|
|
6
|
+
import { mat3 } from "./mat3.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 3D Ray
|
|
10
|
+
* @typedef {Float32Array} ray3
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const ray3 = {};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Allocates a pooled ray3
|
|
17
|
+
* @returns {Float32Array|ray3}
|
|
18
|
+
*/
|
|
19
|
+
ray3.alloc = box3.alloc;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Unallocates a pooled ray3
|
|
23
|
+
* @param {ray3|Float32Array} a
|
|
24
|
+
*/
|
|
25
|
+
ray3.unalloc = box3.unalloc;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Gets a subarray of a ray3's origin vector
|
|
29
|
+
* @property {box3} a
|
|
30
|
+
* @returns {TypedArray}
|
|
31
|
+
*/
|
|
32
|
+
ray3.$origin = box3.$min;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Gets a subarray of a ray3's direction vector
|
|
36
|
+
* @property {box3} a
|
|
37
|
+
* @returns {TypedArray}
|
|
38
|
+
*/
|
|
39
|
+
ray3.$direction = box3.$max;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Clones a ray3
|
|
43
|
+
*
|
|
44
|
+
* @param {ray3} a
|
|
45
|
+
* @returns {ray3}
|
|
46
|
+
*/
|
|
47
|
+
ray3.clone = box3.clone;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Copies the values from one ray3 into another
|
|
51
|
+
*
|
|
52
|
+
* @param {ray3} out
|
|
53
|
+
* @param {ray3} a
|
|
54
|
+
* @returns {ray3} out
|
|
55
|
+
*/
|
|
56
|
+
ray3.copy = box3.copy;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Copies the origin vector of one ray3 to another
|
|
60
|
+
*
|
|
61
|
+
* @param {ray3} out
|
|
62
|
+
* @param {ray3} a
|
|
63
|
+
* @returns {ray3}
|
|
64
|
+
*/
|
|
65
|
+
ray3.copyOrigin = box3.copyMin;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Copies the direction vector of one ray3 to another
|
|
69
|
+
*
|
|
70
|
+
* @param {ray3} out
|
|
71
|
+
* @param {ray3} a
|
|
72
|
+
* @returns {ray3}
|
|
73
|
+
*/
|
|
74
|
+
ray3.copyDirection = box3.copyMax;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Creates a ray3
|
|
78
|
+
*
|
|
79
|
+
* @returns {ray3}
|
|
80
|
+
*/
|
|
81
|
+
ray3.create = box3.create;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Gets the distance from a ray3 to a point
|
|
85
|
+
*
|
|
86
|
+
* @param {ray3} a - source ray3
|
|
87
|
+
* @param {vec3} p - point to measure distance to
|
|
88
|
+
* @returns {number} - distance
|
|
89
|
+
*/
|
|
90
|
+
ray3.distance = function (a, p)
|
|
91
|
+
{
|
|
92
|
+
return Math.sqrt(ray3.squaredDistance(a, p));
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Gets the distance from a ray3"s origin to a plane"s components
|
|
97
|
+
*
|
|
98
|
+
* @author three.js authors (converted)
|
|
99
|
+
* @param {ray3} a - source ray3
|
|
100
|
+
* @param {vec3} n - plane normal
|
|
101
|
+
* @param {number} c - plane constant
|
|
102
|
+
* @returns {null|number} - distance
|
|
103
|
+
*/
|
|
104
|
+
ray3.distanceNormalConstant = function (a, n, c)
|
|
105
|
+
{
|
|
106
|
+
let den = n[0] * a[3] + n[1] * a[4] + n[2] * a[5];
|
|
107
|
+
let dist = (a[0] * n[0] + a[1] * n[1] + a[2] * n[2]) + c;
|
|
108
|
+
if (den === 0)
|
|
109
|
+
{
|
|
110
|
+
if (dist === 0) return 0;
|
|
111
|
+
throw new Error("Determinant error");
|
|
112
|
+
//return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let t = -dist / den;
|
|
116
|
+
return t >= 0 ? t : null;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Gets the distance from a ray3"s origin to a Float32Array(4) plane
|
|
121
|
+
*
|
|
122
|
+
* @author three.js authors (converted)
|
|
123
|
+
* @param {ray3} a - source ray3
|
|
124
|
+
* @param {pln} p - plane to measure distance to
|
|
125
|
+
* @returns {null|Number} - distance
|
|
126
|
+
*/
|
|
127
|
+
ray3.distancePln = function (a, p)
|
|
128
|
+
{
|
|
129
|
+
let den = p[0] * a[3] + p[1] * a[4] + p[2] * a[5];
|
|
130
|
+
let dist = (a[0] * p[0] + a[1] * p[1] + a[2] * p[2]) + p[3];
|
|
131
|
+
|
|
132
|
+
if (den === 0)
|
|
133
|
+
{
|
|
134
|
+
if (dist === 0) return 0;
|
|
135
|
+
throw new Error("Determinant error");
|
|
136
|
+
//return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
let t = -dist / den;
|
|
140
|
+
return t >= 0 ? t : null;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Checks two ray3"s for equality
|
|
145
|
+
*
|
|
146
|
+
* @param {ray3} a
|
|
147
|
+
* @param {ray3} b
|
|
148
|
+
* @returns {boolean}
|
|
149
|
+
*/
|
|
150
|
+
ray3.equals = box3.equals;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Checks a ray3 against it"s components for equality
|
|
154
|
+
*
|
|
155
|
+
* @param {ray3} a
|
|
156
|
+
* @param {vec3} min
|
|
157
|
+
* @param {vec3} max
|
|
158
|
+
* @returns {boolean}
|
|
159
|
+
*/
|
|
160
|
+
ray3.equalsOriginDestination = box3.equalsBounds;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Checks for box3 exact equality
|
|
164
|
+
*
|
|
165
|
+
* @param {ray3} a
|
|
166
|
+
* @param {ray3} b
|
|
167
|
+
* @returns {boolean}
|
|
168
|
+
*/
|
|
169
|
+
ray3.exactEquals = box3.exactEquals;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Checks for exact equality between a ray3 and ray3 components
|
|
173
|
+
*
|
|
174
|
+
* @param {ray3} a
|
|
175
|
+
* @param {vec3} min
|
|
176
|
+
* @param {vec3} max
|
|
177
|
+
* @returns {boolean}
|
|
178
|
+
*/
|
|
179
|
+
ray3.exactEqualsOriginDestination = box3.exactEqualsBounds;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Sets a ray3 from origin and destination
|
|
183
|
+
*
|
|
184
|
+
* @param {ray3} out
|
|
185
|
+
* @param {vec3} o
|
|
186
|
+
* @param {vec3} d
|
|
187
|
+
* @returns {ray3} out
|
|
188
|
+
*/
|
|
189
|
+
ray3.from = box3.from;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Sets a ray3 from an array at an optional offset
|
|
193
|
+
*
|
|
194
|
+
* @param {ray3} out
|
|
195
|
+
* @param {Array} arr
|
|
196
|
+
* @param {number} [index=0]
|
|
197
|
+
* @returns {ray3}
|
|
198
|
+
*/
|
|
199
|
+
ray3.fromArray = box3.fromArray;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Sets a ray 3 from start and end vectors
|
|
203
|
+
*
|
|
204
|
+
* @param {ray3} out
|
|
205
|
+
* @param {vec3} start
|
|
206
|
+
* @param {vec3} end
|
|
207
|
+
* @returns {ray3}
|
|
208
|
+
*/
|
|
209
|
+
ray3.fromStartEnd = function (out, start, end)
|
|
210
|
+
{
|
|
211
|
+
out[0] = start[0];
|
|
212
|
+
out[1] = start[1];
|
|
213
|
+
out[2] = start[2];
|
|
214
|
+
out[3] = end[0] - start[0];
|
|
215
|
+
out[4] = end[1] - start[1];
|
|
216
|
+
out[5] = end[2] - start[2];
|
|
217
|
+
return ray3.normalize(out, out);
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
let mat3_0;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Sets a ray3 from a mat4
|
|
225
|
+
* @param {ray3} out
|
|
226
|
+
* @param {mat4} m
|
|
227
|
+
* @return {ray3}
|
|
228
|
+
*/
|
|
229
|
+
ray3.fromMat4 = function (out, m)
|
|
230
|
+
{
|
|
231
|
+
if (!mat3_0) mat3_0 = mat3.create();
|
|
232
|
+
|
|
233
|
+
out[0] = 0;
|
|
234
|
+
out[1] = 0;
|
|
235
|
+
out[2] = 0;
|
|
236
|
+
out[3] = 0;
|
|
237
|
+
out[4] = 0;
|
|
238
|
+
out[5] = -1;
|
|
239
|
+
|
|
240
|
+
vec3.transformMat4(ray3.$origin(out), ray3.$origin(out), m);
|
|
241
|
+
mat3.fromMat4(mat3_0, m);
|
|
242
|
+
vec3.transformMat3(ray3.$direction(out), ray3.$direction(out), mat3_0);
|
|
243
|
+
return ray3.normalize(out, out);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Sets a ray3 from a screen coordinates and an inverse view projection matrix
|
|
248
|
+
*
|
|
249
|
+
* @param {vec3} out - receiving ray3
|
|
250
|
+
* @param {vec2} coords - canvas coordinates (not client)
|
|
251
|
+
* @param {mat4} m - - inverse view projection matrix
|
|
252
|
+
* @param {mat4} viewport - viewport settings (x, y, width, height)
|
|
253
|
+
*/
|
|
254
|
+
ray3.fromPerspective = function (out, coords, m, viewport)
|
|
255
|
+
{
|
|
256
|
+
// Convert view port co-ordinates
|
|
257
|
+
let x = (coords[0] - viewport[0]) * 2.0 / viewport[2] - 1.0,
|
|
258
|
+
y = (coords[1] - viewport[1]) * 2.0 / viewport[3] - 1.0;
|
|
259
|
+
// Calculate w
|
|
260
|
+
let oW = (m[3] * x + m[7] * y + m[11] * -1 + m[15]),
|
|
261
|
+
dW = (m[3] * x + m[7] * y + m[11] * 1 + m[15]);
|
|
262
|
+
// Check for perspective divide error
|
|
263
|
+
if (oW === 0.0 || dW === 0.0)
|
|
264
|
+
{
|
|
265
|
+
throw new Error("Perspective Divide Error");
|
|
266
|
+
}
|
|
267
|
+
// Transform origin
|
|
268
|
+
out[0] = (m[0] * x + m[4] * y + m[8] * -1 + m[12]) / oW;
|
|
269
|
+
out[1] = (m[1] * x + m[5] * y + m[9] * -1 + m[13]) / oW;
|
|
270
|
+
out[2] = (m[2] * x + m[6] * y + m[10] * -1 + m[14]) / oW;
|
|
271
|
+
// Transform direction
|
|
272
|
+
out[3] = ((m[0] * x + m[4] * y + m[8] * 1 + m[12]) / dW) - out[0];
|
|
273
|
+
out[4] = ((m[1] * x + m[5] * y + m[9] * 1 + m[13]) / dW) - out[1];
|
|
274
|
+
out[5] = ((m[2] * x + m[6] * y + m[10] * 1 + m[14]) / dW) - out[2];
|
|
275
|
+
|
|
276
|
+
// Normalize direction
|
|
277
|
+
return ray3.normalize(out, out);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Alternative to ray3.fromPerspective
|
|
284
|
+
* @param {ray3} out - receiving ray3
|
|
285
|
+
* @param {vec2} coords - event.ClientX, canvasHeight - event.clientY
|
|
286
|
+
* @param {mat4} invProjView - inverse projection view matrix
|
|
287
|
+
* @param {vec4} viewport - x, y, width, height
|
|
288
|
+
* @returns {ray3}
|
|
289
|
+
*/
|
|
290
|
+
ray3.unproject = function (out, coords, invProjView, viewport)
|
|
291
|
+
{
|
|
292
|
+
const
|
|
293
|
+
start = [ coords[0], coords[1], 0 ],
|
|
294
|
+
end = [ coords[0], coords[1], 1 ];
|
|
295
|
+
|
|
296
|
+
vec3.unproject(start, start, invProjView, viewport);
|
|
297
|
+
vec3.unproject(end, end, invProjView, viewport);
|
|
298
|
+
|
|
299
|
+
return ray3.fromStartEnd(out, start, end);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Sets a vec3 with the position on a ray3 at a given distance from it"s origin
|
|
304
|
+
*
|
|
305
|
+
* @param {vec3} out - receiving vec3
|
|
306
|
+
* @param {ray3} a - source ray3
|
|
307
|
+
* @param {number} t - distance along the ray3
|
|
308
|
+
* @returns {vec3} out - receiving vec3
|
|
309
|
+
*/
|
|
310
|
+
ray3.get = function (out, a, t)
|
|
311
|
+
{
|
|
312
|
+
out[0] = a[0] + (a[3] * t);
|
|
313
|
+
out[1] = a[1] + (a[4] * t);
|
|
314
|
+
out[2] = a[2] + (a[5] * t);
|
|
315
|
+
return out;
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Sets a vec3 with the ray3's direction
|
|
320
|
+
*
|
|
321
|
+
* @param {vec3} out - receiving vec3
|
|
322
|
+
* @param {ray3} a - source ray
|
|
323
|
+
* @returns {vec3} [out] - receiving vec3
|
|
324
|
+
*/
|
|
325
|
+
ray3.getDirection = box3.getMax;
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Sets a vec3 with the closest point on a ray3 to a given point
|
|
329
|
+
*
|
|
330
|
+
* @author three.js authors (converted)
|
|
331
|
+
* @param {vec3} out - receiving vec3
|
|
332
|
+
* @param {ray3} a - source ray3
|
|
333
|
+
* @param {vec3} p - point to compare
|
|
334
|
+
* @returns {vec3} out - receiving vec3
|
|
335
|
+
*/
|
|
336
|
+
ray3.getClosestPointToPoint = function (out, a, p)
|
|
337
|
+
{
|
|
338
|
+
let x = p[0] - a[0],
|
|
339
|
+
y = p[1] - a[1],
|
|
340
|
+
z = p[2] - a[2];
|
|
341
|
+
|
|
342
|
+
let dirDist = x * a[3] + y * a[4] + z * a[5];
|
|
343
|
+
|
|
344
|
+
if (dirDist < 0)
|
|
345
|
+
{
|
|
346
|
+
out[0] = a[0];
|
|
347
|
+
out[1] = a[1];
|
|
348
|
+
out[2] = a[2];
|
|
349
|
+
}
|
|
350
|
+
else
|
|
351
|
+
{
|
|
352
|
+
ray3.get(out, a, dirDist);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return out;
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Sets a vec3 with the intersection point of a ray3 and boxes' components
|
|
360
|
+
* - Returns null if there was no intersection, or the receiving vec3 if there was
|
|
361
|
+
*
|
|
362
|
+
* @author three.js authors (converted)
|
|
363
|
+
* @param {vec3} out - receiving vec3
|
|
364
|
+
* @param {ray3} a - source ray3
|
|
365
|
+
* @param {vec3} min - box min bounds
|
|
366
|
+
* @param {vec3} max - box max bounds
|
|
367
|
+
* @returns {(null|vec3)} [out] - null or receiving vec3
|
|
368
|
+
*/
|
|
369
|
+
ray3.getIntersectBounds = function (out, a, min, max)
|
|
370
|
+
{
|
|
371
|
+
let tMin, tMax, tyMin, tyMax, tzMin, tzMax;
|
|
372
|
+
|
|
373
|
+
let invDirX = 1 / a[3],
|
|
374
|
+
invDirY = 1 / a[4],
|
|
375
|
+
invDirZ = 1 / a[5];
|
|
376
|
+
|
|
377
|
+
if (invDirX >= 0)
|
|
378
|
+
{
|
|
379
|
+
tMin = (min[0] - a[0]) * invDirX;
|
|
380
|
+
tMax = (max[0] - a[0]) * invDirX;
|
|
381
|
+
}
|
|
382
|
+
else
|
|
383
|
+
{
|
|
384
|
+
tMin = (max[0] - a[0]) * invDirX;
|
|
385
|
+
tMax = (min[0] - a[0]) * invDirX;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (invDirY >= 0)
|
|
389
|
+
{
|
|
390
|
+
tyMin = (min[1] - a[1]) * invDirY;
|
|
391
|
+
tyMax = (max[1] - a[1]) * invDirY;
|
|
392
|
+
}
|
|
393
|
+
else
|
|
394
|
+
{
|
|
395
|
+
tyMin = (max[1] - a[1]) * invDirY;
|
|
396
|
+
tyMax = (min[1] - a[1]) * invDirY;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if ((tMin > tyMax) || (tyMin > tMax)) return null;
|
|
400
|
+
|
|
401
|
+
if (tyMin > tMin || tMin !== tMin) tMin = tyMin;
|
|
402
|
+
if (tyMax < tMax || tMax !== tMax) tMax = tyMax;
|
|
403
|
+
|
|
404
|
+
if (invDirZ >= 0)
|
|
405
|
+
{
|
|
406
|
+
tzMin = (min[2] - a[2]) * invDirZ;
|
|
407
|
+
tzMax = (max[2] - a[2]) * invDirZ;
|
|
408
|
+
}
|
|
409
|
+
else
|
|
410
|
+
{
|
|
411
|
+
tzMin = (max[2] - a[2]) * invDirZ;
|
|
412
|
+
tzMax = (min[2] - a[2]) * invDirZ;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if ((tMin > tzMax) || (tzMin > tMax)) return null;
|
|
416
|
+
|
|
417
|
+
if (tzMin > tMin || tMin !== tMin) tMin = tzMin;
|
|
418
|
+
if (tzMax < tMax || tMax !== tMax) tMax = tzMax;
|
|
419
|
+
if (tMax < 0) return null;
|
|
420
|
+
|
|
421
|
+
return ray3.get(out, a, tMin >= 0 ? tMin : tMax);
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Sets a vec3 with the intersection point of a ray3 and boxes" components
|
|
426
|
+
* - Returns null if there was no intersection, or the receiving vec3 if there was
|
|
427
|
+
* TODO: Flip internals of getIntersectBounds with this as it will be called more often
|
|
428
|
+
*
|
|
429
|
+
* @param {vec3} out
|
|
430
|
+
* @param {ray3} ray
|
|
431
|
+
* @param {box3|Float32Array} box
|
|
432
|
+
* @returns {null|vec3}
|
|
433
|
+
*/
|
|
434
|
+
ray3.getIntersectBox3 = (function ()
|
|
435
|
+
{
|
|
436
|
+
let vec3_0, vec3_1;
|
|
437
|
+
|
|
438
|
+
return function (out, a, b)
|
|
439
|
+
{
|
|
440
|
+
if (!vec3_0)
|
|
441
|
+
{
|
|
442
|
+
vec3_0 = vec3.create();
|
|
443
|
+
vec3_1 = vec3.create();
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
box3.getMin(vec3_0, b);
|
|
447
|
+
box3.getMax(vec3_1, b);
|
|
448
|
+
|
|
449
|
+
return ray3.getIntersectBounds(out, a, vec3_0, vec3_1);
|
|
450
|
+
};
|
|
451
|
+
})();
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Sets a vec3 with the intersection point of a ray3 and a triangle"s components
|
|
455
|
+
* - Returns null if there was no intersection, or the receiving vec3 if there was
|
|
456
|
+
* @TODO: Flip internals with getIntersectVertices as this will be called more often
|
|
457
|
+
*
|
|
458
|
+
* @param {vec3} out - receiving vec3
|
|
459
|
+
* @param {ray3} a - source ray3
|
|
460
|
+
* @param {tri3} f - The tri3 to intersect
|
|
461
|
+
* @param {boolean} bfc - enables/ disables back face culling
|
|
462
|
+
* @returns {(null|vec3)} [out] - null or receiving vec3
|
|
463
|
+
*/
|
|
464
|
+
ray3.getIntersectTri3 = (function ()
|
|
465
|
+
{
|
|
466
|
+
let vec3_0, vec3_1, vec3_2;
|
|
467
|
+
|
|
468
|
+
return function (out, a, f, bfc)
|
|
469
|
+
{
|
|
470
|
+
if (!vec3_0)
|
|
471
|
+
{
|
|
472
|
+
vec3_0 = vec3.create();
|
|
473
|
+
vec3_1 = vec3.create();
|
|
474
|
+
vec3_2 = vec3.create();
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
tri3.getV1(vec3_0, f);
|
|
478
|
+
tri3.getV2(vec3_1, f);
|
|
479
|
+
tri3.getV3(vec3_2, f);
|
|
480
|
+
|
|
481
|
+
return ray3.getIntersectVertices(out, a, vec3_0, vec3_1, vec3_2, bfc);
|
|
482
|
+
};
|
|
483
|
+
})();
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Sets a vec3 with the intersection point of a ray3 and a triangle"s components
|
|
488
|
+
* - Returns null if there was no intersection, or the receiving vec3 if there was
|
|
489
|
+
*
|
|
490
|
+
* @author three.js authors (converted)
|
|
491
|
+
* @param {vec3} out - receiving vec3
|
|
492
|
+
* @param {ray3} a - source ray3
|
|
493
|
+
* @param {vec3} vertA - first triangle vertex position
|
|
494
|
+
* @param {vec3} vertB - second triangle vertex position
|
|
495
|
+
* @param {vec3} vertC - third triangle vertex position
|
|
496
|
+
* @param {boolean} bfc - enables/ disables back face culling
|
|
497
|
+
* @returns {(null|vec3)} [out] - null or receiving vec3
|
|
498
|
+
*/
|
|
499
|
+
ray3.getIntersectVertices = (function ()
|
|
500
|
+
{
|
|
501
|
+
let vec3_0, vec3_1, vec3_2, vec3_3, vec3_4, vec3_5;
|
|
502
|
+
|
|
503
|
+
return function (out, a, vertA, vertB, vertC, bfc)
|
|
504
|
+
{
|
|
505
|
+
if (!vec3_0)
|
|
506
|
+
{
|
|
507
|
+
vec3_0 = vec3.create();
|
|
508
|
+
vec3_1 = vec3.create();
|
|
509
|
+
vec3_2 = vec3.create();
|
|
510
|
+
vec3_3 = vec3.create();
|
|
511
|
+
vec3_4 = vec3.create();
|
|
512
|
+
vec3_5 = vec3.create();
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
let o = ray3.getOrigin(vec3_4, a);
|
|
516
|
+
let d = ray3.getDirection(vec3_5, a);
|
|
517
|
+
|
|
518
|
+
let diff = vec3.subtract(vec3_0, o, vertA);
|
|
519
|
+
let e1 = vec3.subtract(vec3_1, vertB, vertA);
|
|
520
|
+
let e2 = vec3.subtract(vec3_2, vertC, vertA);
|
|
521
|
+
let n = vec3.cross(vec3_3, e1, e2);
|
|
522
|
+
let DdN = vec3.dot(d, n);
|
|
523
|
+
let sign;
|
|
524
|
+
|
|
525
|
+
if (DdN > 0)
|
|
526
|
+
{
|
|
527
|
+
if (bfc) return null;
|
|
528
|
+
sign = 1;
|
|
529
|
+
}
|
|
530
|
+
else if (DdN < 0)
|
|
531
|
+
{
|
|
532
|
+
sign = -1;
|
|
533
|
+
DdN = -DdN;
|
|
534
|
+
}
|
|
535
|
+
else return null;
|
|
536
|
+
|
|
537
|
+
vec3.cross(e2, diff, e2);
|
|
538
|
+
let b1 = sign * vec3.dot(d, e2);
|
|
539
|
+
if (b1 < 0) return null;
|
|
540
|
+
|
|
541
|
+
vec3.cross(e1, e1, diff);
|
|
542
|
+
let b2 = sign * vec3.dot(d, e1);
|
|
543
|
+
if (b2 < 0) return null;
|
|
544
|
+
if (b1 + b2 > DdN) return null;
|
|
545
|
+
|
|
546
|
+
let QdN = -sign * vec3.dot(diff, n);
|
|
547
|
+
if (QdN < 0) return null;
|
|
548
|
+
|
|
549
|
+
return ray3.get(out, a, QdN / DdN);
|
|
550
|
+
};
|
|
551
|
+
})();
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Sets a vec3 with the intersection point of a ray3 and a plane"s components
|
|
555
|
+
* - Returns null if there was no intersection, or the receiving vec3 if there was
|
|
556
|
+
*
|
|
557
|
+
* @param {vec3} out - receiving vec3
|
|
558
|
+
* @param {ray3} a - source ray3
|
|
559
|
+
* @param {vec3} n - plane normal
|
|
560
|
+
* @param {number} c - plane constant
|
|
561
|
+
* @returns {(null|vec3)} vecOut - null or receiving vec3
|
|
562
|
+
*/
|
|
563
|
+
ray3.getIntersectNormalConstant = function (out, a, n, c)
|
|
564
|
+
{
|
|
565
|
+
let t = ray3.distanceNormalConstant(a, n, c);
|
|
566
|
+
return t !== null ? ray3.get(out, a, t) : null;
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Sets a vec3 with the intersection point of a ray3 and a Float32Array(4) Plane
|
|
571
|
+
* - Returns null if there was no intersection, or the receiving vec3 if there was
|
|
572
|
+
*
|
|
573
|
+
* @param {vec3} out - receiving vec3
|
|
574
|
+
* @param {ray3} a - source ray3
|
|
575
|
+
* @param {(pln|Float32Array)} p - plane to intersect
|
|
576
|
+
* @returns {(null|vec3)} [out] - null or receiving vec3
|
|
577
|
+
*/
|
|
578
|
+
ray3.getIntersectPln = function (out, a, p)
|
|
579
|
+
{
|
|
580
|
+
let t = ray3.distancePln(a, p);
|
|
581
|
+
return t !== null ? ray3.get(out, a, t) : null;
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Sets a vec3 with the intersection point of a ray3 and a sphere"s components
|
|
586
|
+
* - Returns null if there was no intersection, or the receiving vec3 if there was
|
|
587
|
+
*
|
|
588
|
+
* @author three.js authors (converted)
|
|
589
|
+
* @param {vec3} out - receiving vec3
|
|
590
|
+
* @param {ray3} a - source ray3
|
|
591
|
+
* @param {vec3} p - sphere position
|
|
592
|
+
* @param {number} r - sphere radius
|
|
593
|
+
* @returns {(null|vec3)} [out] - null or receiving vec3
|
|
594
|
+
*/
|
|
595
|
+
ray3.getIntersectPositionRadius = (function ()
|
|
596
|
+
{
|
|
597
|
+
let sph3_0;
|
|
598
|
+
|
|
599
|
+
return function (out, a, p, r)
|
|
600
|
+
{
|
|
601
|
+
if (!sph3_0) sph3_0 = sph3.create();
|
|
602
|
+
sph3.from(sph3_0, p, r);
|
|
603
|
+
return ray3.getIntersectSph3(out, a, sph3_0);
|
|
604
|
+
};
|
|
605
|
+
})();
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Sets a vec3 with the intersection point of a ray3 and a Float32Array(4) sphere
|
|
609
|
+
* - Returns null if there was no intersection, or the receiving vec3 if there was
|
|
610
|
+
*
|
|
611
|
+
* @author three.js authors (converted)
|
|
612
|
+
* @param {vec3} out - receiving vec3
|
|
613
|
+
* @param {ray3} a - source ray3
|
|
614
|
+
* @param {sph3} s - sphere
|
|
615
|
+
* @returns {(null|vec3)} [out] - null or receiving vec3
|
|
616
|
+
*/
|
|
617
|
+
ray3.getIntersectSph3 = function (out, a, s)
|
|
618
|
+
{
|
|
619
|
+
let x = s[0] - a[0],
|
|
620
|
+
y = s[1] - a[1],
|
|
621
|
+
z = s[2] - a[2],
|
|
622
|
+
r2 = s[3] * s[3];
|
|
623
|
+
|
|
624
|
+
let tca = x * a[3] + y * a[4] + z * a[5];
|
|
625
|
+
let d2 = (x * x + y * y + z * z) - tca * tca;
|
|
626
|
+
|
|
627
|
+
if (d2 > r2) return null;
|
|
628
|
+
|
|
629
|
+
let thc = Math.sqrt(r2 - d2);
|
|
630
|
+
let t0 = tca - thc;
|
|
631
|
+
let t1 = tca + thc;
|
|
632
|
+
|
|
633
|
+
if (t0 < 0 && t1 < 0) return null;
|
|
634
|
+
if (t0 < 0) return ray3.get(out, a, t1);
|
|
635
|
+
return ray3.get(out, a, t0);
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Gets the origin component of a ray3
|
|
641
|
+
*
|
|
642
|
+
* @param {vec3} out
|
|
643
|
+
* @param {ray3} a
|
|
644
|
+
* @returns {vec3} out
|
|
645
|
+
*/
|
|
646
|
+
ray3.getOrigin = box3.getMin;
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Checks for ray3 intersection with a Float32Array(6) box
|
|
650
|
+
* TODO: Replace internals with intersectsBounds as this will get called more often
|
|
651
|
+
* @param {ray3} a - ray3
|
|
652
|
+
* @param {(box3|Float32Array)} b - box
|
|
653
|
+
* @returns {boolean} - true if intersection occurs
|
|
654
|
+
*/
|
|
655
|
+
ray3.intersectsBox3 = (function ()
|
|
656
|
+
{
|
|
657
|
+
let vec3_0;
|
|
658
|
+
return function (a, b)
|
|
659
|
+
{
|
|
660
|
+
if (!vec3_0) vec3_0 = vec3.create();
|
|
661
|
+
return ray3.vec3_0 = ray3.getIntersectBox3(vec3_0, a, b) !== null;
|
|
662
|
+
};
|
|
663
|
+
})();
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Checks for ray3 intersection with bounds
|
|
667
|
+
*
|
|
668
|
+
* @param {ray3} a - ray3
|
|
669
|
+
* @param {vec3} min - box min bounds
|
|
670
|
+
* @param {vec3} max - box max bounds
|
|
671
|
+
* @returns {boolean} - true if intersection occurs
|
|
672
|
+
*/
|
|
673
|
+
ray3.intersectsBounds = (function ()
|
|
674
|
+
{
|
|
675
|
+
let vec3_0;
|
|
676
|
+
return function intersectsBounds(a, min, max)
|
|
677
|
+
{
|
|
678
|
+
if (!vec3_0) vec3_0 = vec3.create();
|
|
679
|
+
return ray3.getIntersectBounds(vec3_0, a, min, max) !== null;
|
|
680
|
+
};
|
|
681
|
+
})();
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Checks for ray3 intersection with a plane"s components
|
|
685
|
+
*
|
|
686
|
+
* @param {ray3} a - source ray3
|
|
687
|
+
* @param {vec3} n - plane normal
|
|
688
|
+
* @param {number} c - plane constant
|
|
689
|
+
* @returns {boolean} - true if intersection occurs
|
|
690
|
+
*/
|
|
691
|
+
ray3.intersectsNormalConstant = function (a, n, c)
|
|
692
|
+
{
|
|
693
|
+
let dist = (a[0] * n[0] + a[1] * n[1] + a[2] * n[2]) + c;
|
|
694
|
+
return dist === 0 ? true : ((n[0] * a[3] + n[1] * a[4] + n[2] * a[5]) * dist < 0);
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Checks for ray3 intersection with a Float32Array(4) plane
|
|
699
|
+
*
|
|
700
|
+
* @param {ray3} a - source ray3
|
|
701
|
+
* @param {pln} p - plane
|
|
702
|
+
* @returns {boolean} - true if intersection occurs
|
|
703
|
+
*/
|
|
704
|
+
ray3.intersectsPln = function (a, p)
|
|
705
|
+
{
|
|
706
|
+
let dist = (a[0] * p[0] + a[1] * p[1] + a[2] * p[2]) + p[3];
|
|
707
|
+
return (dist === 0) ? true : ((p[0] * a[3] + p[1] * a[4] + p[2] * a[5]) * dist < 0);
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Checks for ray3 intersection with a sphere"s components
|
|
712
|
+
*
|
|
713
|
+
* @param {ray3} a - source ray3
|
|
714
|
+
* @param {vec3} p - sphere position
|
|
715
|
+
* @param {number} r - sphere radius
|
|
716
|
+
* @returns {boolean} - true if intersection occurs
|
|
717
|
+
*/
|
|
718
|
+
ray3.intersectsPositionRadius = function (a, p, r)
|
|
719
|
+
{
|
|
720
|
+
return ray3.distance(a, p) <= r;
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Checks for ray3 intersection with a Float32Array(4) Sphere
|
|
725
|
+
*
|
|
726
|
+
* @param {ray3} a - source ray3
|
|
727
|
+
* @param {sph3|Float32Array} s - sphere
|
|
728
|
+
* @returns {boolean} - true if intersection occurs
|
|
729
|
+
*/
|
|
730
|
+
ray3.intersectsSph3 = function (a, s)
|
|
731
|
+
{
|
|
732
|
+
return ray3.distance(a, s) <= s[3];
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Sets the direction of a ray3 to be looking at a specific point
|
|
737
|
+
*
|
|
738
|
+
* @param {ray3} out - receiving ray3
|
|
739
|
+
* @param {vec3} a - source ray3
|
|
740
|
+
* @param {vec3} p - point to look at
|
|
741
|
+
* @returns {ray3} out - receiving ray3
|
|
742
|
+
*/
|
|
743
|
+
ray3.lookAt = function (out, a, p)
|
|
744
|
+
{
|
|
745
|
+
out[0] = a[0];
|
|
746
|
+
out[1] = a[1];
|
|
747
|
+
out[2] = a[2];
|
|
748
|
+
out[3] = p[0] - a[0];
|
|
749
|
+
out[4] = p[1] - a[1];
|
|
750
|
+
out[5] = p[2] - a[2];
|
|
751
|
+
return ray3.normalize(out, out);
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Sets a ray3 from the results of normalizing another
|
|
756
|
+
*
|
|
757
|
+
* @param {ray3} out - receiving ray3
|
|
758
|
+
* @param {ray3} a - source ray3
|
|
759
|
+
* @returns {ray3} out - receiving ray3
|
|
760
|
+
*/
|
|
761
|
+
ray3.normalize = function (out, a)
|
|
762
|
+
{
|
|
763
|
+
if (out !== a)
|
|
764
|
+
{
|
|
765
|
+
out[0] = a[0];
|
|
766
|
+
out[1] = a[1];
|
|
767
|
+
out[2] = a[2];
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
let x = a[3],
|
|
771
|
+
y = a[4],
|
|
772
|
+
z = a[5];
|
|
773
|
+
|
|
774
|
+
// Normalize the direction
|
|
775
|
+
let len = x * x + y * y + z * z;
|
|
776
|
+
if (len > 0)
|
|
777
|
+
{
|
|
778
|
+
len = 1 / Math.sqrt(len);
|
|
779
|
+
out[3] = x * len;
|
|
780
|
+
out[4] = y * len;
|
|
781
|
+
out[5] = z * len;
|
|
782
|
+
}
|
|
783
|
+
else
|
|
784
|
+
{
|
|
785
|
+
out[1] = 0;
|
|
786
|
+
out[2] = 0;
|
|
787
|
+
out[3] = 0;
|
|
788
|
+
throw new Error("Normalization error");
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
return out;
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Shifts the origin of a ray3 to be further down it"s direction
|
|
796
|
+
*
|
|
797
|
+
* @param {ray3} out - receiving ray3
|
|
798
|
+
* @param {ray3} a - source ray3
|
|
799
|
+
* @param {number} t - distance along the ray3
|
|
800
|
+
* @returns {ray3} - receiving ray3
|
|
801
|
+
*/
|
|
802
|
+
ray3.recast = function (out, a, t)
|
|
803
|
+
{
|
|
804
|
+
out[0] = a[0] + (a[3] * t);
|
|
805
|
+
out[1] = a[1] + (a[4] * t);
|
|
806
|
+
out[2] = a[2] + (a[5] * t);
|
|
807
|
+
out[3] = a[3];
|
|
808
|
+
out[4] = a[4];
|
|
809
|
+
out[5] = a[5];
|
|
810
|
+
return out;
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
/**
|
|
814
|
+
* Sets a ray3 from values
|
|
815
|
+
*
|
|
816
|
+
* @param {ray3} out
|
|
817
|
+
* @param {vec3} startProp
|
|
818
|
+
* @param {vec3} endProp
|
|
819
|
+
* @returns {ray3} out
|
|
820
|
+
*/
|
|
821
|
+
ray3.set = box3.set;
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Ray3 generic sorting
|
|
825
|
+
*
|
|
826
|
+
* @param {{}} a
|
|
827
|
+
* @param {number} a.distance
|
|
828
|
+
* @param {{}} b
|
|
829
|
+
* @param {number} b.distance
|
|
830
|
+
* @returns {number}
|
|
831
|
+
*/
|
|
832
|
+
ray3.SORT = function (a, b)
|
|
833
|
+
{
|
|
834
|
+
return a.distance - b.distance;
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Gets the squared distance from a ray3 to a point
|
|
839
|
+
*
|
|
840
|
+
* @author three.js authors (converted)
|
|
841
|
+
* @param {ray3} a - source ray3
|
|
842
|
+
* @param {vec3} p - point to measure distance to
|
|
843
|
+
* @returns {number} - squared distance
|
|
844
|
+
*/
|
|
845
|
+
ray3.squaredDistance = (function ()
|
|
846
|
+
{
|
|
847
|
+
let vec3_0, vec3_1;
|
|
848
|
+
return function distanceSquared(a, p)
|
|
849
|
+
{
|
|
850
|
+
if (!vec3_0)
|
|
851
|
+
{
|
|
852
|
+
vec3_0 = vec3.create();
|
|
853
|
+
vec3_1 = vec3.create();
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
vec3_0[0] = p[0] - a[0];
|
|
857
|
+
vec3_0[1] = p[1] - a[1];
|
|
858
|
+
vec3_0[2] = p[2] - a[2];
|
|
859
|
+
|
|
860
|
+
let dirDist = vec3_0[0] * a[3] + vec3_0[1] * a[4] + vec3_0[2] * a[5];
|
|
861
|
+
if (dirDist < 0)
|
|
862
|
+
{
|
|
863
|
+
ray3.getOrigin(vec3_1, a);
|
|
864
|
+
return vec3.squaredDistance(vec3_1, p); // could just pass in the ray3
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
ray3.get(vec3_0, a, dirDist);
|
|
868
|
+
return vec3.squaredDistance(vec3_0, p);
|
|
869
|
+
};
|
|
870
|
+
})();
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Sets an array at at optional offset from a ray3
|
|
874
|
+
*
|
|
875
|
+
* @param {ray3} a
|
|
876
|
+
* @param {Array} arr
|
|
877
|
+
* @param {number} [index]
|
|
878
|
+
* @returns {ray3} a
|
|
879
|
+
*/
|
|
880
|
+
ray3.toArray = box3.toArray;
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Sets origin and direction vectors from a ray3
|
|
884
|
+
*
|
|
885
|
+
* @param {ray3} a
|
|
886
|
+
* @param {vec3} origin
|
|
887
|
+
* @param {vec3} direction
|
|
888
|
+
* @returns {ray3} a
|
|
889
|
+
*/
|
|
890
|
+
ray3.toOriginDirection = function (a, origin, direction)
|
|
891
|
+
{
|
|
892
|
+
origin[0] = a[0];
|
|
893
|
+
origin[1] = a[1];
|
|
894
|
+
origin[2] = a[2];
|
|
895
|
+
direction[0] = a[3];
|
|
896
|
+
direction[1] = a[4];
|
|
897
|
+
direction[2] = a[5];
|
|
898
|
+
return a;
|
|
899
|
+
};
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Transforms a ray3 by a mat4
|
|
903
|
+
*
|
|
904
|
+
* @param {ray3} out - receiving ray3
|
|
905
|
+
* @param {vec3} a - ray3 to transform
|
|
906
|
+
* @param {mat4} m - matrix to transform by
|
|
907
|
+
*/
|
|
908
|
+
ray3.transformMat4 = function (out, a, m)
|
|
909
|
+
{
|
|
910
|
+
let oX = a[0],
|
|
911
|
+
oY = a[1],
|
|
912
|
+
oZ = a[2],
|
|
913
|
+
dX = a[3] + a[0],
|
|
914
|
+
dY = a[4] + a[1],
|
|
915
|
+
dZ = a[5] + a[2];
|
|
916
|
+
|
|
917
|
+
// Calculate w
|
|
918
|
+
let oW = (m[3] * oX + m[7] * oY + m[11] * oZ + m[15]) || 1.0,
|
|
919
|
+
dW = (m[3] * dX + m[7] * dY + m[11] * dZ + m[15]) || 1.0;
|
|
920
|
+
// Transform origin
|
|
921
|
+
out[0] = (m[0] * oX + m[4] * oY + m[8] * oZ + m[12]) / oW;
|
|
922
|
+
out[1] = (m[1] * oX + m[5] * oY + m[9] * oZ + m[13]) / oW;
|
|
923
|
+
out[2] = (m[2] * oX + m[6] * oY + m[10] * oZ + m[14]) / oW;
|
|
924
|
+
// Transform direction
|
|
925
|
+
out[3] = (m[0] * dX + m[4] * dY + m[8] * dZ + m[12]) / dW - out[0];
|
|
926
|
+
out[4] = (m[1] * dX + m[5] * dY + m[9] * dZ + m[13]) / dW - out[1];
|
|
927
|
+
out[5] = (m[2] * dX + m[6] * dY + m[10] * dZ + m[14]) / dW - out[2];
|
|
928
|
+
// Normalize direction
|
|
929
|
+
return ray3.normalize(out, out);
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* Translates a ray3
|
|
934
|
+
*
|
|
935
|
+
* @param {ray3} out
|
|
936
|
+
* @param {ray3} a
|
|
937
|
+
* @param {vec3} v
|
|
938
|
+
* @returns {ray3} out
|
|
939
|
+
*/
|
|
940
|
+
ray3.translate = function (out, a, v)
|
|
941
|
+
{
|
|
942
|
+
out[0] = a[0] + v[0];
|
|
943
|
+
out[1] = a[1] + v[1];
|
|
944
|
+
out[2] = a[2] + v[2];
|
|
945
|
+
out[3] = a[3];
|
|
946
|
+
out[4] = a[4];
|
|
947
|
+
out[5] = a[5];
|
|
948
|
+
return out;
|
|
949
|
+
};
|
|
950
|
+
|
|
951
|
+
let viewPort;
|
|
952
|
+
|
|
953
|
+
/**
|
|
954
|
+
* Gets a ray3 from an element event
|
|
955
|
+
* @param {ray3} ray
|
|
956
|
+
* @param {mat4} viewProjectionInverse
|
|
957
|
+
* @param {event} event
|
|
958
|
+
* @param {vec2} [mouse]
|
|
959
|
+
* @param {vec2} [pixel]
|
|
960
|
+
* @param {vec2} [css]
|
|
961
|
+
* @returns {ray3}
|
|
962
|
+
*/
|
|
963
|
+
ray3.fromEvent = function (ray, viewProjectionInverse, event, mouse, pixel, css)
|
|
964
|
+
{
|
|
965
|
+
if (!viewPort) viewPort = pln.create();
|
|
966
|
+
|
|
967
|
+
const
|
|
968
|
+
el = event.target || event.srcElement,
|
|
969
|
+
rect = el.getBoundingClientRect(),
|
|
970
|
+
mX = event.clientX,
|
|
971
|
+
mY = event.clientY,
|
|
972
|
+
cX = mX - rect.left,
|
|
973
|
+
cY = mY - rect.top,
|
|
974
|
+
pX = cX * el.width / el.clientWidth,
|
|
975
|
+
pY = el.height - cY * el.height / el.clientHeight - 1;
|
|
976
|
+
|
|
977
|
+
// Should this be a param?
|
|
978
|
+
viewPort[0] = 0;
|
|
979
|
+
viewPort[1] = 0;
|
|
980
|
+
viewPort[2] = el.width;
|
|
981
|
+
viewPort[3] = el.height;
|
|
982
|
+
|
|
983
|
+
if (mouse)
|
|
984
|
+
{
|
|
985
|
+
mouse[0] = mX;
|
|
986
|
+
mouse[1] = mY;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
if (pixel)
|
|
990
|
+
{
|
|
991
|
+
pixel[0] = pX;
|
|
992
|
+
pixel[1] = pY;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
if (css)
|
|
996
|
+
{
|
|
997
|
+
css[0] = cX;
|
|
998
|
+
css[1] = cY;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
return ray3.unproject(ray, [ pX, pY ], viewProjectionInverse, viewPort);
|
|
1002
|
+
};
|
|
1003
|
+
|
|
1004
|
+
export const {
|
|
1005
|
+
alloc,
|
|
1006
|
+
unalloc,
|
|
1007
|
+
$origin,
|
|
1008
|
+
$direction,
|
|
1009
|
+
clone,
|
|
1010
|
+
copy,
|
|
1011
|
+
copyOrigin,
|
|
1012
|
+
copyDirection,
|
|
1013
|
+
create,
|
|
1014
|
+
distance,
|
|
1015
|
+
distanceNormalConstant,
|
|
1016
|
+
distancePln,
|
|
1017
|
+
equals,
|
|
1018
|
+
equalsOriginDestination,
|
|
1019
|
+
exactEquals,
|
|
1020
|
+
exactEqualsOriginDestination,
|
|
1021
|
+
from,
|
|
1022
|
+
fromArray,
|
|
1023
|
+
fromStartEnd,
|
|
1024
|
+
fromMat4,
|
|
1025
|
+
fromPerspective,
|
|
1026
|
+
unproject,
|
|
1027
|
+
get,
|
|
1028
|
+
getDirection,
|
|
1029
|
+
getClosestPointToPoint,
|
|
1030
|
+
getIntersectBounds,
|
|
1031
|
+
getIntersectBox3,
|
|
1032
|
+
getIntersectTri3,
|
|
1033
|
+
getIntersectVertices,
|
|
1034
|
+
getIntersectNormalConstant,
|
|
1035
|
+
getIntersectPln,
|
|
1036
|
+
getIntersectPositionRadius,
|
|
1037
|
+
getIntersectSph3,
|
|
1038
|
+
getOrigin,
|
|
1039
|
+
intersectsBox3,
|
|
1040
|
+
intersectsBounds,
|
|
1041
|
+
intersectsNormalConstant,
|
|
1042
|
+
intersectsPln,
|
|
1043
|
+
intersectsPositionRadius,
|
|
1044
|
+
intersectsSph3,
|
|
1045
|
+
lookAt,
|
|
1046
|
+
normalize,
|
|
1047
|
+
recast,
|
|
1048
|
+
set,
|
|
1049
|
+
SORT,
|
|
1050
|
+
squaredDistance,
|
|
1051
|
+
toArray,
|
|
1052
|
+
toOriginDirection,
|
|
1053
|
+
transformMat4,
|
|
1054
|
+
translate,
|
|
1055
|
+
fromEvent
|
|
1056
|
+
} = ray3;
|