@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/num.js
ADDED
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
export const num = {};
|
|
2
|
+
|
|
3
|
+
num.EPSILON = 0.000001;
|
|
4
|
+
num.RAD2DEG = 180 / Math.PI;
|
|
5
|
+
num.DEG2RAD = Math.PI / 180;
|
|
6
|
+
num.TWO_PI = Math.PI * 2;
|
|
7
|
+
num.PI = Math.PI;
|
|
8
|
+
num.INV_TWO_PI = 1 / num.TWO_PI;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* biCumulative
|
|
12
|
+
*
|
|
13
|
+
* @param {number} t
|
|
14
|
+
* @param {number} order
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
num.biCumulative = function (t, order)
|
|
18
|
+
{
|
|
19
|
+
if (order === 1)
|
|
20
|
+
{
|
|
21
|
+
const some = (1.0 - t);
|
|
22
|
+
return 1.0 - some * some * some;
|
|
23
|
+
}
|
|
24
|
+
else if (order === 2)
|
|
25
|
+
{
|
|
26
|
+
return 3.0 * t * t - 2.0 * t * t * t;
|
|
27
|
+
}
|
|
28
|
+
else
|
|
29
|
+
{
|
|
30
|
+
return t * t * t;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @alias Math.ceil
|
|
36
|
+
*/
|
|
37
|
+
num.ceil = Math.ceil;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Clamps a number
|
|
41
|
+
*
|
|
42
|
+
* @param {number} a
|
|
43
|
+
* @param {number} min
|
|
44
|
+
* @param {number} max
|
|
45
|
+
* @returns {number}
|
|
46
|
+
*/
|
|
47
|
+
num.clamp = function (a, min, max)
|
|
48
|
+
{
|
|
49
|
+
return Math.max(min, Math.min(max, a));
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Returns how many decimal places a number has
|
|
54
|
+
*
|
|
55
|
+
* @param {number} a
|
|
56
|
+
* @returns {number}
|
|
57
|
+
*/
|
|
58
|
+
num.decimalPlaces = function (a)
|
|
59
|
+
{
|
|
60
|
+
let match = ("" + a).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
|
|
61
|
+
return match ? Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)) : 0;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Converts from radians to degrees
|
|
66
|
+
*
|
|
67
|
+
* @param {number} a
|
|
68
|
+
* @returns {number}
|
|
69
|
+
*/
|
|
70
|
+
num.degrees = function (a)
|
|
71
|
+
{
|
|
72
|
+
return a * num.RAD2DEG;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Converts from radians to unwrapped degrees
|
|
77
|
+
*
|
|
78
|
+
* @param {number} a
|
|
79
|
+
* @returns {number}
|
|
80
|
+
*/
|
|
81
|
+
num.degreesUnwrapped = function (a)
|
|
82
|
+
{
|
|
83
|
+
return num.unwrapDegrees(a * num.RAD2DEG);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Converts a Dword to Float
|
|
88
|
+
* @param value
|
|
89
|
+
* @return {Number}
|
|
90
|
+
*/
|
|
91
|
+
num.dwordToFloat = function (value)
|
|
92
|
+
{
|
|
93
|
+
const
|
|
94
|
+
b4 = (value & 0xff),
|
|
95
|
+
b3 = (value & 0xff00) >> 8,
|
|
96
|
+
b2 = (value & 0xff0000) >> 16,
|
|
97
|
+
b1 = (value & 0xff000000) >> 24,
|
|
98
|
+
sign = 1 - (2 * (b1 >> 7)), // sign = bit 0
|
|
99
|
+
exp = (((b1 << 1) & 0xff) | (b2 >> 7)) - 127, // exponent = bits 1..8
|
|
100
|
+
sig = ((b2 & 0x7f) << 16) | (b3 << 8) | b4; // significand = bits 9..31
|
|
101
|
+
|
|
102
|
+
if (sig === 0 && exp === -127) return 0.0;
|
|
103
|
+
return sign * (1 + sig * Math.pow(2, -23)) * Math.pow(2, exp);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Checks if a number equals another
|
|
108
|
+
*
|
|
109
|
+
* @param a
|
|
110
|
+
* @param b
|
|
111
|
+
* @returns {boolean}
|
|
112
|
+
*/
|
|
113
|
+
num.equals = function (a, b)
|
|
114
|
+
{
|
|
115
|
+
return Math.abs(a - b) <= num.EPSILON * Math.max(1.0, Math.abs(a), Math.abs(b));
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Checks if a number exactly equals another
|
|
120
|
+
* - included for library consistency
|
|
121
|
+
*
|
|
122
|
+
* @param {number} a
|
|
123
|
+
* @param {number} b
|
|
124
|
+
* @returns {boolean}
|
|
125
|
+
*/
|
|
126
|
+
num.exactEquals = function (a, b)
|
|
127
|
+
{
|
|
128
|
+
return a === b;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Exponential decay
|
|
133
|
+
*
|
|
134
|
+
* @param {number} omega0
|
|
135
|
+
* @param {number} torque
|
|
136
|
+
* @param {number} I - inertia
|
|
137
|
+
* @param {number} d - drag
|
|
138
|
+
* @param {number} time - time
|
|
139
|
+
* @returns {number}
|
|
140
|
+
*/
|
|
141
|
+
num.exponentialDecay = function (omega0, torque, I, d, time)
|
|
142
|
+
{
|
|
143
|
+
return torque * time / d + I * (omega0 * d - torque) / (d * d) * (1.0 - Math.pow(Math.E, -d * time / I));
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Gets the fractional components of a number
|
|
148
|
+
*
|
|
149
|
+
* @param {number} a
|
|
150
|
+
* @returns {number}
|
|
151
|
+
*/
|
|
152
|
+
num.fract = function (a)
|
|
153
|
+
{
|
|
154
|
+
return a - Math.floor(a);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Gets a value from a half float
|
|
159
|
+
* @author Babylon
|
|
160
|
+
* @param {number} a
|
|
161
|
+
* @returns {number}
|
|
162
|
+
*/
|
|
163
|
+
num.fromHalfFloat = function (a)
|
|
164
|
+
{
|
|
165
|
+
const
|
|
166
|
+
s = (a & 0x8000) >> 15,
|
|
167
|
+
e = (a & 0x7C00) >> 10,
|
|
168
|
+
f = a & 0x03FF;
|
|
169
|
+
|
|
170
|
+
if (e === 0)
|
|
171
|
+
{
|
|
172
|
+
return (s ? -1 : 1) * Math.pow(2, -14) * (f / Math.pow(2, 10));
|
|
173
|
+
}
|
|
174
|
+
else if (e === 0x1F)
|
|
175
|
+
{
|
|
176
|
+
return f ? NaN : ((s ? -1 : 1) * Infinity);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return (s ? -1 : 1) * Math.pow(2, e - 15) * (1 + (f / Math.pow(2, 10)));
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* @alias Math.floor
|
|
184
|
+
*/
|
|
185
|
+
num.floor = Math.floor;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Gets long word order
|
|
189
|
+
* @author Babylon
|
|
190
|
+
* @param {number} a
|
|
191
|
+
* @returns {number}
|
|
192
|
+
*/
|
|
193
|
+
num.getLongWordOrder = function (a)
|
|
194
|
+
{
|
|
195
|
+
return (a === 0 || a === 255 || a === -16777216) ? 0 : 1 + num.getLongWordOrder(a >> 8);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
*
|
|
200
|
+
*
|
|
201
|
+
* @param {number} a
|
|
202
|
+
* @param {number} b
|
|
203
|
+
* @returns {number}
|
|
204
|
+
*/
|
|
205
|
+
num.greaterThan = function (a, b)
|
|
206
|
+
{
|
|
207
|
+
return a > b ? 1 : 0;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
*
|
|
212
|
+
*
|
|
213
|
+
* @param {number} a
|
|
214
|
+
* @param {number} b
|
|
215
|
+
* @returns {number}
|
|
216
|
+
*/
|
|
217
|
+
num.greaterThanEqual = function (a, b)
|
|
218
|
+
{
|
|
219
|
+
return num.isEqual(a, b) || a > b ? 1 : 0;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
*
|
|
224
|
+
* - included for library consistency
|
|
225
|
+
*
|
|
226
|
+
* @param {number} a
|
|
227
|
+
* @param {number} b
|
|
228
|
+
* @returns {number}
|
|
229
|
+
*/
|
|
230
|
+
num.greaterThanExactEqual = function (a, b)
|
|
231
|
+
{
|
|
232
|
+
return a >= b ? 1 : 0;
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Checks if a number is even
|
|
238
|
+
*
|
|
239
|
+
* @param {number} a
|
|
240
|
+
* @returns {boolean}
|
|
241
|
+
*/
|
|
242
|
+
num.isEven = function (a)
|
|
243
|
+
{
|
|
244
|
+
return Math.abs(a) % 2 === 0;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Checks if a number is a float
|
|
249
|
+
*
|
|
250
|
+
* @param {number} a
|
|
251
|
+
* @returns {boolean}
|
|
252
|
+
*/
|
|
253
|
+
num.isFloat = function (a)
|
|
254
|
+
{
|
|
255
|
+
return a % 1 !== 0;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* @alias Number.isFinite
|
|
260
|
+
*/
|
|
261
|
+
num.isFinite = Number.isFinite;
|
|
262
|
+
// return (typeof v === "number" && !isNaN(v) && v !== Infinity && v !== -Infinity);
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Checks if a number is an integer
|
|
266
|
+
*
|
|
267
|
+
* @param {number} a
|
|
268
|
+
* @returns {boolean}
|
|
269
|
+
*/
|
|
270
|
+
num.isInt = function (a)
|
|
271
|
+
{
|
|
272
|
+
return a % 1 === 0;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @alias Number.isNaN
|
|
277
|
+
*/
|
|
278
|
+
num.isNaN = Number.isNaN;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Checks if a number is odd
|
|
282
|
+
*
|
|
283
|
+
* @param {number} a
|
|
284
|
+
* @returns {boolean}
|
|
285
|
+
*/
|
|
286
|
+
num.isOdd = function (a)
|
|
287
|
+
{
|
|
288
|
+
return Math.abs(a) % 2 === 1;
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Checks if a number is to the power of two
|
|
293
|
+
*
|
|
294
|
+
* @param {number} a
|
|
295
|
+
* @returns {boolean}
|
|
296
|
+
*/
|
|
297
|
+
num.isPowerOfTwo = function (a)
|
|
298
|
+
{
|
|
299
|
+
return (a & (a - 1)) === 0 && a !== 0;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
*
|
|
304
|
+
*
|
|
305
|
+
* @param {number} a
|
|
306
|
+
* @param {number} b
|
|
307
|
+
* @returns {number}
|
|
308
|
+
*/
|
|
309
|
+
num.lessThan = function (a, b)
|
|
310
|
+
{
|
|
311
|
+
return a < b ? 1 : 0;
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
*
|
|
316
|
+
*
|
|
317
|
+
* @param {number} a
|
|
318
|
+
* @param {number} b
|
|
319
|
+
* @returns {number}
|
|
320
|
+
*/
|
|
321
|
+
num.lessThanEqual = function (a, b)
|
|
322
|
+
{
|
|
323
|
+
return num.isEqual(a, b) || a < b ? 1 : 0;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
*
|
|
328
|
+
* - included for library consistency
|
|
329
|
+
*
|
|
330
|
+
* @param {number} a
|
|
331
|
+
* @param {number} b
|
|
332
|
+
* @returns {number}
|
|
333
|
+
*/
|
|
334
|
+
num.lessThanExactEqual = function (a, b)
|
|
335
|
+
{
|
|
336
|
+
return a <= b ? 1 : 0;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Gets the log2 of a number
|
|
341
|
+
* @param {number} a
|
|
342
|
+
* @returns {number}
|
|
343
|
+
*/
|
|
344
|
+
num.log2 = function (a)
|
|
345
|
+
{
|
|
346
|
+
return Math.log(a) * Math.LOG2E;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @alias Math.max
|
|
351
|
+
*/
|
|
352
|
+
num.max = Math.max;
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* @alias Math.min
|
|
356
|
+
*/
|
|
357
|
+
num.min = Math.min;
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Gets the nearest power of two value to a number
|
|
362
|
+
*
|
|
363
|
+
* @param {number} a
|
|
364
|
+
* @returns {number}
|
|
365
|
+
*/
|
|
366
|
+
num.nearestPowerOfTwo = function (a)
|
|
367
|
+
{
|
|
368
|
+
return Math.pow(2, Math.round(Math.log(a) / Math.LN2));
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
*
|
|
373
|
+
*
|
|
374
|
+
* @param {number} value
|
|
375
|
+
* @param {number} start
|
|
376
|
+
* @param {number} end
|
|
377
|
+
* @param {number} precision
|
|
378
|
+
* @returns {number}
|
|
379
|
+
*/
|
|
380
|
+
num.normalizeInt = function (value, start, end, precision)
|
|
381
|
+
{
|
|
382
|
+
let width = end - start;
|
|
383
|
+
let offsetValue = value - start;
|
|
384
|
+
let result = (offsetValue - ((offsetValue / width) * width)) + start;
|
|
385
|
+
return precision === undefined ? result : Number(result.toFixed(precision));
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
*
|
|
390
|
+
*
|
|
391
|
+
* @param {number} value
|
|
392
|
+
* @param {number} start
|
|
393
|
+
* @param {number} end
|
|
394
|
+
* @param {number} precision
|
|
395
|
+
* @returns {number}
|
|
396
|
+
*/
|
|
397
|
+
num.normalizeFloat = function (value, start, end, precision)
|
|
398
|
+
{
|
|
399
|
+
let width = end - start;
|
|
400
|
+
let offsetValue = value - start;
|
|
401
|
+
let result = (offsetValue - (Math.floor(offsetValue / width) * width)) + start;
|
|
402
|
+
return precision === undefined ? result : Number(result.toFixed(precision));
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Converts from degrees to radians
|
|
408
|
+
*
|
|
409
|
+
* @param {number} a
|
|
410
|
+
* @returns {number}
|
|
411
|
+
*/
|
|
412
|
+
num.radians = function (a)
|
|
413
|
+
{
|
|
414
|
+
return a * num.DEG2RAD;
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Converts from degrees to unwrapped radians
|
|
419
|
+
*
|
|
420
|
+
* @param {number} a
|
|
421
|
+
* @returns {number}
|
|
422
|
+
*/
|
|
423
|
+
num.radiansUnwrapped = function (a)
|
|
424
|
+
{
|
|
425
|
+
return num.unwrapRadians(a *= num.DEG2RAD);
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Creates a random integer
|
|
430
|
+
*
|
|
431
|
+
* @param {number} low
|
|
432
|
+
* @param {number} high
|
|
433
|
+
* @returns {number}
|
|
434
|
+
*/
|
|
435
|
+
num.randomInt = function (low, high)
|
|
436
|
+
{
|
|
437
|
+
return low + Math.floor(Math.random() * (high - low + 1));
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Creates a random float
|
|
442
|
+
*
|
|
443
|
+
* @param {number} low
|
|
444
|
+
* @param {number} high
|
|
445
|
+
* @returns {number}
|
|
446
|
+
*/
|
|
447
|
+
num.randomFloat = function (low, high)
|
|
448
|
+
{
|
|
449
|
+
return low + Math.random() * (high - low);
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* @alias for Math.round
|
|
454
|
+
*/
|
|
455
|
+
num.round = Math.round;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Rounds a number to the closest zero
|
|
459
|
+
*
|
|
460
|
+
* @param {number} a
|
|
461
|
+
* @returns {number}
|
|
462
|
+
*/
|
|
463
|
+
num.roundToZero = function (a)
|
|
464
|
+
{
|
|
465
|
+
return a < 0 ? Math.ceil(a) : Math.floor(a);
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* @alias for num.greaterThan
|
|
470
|
+
*/
|
|
471
|
+
num.step = num.greaterThan;
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Force positive number (excluding 0)
|
|
475
|
+
* @param {Number} s
|
|
476
|
+
* @returns {Number}
|
|
477
|
+
*/
|
|
478
|
+
num.strictPositive = function (s)
|
|
479
|
+
{
|
|
480
|
+
return Math.max(num.EPSILON, Math.abs(s));
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Force negative number (excluding 0)
|
|
485
|
+
* @param {Number} s
|
|
486
|
+
* @returns {Number}
|
|
487
|
+
*/
|
|
488
|
+
num.strictNegative = function (s)
|
|
489
|
+
{
|
|
490
|
+
return -Math.max(num.EPSILON, Math.abs(s));
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
*
|
|
496
|
+
* @param a
|
|
497
|
+
* @param min
|
|
498
|
+
* @param max
|
|
499
|
+
* @returns {number}
|
|
500
|
+
*/
|
|
501
|
+
num.smoothStep = function (a, min, max)
|
|
502
|
+
{
|
|
503
|
+
if (a <= min) return 0;
|
|
504
|
+
if (a >= max) return 1;
|
|
505
|
+
a = (a - min) / (max - min);
|
|
506
|
+
return a * a * (3 - 2 * a);
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
*
|
|
511
|
+
* @param a
|
|
512
|
+
* @param min
|
|
513
|
+
* @param max
|
|
514
|
+
* @returns {number}
|
|
515
|
+
*/
|
|
516
|
+
num.smootherStep = function (a, min, max)
|
|
517
|
+
{
|
|
518
|
+
if (a <= min) return 0;
|
|
519
|
+
if (a >= max) return 1;
|
|
520
|
+
a = (a - min) / (max - min);
|
|
521
|
+
return a * a * a * (a * (a * 6 - 15) + 10);
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Converts a number to a half float
|
|
526
|
+
* @author http://stackoverflow.com/questions/32633585/how-do-you-convert-to-half-floats-in-javascript
|
|
527
|
+
* @param {number} a
|
|
528
|
+
* @returns {number}
|
|
529
|
+
*/
|
|
530
|
+
num.toHalfFloat = (function ()
|
|
531
|
+
{
|
|
532
|
+
let floatView, int32View;
|
|
533
|
+
|
|
534
|
+
return function (a)
|
|
535
|
+
{
|
|
536
|
+
if (!floatView)
|
|
537
|
+
{
|
|
538
|
+
floatView = new Float32Array(1);
|
|
539
|
+
int32View = new Int32Array(floatView.buffer);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
floatView[0] = a;
|
|
543
|
+
const x = int32View[0];
|
|
544
|
+
|
|
545
|
+
let bits = (x >> 16) & 0x8000;
|
|
546
|
+
/* Get the sign */
|
|
547
|
+
let m = (x >> 12) & 0x07ff;
|
|
548
|
+
/* Keep one extra bit for rounding */
|
|
549
|
+
let e = (x >> 23) & 0xff;
|
|
550
|
+
/* Using int is faster here */
|
|
551
|
+
|
|
552
|
+
/* If zero, or denormal, or exponent underflows too much for a denormal half, return signed zero. */
|
|
553
|
+
if (e < 103)
|
|
554
|
+
{
|
|
555
|
+
return bits;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
|
|
559
|
+
if (e > 142)
|
|
560
|
+
{
|
|
561
|
+
bits |= 0x7c00;
|
|
562
|
+
/* If exponent was 0xff and one mantissa bit was set, it means NaN,
|
|
563
|
+
* not Inf, so make sure we set one mantissa bit too. */
|
|
564
|
+
bits |= ((e === 255) ? 0 : 1) && (x & 0x007fffff);
|
|
565
|
+
return bits;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/* If exponent underflows but not too much, return a denormal */
|
|
569
|
+
if (e < 113)
|
|
570
|
+
{
|
|
571
|
+
m |= 0x0800;
|
|
572
|
+
/* Extra rounding may overflow and set mantissa to 0 and exponent to 1, which is OK. */
|
|
573
|
+
bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
|
|
574
|
+
return bits;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
bits |= ((e - 112) << 10) | (m >> 1);
|
|
578
|
+
/* Extra rounding. An overflow will set mantissa to 0 and increment the exponent, which is OK. */
|
|
579
|
+
bits += m & 1;
|
|
580
|
+
return bits;
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
}());
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Converts linear color to rgba/rgb color
|
|
587
|
+
* @param {Number} a
|
|
588
|
+
* @returns {Number}
|
|
589
|
+
*/
|
|
590
|
+
num.colorFromLinear = function (a)
|
|
591
|
+
{
|
|
592
|
+
return Math.min(Math.floor(a * 255), 255);
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Converts linear color to rgba/rgb color
|
|
597
|
+
* @param {Number} a
|
|
598
|
+
* @returns {Number}
|
|
599
|
+
*/
|
|
600
|
+
num.linearFromColor = function (a)
|
|
601
|
+
{
|
|
602
|
+
return a / 255;
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Converts linear color to hex string
|
|
607
|
+
* @param {Number} a
|
|
608
|
+
* @returns {String}
|
|
609
|
+
*/
|
|
610
|
+
num.hexFromLinear = function (a)
|
|
611
|
+
{
|
|
612
|
+
return num.hexFromColor(num.colorFromLinear(a));
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Converts rgb/rgba color to hex string
|
|
617
|
+
* @param {Number} a
|
|
618
|
+
* @returns {String}
|
|
619
|
+
*/
|
|
620
|
+
num.hexFromColor = function (a)
|
|
621
|
+
{
|
|
622
|
+
return (a | 1 << 8).toString(16).slice(1);
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Unwraps degrees
|
|
627
|
+
*
|
|
628
|
+
* @param {number} d
|
|
629
|
+
* @returns {number}
|
|
630
|
+
*/
|
|
631
|
+
num.unwrapDegrees = function (d)
|
|
632
|
+
{
|
|
633
|
+
d = d % 360;
|
|
634
|
+
if (d > 180) d -= 360;
|
|
635
|
+
if (d < -180) d += 360;
|
|
636
|
+
return d;
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Unwraps radians
|
|
641
|
+
*
|
|
642
|
+
* @param {number} r
|
|
643
|
+
* @returns {number}
|
|
644
|
+
*/
|
|
645
|
+
num.unwrapRadians = function (r)
|
|
646
|
+
{
|
|
647
|
+
r = r % num.TWO_PI;
|
|
648
|
+
if (r > num.PI) r -= num.TWO_PI;
|
|
649
|
+
if (r < -num.PI) r += num.TWO_PI;
|
|
650
|
+
return r;
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Converts srgb to linear colour
|
|
655
|
+
* @param {Number} a
|
|
656
|
+
* @returns {Number}
|
|
657
|
+
*/
|
|
658
|
+
num.linearFromSRGB = function (a)
|
|
659
|
+
{
|
|
660
|
+
return (a < 0.04045) ? a * 0.0773993808 : Math.pow(a * 0.9478672986 + 0.0521327014, 2.4);
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Converts linear colour to srgb
|
|
665
|
+
* @param {Number} a
|
|
666
|
+
* @returns {Number}
|
|
667
|
+
*/
|
|
668
|
+
num.srgbFromLinear = function (a)
|
|
669
|
+
{
|
|
670
|
+
return (a < 0.0031308)
|
|
671
|
+
? a * 12.92
|
|
672
|
+
: 1.055 * Math.pow(a, 1.0 / 2.4) - 0.055;
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
export const {
|
|
676
|
+
EPSILON,
|
|
677
|
+
RAD2DEG,
|
|
678
|
+
DEG2RAD,
|
|
679
|
+
TWO_PI,
|
|
680
|
+
PI,
|
|
681
|
+
INV_TWO_PI,
|
|
682
|
+
biCumulative,
|
|
683
|
+
ceil,
|
|
684
|
+
clamp,
|
|
685
|
+
decimalPlaces,
|
|
686
|
+
degrees,
|
|
687
|
+
degreesUnwrapped,
|
|
688
|
+
dwordToFloat,
|
|
689
|
+
equals,
|
|
690
|
+
exactEquals,
|
|
691
|
+
exponentialDecay,
|
|
692
|
+
fract,
|
|
693
|
+
fromHalfFloat,
|
|
694
|
+
floor,
|
|
695
|
+
getLongWordOrder,
|
|
696
|
+
greaterThan,
|
|
697
|
+
greaterThanEqual,
|
|
698
|
+
greaterThanExactEqual,
|
|
699
|
+
isEven,
|
|
700
|
+
isFloat,
|
|
701
|
+
isFinite,
|
|
702
|
+
isInt,
|
|
703
|
+
isNaN,
|
|
704
|
+
isOdd,
|
|
705
|
+
isPowerOfTwo,
|
|
706
|
+
lessThan,
|
|
707
|
+
lessThanEqual,
|
|
708
|
+
lessThanExactEqual,
|
|
709
|
+
log2,
|
|
710
|
+
max,
|
|
711
|
+
min,
|
|
712
|
+
nearestPowerOfTwo,
|
|
713
|
+
normalizeInt,
|
|
714
|
+
normalizeFloat,
|
|
715
|
+
radians,
|
|
716
|
+
radiansUnwrapped,
|
|
717
|
+
randomInt,
|
|
718
|
+
randomFloat,
|
|
719
|
+
round,
|
|
720
|
+
roundToZero,
|
|
721
|
+
step,
|
|
722
|
+
strictPositive,
|
|
723
|
+
strictNegative,
|
|
724
|
+
smoothStep,
|
|
725
|
+
smootherStep,
|
|
726
|
+
toHalfFloat,
|
|
727
|
+
colorFromLinear,
|
|
728
|
+
linearFromColor,
|
|
729
|
+
hexFromLinear,
|
|
730
|
+
hexFromColor,
|
|
731
|
+
unwrapDegrees,
|
|
732
|
+
unwrapRadians,
|
|
733
|
+
linearFromSRGB,
|
|
734
|
+
srgbFromLinear
|
|
735
|
+
} = num;
|