bg2e-js 2.3.11 → 2.3.13

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.
Files changed (148) hide show
  1. package/dist/bg2e-js.js +356 -326
  2. package/dist/bg2e-js.js.map +1 -1
  3. package/package.json +56 -56
  4. package/src/app/AppController.ts +39 -39
  5. package/src/app/Bg2KeyboardEvent.ts +54 -54
  6. package/src/app/Bg2MouseEvent.ts +82 -82
  7. package/src/app/Bg2TouchEvent.ts +18 -18
  8. package/src/app/Canvas.ts +108 -108
  9. package/src/app/EventBase.ts +10 -10
  10. package/src/app/MainLoop.ts +273 -273
  11. package/src/app/index.ts +24 -24
  12. package/src/base/Color.ts +134 -134
  13. package/src/base/Environment.ts +183 -183
  14. package/src/base/Light.ts +192 -192
  15. package/src/base/Material.ts +620 -620
  16. package/src/base/PolyList.ts +365 -365
  17. package/src/base/Texture.ts +620 -620
  18. package/src/base/index.ts +81 -81
  19. package/src/db/Bg2LoaderPlugin.ts +143 -143
  20. package/src/db/DBPluginApi.ts +48 -48
  21. package/src/db/Loader.ts +116 -116
  22. package/src/db/LoaderPlugin.ts +34 -34
  23. package/src/db/MtlParser.ts +7 -7
  24. package/src/db/ObjLoaderPlugin.ts +54 -54
  25. package/src/db/ObjParser.ts +252 -252
  26. package/src/db/ObjWriterPlugin.ts +18 -18
  27. package/src/db/VitscnjLoaderPlugin.ts +112 -112
  28. package/src/db/Writer.ts +52 -52
  29. package/src/db/WriterPlugin.ts +22 -22
  30. package/src/db/index.ts +44 -44
  31. package/src/debug/DebugRenderer.ts +173 -173
  32. package/src/debug/WebGLTextureViewer.ts +75 -75
  33. package/src/debug/index.ts +6 -6
  34. package/src/index.html +11 -11
  35. package/src/index.ts +33 -33
  36. package/src/manipulation/SelectionBuffer.ts +81 -81
  37. package/src/manipulation/SelectionHighlight.ts +105 -84
  38. package/src/manipulation/SelectionIdAssignVisitor.ts +96 -96
  39. package/src/manipulation/SelectionManager.ts +196 -188
  40. package/src/manipulation/SelectionMode.ts +6 -6
  41. package/src/math/Mat3.ts +259 -259
  42. package/src/math/Mat4.ts +710 -710
  43. package/src/math/MatrixStrategy.ts +25 -25
  44. package/src/math/Quat.ts +65 -65
  45. package/src/math/Vec.ts +753 -753
  46. package/src/math/constants.ts +46 -46
  47. package/src/math/functions.ts +103 -103
  48. package/src/math/index.ts +74 -74
  49. package/src/phsics/joint.ts +137 -137
  50. package/src/primitives/arrow.ts +57 -57
  51. package/src/primitives/cone.ts +138 -138
  52. package/src/primitives/cube.ts +60 -60
  53. package/src/primitives/cylinder.ts +216 -216
  54. package/src/primitives/index.ts +13 -13
  55. package/src/primitives/plane.ts +31 -31
  56. package/src/primitives/sphere.ts +809 -809
  57. package/src/react/useBg2e.ts +69 -69
  58. package/src/render/BRDFIntegrationMap.ts +4 -4
  59. package/src/render/Environment.ts +135 -135
  60. package/src/render/FrameBuffer.ts +35 -35
  61. package/src/render/MaterialRenderer.ts +34 -34
  62. package/src/render/Pipeline.ts +108 -108
  63. package/src/render/PolyListRenderer.ts +47 -47
  64. package/src/render/RenderBuffer.ts +197 -197
  65. package/src/render/RenderQueue.ts +198 -198
  66. package/src/render/RenderState.ts +116 -116
  67. package/src/render/Renderer.ts +248 -248
  68. package/src/render/SceneAppController.ts +250 -250
  69. package/src/render/SceneRenderer.ts +387 -387
  70. package/src/render/Shader.ts +32 -32
  71. package/src/render/ShadowRenderer.ts +176 -176
  72. package/src/render/SkyCube.ts +105 -105
  73. package/src/render/SkySphere.ts +117 -117
  74. package/src/render/TextureMergerRenderer.ts +70 -70
  75. package/src/render/TextureRenderer.ts +34 -34
  76. package/src/render/index.ts +67 -67
  77. package/src/render/webgl/FrameBuffer.ts +9 -9
  78. package/src/render/webgl/MaterialRenderer.ts +112 -112
  79. package/src/render/webgl/Pipeline.ts +88 -88
  80. package/src/render/webgl/PolyListRenderer.ts +260 -260
  81. package/src/render/webgl/RenderBuffer.ts +226 -226
  82. package/src/render/webgl/Renderer.ts +262 -262
  83. package/src/render/webgl/SceneRenderer.ts +67 -67
  84. package/src/render/webgl/ShaderProgram.ts +424 -424
  85. package/src/render/webgl/ShadowRenderer.ts +6 -6
  86. package/src/render/webgl/SkyCube.ts +15 -15
  87. package/src/render/webgl/SkySphere.ts +15 -15
  88. package/src/render/webgl/State.ts +152 -152
  89. package/src/render/webgl/TextureRenderer.ts +167 -167
  90. package/src/render/webgl/VertexBuffer.ts +137 -137
  91. package/src/render/webgl/index.ts +35 -35
  92. package/src/scene/Camera.ts +458 -458
  93. package/src/scene/Chain.ts +44 -44
  94. package/src/scene/ChainJoint.ts +58 -58
  95. package/src/scene/Component.ts +177 -177
  96. package/src/scene/ComponentMap.ts +106 -106
  97. package/src/scene/Drawable.ts +154 -154
  98. package/src/scene/EnvironmentComponent.ts +141 -141
  99. package/src/scene/FindNodeVisitor.ts +59 -59
  100. package/src/scene/LightComponent.ts +154 -154
  101. package/src/scene/MatrixState.ts +46 -46
  102. package/src/scene/Node.ts +328 -328
  103. package/src/scene/NodeVisitor.ts +15 -15
  104. package/src/scene/OrbitCameraController.ts +450 -450
  105. package/src/scene/SmoothOrbitCameraController.ts +99 -99
  106. package/src/scene/Transform.ts +73 -73
  107. package/src/scene/index.ts +60 -60
  108. package/src/shaders/BasicDiffuseColorShader.ts +111 -111
  109. package/src/shaders/BasicPBRLightShader.ts +276 -276
  110. package/src/shaders/DebugRenderShader.ts +97 -97
  111. package/src/shaders/DepthRenderShader.ts +127 -127
  112. package/src/shaders/IrradianceMapCubeShader.ts +115 -115
  113. package/src/shaders/PBRLightIBLShader.ts +486 -486
  114. package/src/shaders/PickSelectionShader.ts +101 -101
  115. package/src/shaders/PresentDebugFramebufferShader.ts +118 -118
  116. package/src/shaders/PresentTextureShader.ts +99 -99
  117. package/src/shaders/SelectionHighlightShader.ts +143 -127
  118. package/src/shaders/ShaderFunction.ts +318 -318
  119. package/src/shaders/SkyCubeShader.ts +93 -93
  120. package/src/shaders/SkySphereShader.ts +102 -102
  121. package/src/shaders/SpecularMapCubeShader.ts +164 -164
  122. package/src/shaders/TextureMergerShader.ts +171 -171
  123. package/src/shaders/index.ts +36 -36
  124. package/src/shaders/webgl/color_correction.glsl +47 -47
  125. package/src/shaders/webgl/constants.glsl +6 -6
  126. package/src/shaders/webgl/index.ts +70 -70
  127. package/src/shaders/webgl/normal_map.glsl +9 -9
  128. package/src/shaders/webgl/pbr.glsl +173 -173
  129. package/src/shaders/webgl/uniforms.glsl +91 -91
  130. package/src/shaders/webgl_shader_lib.ts +213 -213
  131. package/src/tools/BinaryResourceProvider.ts +14 -14
  132. package/src/tools/ImageResourceProvider.ts +66 -66
  133. package/src/tools/MaterialModifier.ts +446 -446
  134. package/src/tools/Resource.ts +203 -203
  135. package/src/tools/ResourceProvider.ts +69 -69
  136. package/src/tools/TextResourceProvider.ts +24 -24
  137. package/src/tools/TextureCache.ts +51 -51
  138. package/src/tools/TextureResourceDatabase.ts +100 -100
  139. package/src/tools/UserAgent.ts +362 -362
  140. package/src/tools/VideoResourceProvider.ts +50 -50
  141. package/src/tools/WriteStrategy.ts +22 -22
  142. package/src/tools/base64.ts +11 -11
  143. package/src/tools/crypto.ts +19 -19
  144. package/src/tools/endiantess.ts +13 -13
  145. package/src/tools/image.ts +18 -18
  146. package/src/tools/index.ts +41 -41
  147. package/src/tools/processType.ts +39 -39
  148. package/src/vite-env.d.ts +12 -12
package/src/math/Vec.ts CHANGED
@@ -1,753 +1,753 @@
1
- import { NumericArray } from "./constants";
2
- import { isZero, equals, lerp, clamp } from "./functions";
3
-
4
- const checkEqualLength = (v1: ArrayLike<number>, v2: ArrayLike<number>): void => {
5
- if (v1.length!=v2.length) throw new Error(`Invalid vector length in operation`);
6
- }
7
-
8
- export default class Vec extends NumericArray {
9
- constructor();
10
- constructor(v: ArrayLike<number>);
11
- constructor(v: ArrayLike<number>, z: number);
12
- constructor(v: ArrayLike<number>, z: number, w: number);
13
- constructor(x: number, y: number);
14
- constructor(x: number, y: number, z: number);
15
- constructor(x: number, y: number, z: number, w: number);
16
- constructor(...args: any[]) {
17
- switch (args.length) {
18
- case 0:
19
- super([0, 0]);
20
- break;
21
- case 1:
22
- if (args[0].length>1 && args[0].length<5)
23
- {
24
- super(args[0]);
25
- }
26
- break;
27
- case 2:
28
- if (args[0].length === 2 && typeof(args[1]) === "number"
29
- ) {
30
- super([ args[0][0], args[0][1], args[1]]);
31
- }
32
- else if (args[0].length === 3 &&
33
- typeof(args[1]) === "number"
34
- ) {
35
- super([ args[0][0], args[0][1], args[0][2], args[1]]);
36
- }
37
- else if (typeof(args[0]) === "number" &&
38
- typeof(args[1]) === "number"
39
- ) {
40
- super([args[0],args[1]]);
41
- }
42
- break;
43
- case 3:
44
- if (args[0].length === 2 &&
45
- typeof(args[1]) === "number" && typeof(args[2]) === "number"
46
- ) {
47
- super([ args[0][0], args[0][1], args[1], args[2]])
48
- }
49
- else if (typeof(args[0]) === "number" &&
50
- typeof(args[1]) === "number" &&
51
- typeof(args[2]) === "number"
52
- ) {
53
- super([args[0],args[1],args[2]]);
54
- }
55
- break;
56
- case 4:
57
- super([args[0],args[1],args[2],args[3]]);
58
- break;
59
- default:
60
- throw new Error(`Invalid parameters in Vec constructor`);
61
- }
62
- }
63
-
64
- normalize(): this {
65
- const m = Vec.Magnitude(this);
66
- switch (this.length) {
67
- case 4:
68
- this[3] = this[3] / m;
69
- case 3:
70
- this[2] = this[2] / m;
71
- case 2:
72
- this[1] = this[1] / m;
73
- this[0] = this[0] / m;
74
- break;
75
- default:
76
- throw new Error(`Invalid vector size: ${ this.length }`);
77
- }
78
- return this;
79
- }
80
-
81
- assign(src: ArrayLike<number>): void {
82
- checkEqualLength(this,src);
83
- switch (this.length) {
84
- case 4:
85
- this[3] = src[3];
86
- case 3:
87
- this[2] = src[2];
88
- case 2:
89
- this[1] = src[1];
90
- this[0] = src[0];
91
- break;
92
- default:
93
- throw new Error(`Invalid vector size: ${ this.length }`);
94
- }
95
- }
96
-
97
-
98
- setValue(x: number, y: number, z?: number | null, w?: number | null): void {
99
- if (this.length === 2) {
100
- this[0] = x;
101
- this[1] = y;
102
- }
103
- else if (this.length === 3 && z !== null && z !== undefined) {
104
- this[0] = x;
105
- this[1] = y;
106
- this[2] = z;
107
- }
108
- else if (this.length === 4 && z !== null && z !== undefined && w !== null && w !== undefined) {
109
- this[0] = x;
110
- this[1] = y;
111
- this[2] = z;
112
- this[3] = w;
113
- }
114
- else {
115
- throw new Error(`Invalid vector size: ${ this.length }. Trying to set x=${x}, y=${y}, z=${z}, w=${w}`);
116
- }
117
- }
118
-
119
- set(array: ArrayLike<number>, offset?: number): this {
120
- throw new Error("Vec.set() is not available. Use Vec.setValue() to set individual components or Vec.assign() to copy from another vector.");
121
- }
122
-
123
- scale(s: number): this {
124
- switch (this.length) {
125
- case 4:
126
- this[3] = this[3] * s;
127
- case 3:
128
- this[2] = this[2] * s;
129
- case 2:
130
- this[1] = this[1] * s;
131
- this[0] = this[0] * s;
132
- break;
133
- default:
134
- throw new Error(`Invalid vector size: ${ this.length }`);
135
- }
136
- return this;
137
- }
138
-
139
- get x(): number {
140
- return this[0];
141
- }
142
-
143
- get y(): number {
144
- return this[1];
145
- }
146
-
147
- get z(): number {
148
- return this[2];
149
- }
150
-
151
- get w(): number {
152
- return this[3];
153
- }
154
-
155
- set x(v: number) {
156
- this[0] = v;
157
- }
158
-
159
- set y(v: number) {
160
- this[1] = v;
161
- }
162
-
163
- set z(v: number) {
164
- this[2] = v;
165
- }
166
-
167
- set w(v: number) {
168
- this[3] = v;
169
- }
170
-
171
- get r(): number {
172
- return this[0];
173
- }
174
-
175
- get g(): number {
176
- return this[1];
177
- }
178
-
179
- get b(): number {
180
- return this[2];
181
- }
182
-
183
- get a(): number {
184
- return this[3];
185
- }
186
-
187
- set r(v: number) {
188
- this[0] = v;
189
- }
190
-
191
- set g(v: number) {
192
- this[1] = v;
193
- }
194
-
195
- set b(v: number) {
196
- this[2] = v;
197
- }
198
-
199
- set a(v: number) {
200
- this[3] = v;
201
- }
202
-
203
- get width(): number {
204
- switch (this.length) {
205
- case 2:
206
- return this[0];
207
- case 4:
208
- return this[2];
209
- default:
210
- throw new Error("Vec.width function used on non size or viewport vectors (two or four elements)");
211
- }
212
- }
213
-
214
- get height(): number {
215
- switch (this.length) {
216
- case 2:
217
- return this[1];
218
- case 4:
219
- return this[3];
220
- default:
221
- throw new Error("Vec.width function used on non size or viewport vectors (two or four elements)");
222
- }
223
- }
224
-
225
- set width(w: number) {
226
- this[0] = w;
227
- }
228
-
229
- set height(h: number) {
230
- this[1] = h;
231
- }
232
-
233
- get xy(): Vec {
234
- switch (this.length) {
235
- case 2:
236
- return new Vec(this);
237
- case 3:
238
- case 4:
239
- return new Vec(this[0], this[1]);
240
- default:
241
- throw new Error(`Invalid vector size: ${ this.length }`);
242
- }
243
- }
244
-
245
- get xz(): Vec {
246
- switch (this.length) {
247
- case 3:
248
- case 4:
249
- return new Vec(this[0], this[2]);
250
- case 2:
251
- default:
252
- throw new Error(`Invalid vector size: ${ this.length }`);
253
- }
254
- }
255
-
256
- get yz(): Vec {
257
- switch (this.length) {
258
- case 3:
259
- case 4:
260
- return new Vec(this[1], this[2]);
261
- case 2:
262
- default:
263
- throw new Error(`Invalid vector size: ${ this.length }`);
264
- }
265
- }
266
-
267
- set xy(v: Vec) {
268
- this[0] = v[0];
269
- this[1] = v[1];
270
- }
271
-
272
- set xz(v: Vec) {
273
- if (this.length<3) {
274
- throw new Error('Invalid vector size');
275
- }
276
- this[0] = v[0];
277
- this[2] = v[1];
278
- }
279
-
280
- set yz(v: Vec) {
281
- if (this.length<3) {
282
- throw new Error('Invalid vector size');
283
- }
284
- this[1] = v[0];
285
- this[2] = v[1];
286
- }
287
-
288
- get xyz(): Vec {
289
- if (this.length < 3) {
290
- throw new Error(`Invalid vector size: ${ this.length }`);
291
- }
292
- return new Vec(this[0], this[1], this[2]);
293
- }
294
-
295
- set xyz(v: Vec) {
296
- if (v.length<3 || this.length<3) {
297
- throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
298
- }
299
- this[0] = v[0];
300
- this[1] = v[1];
301
- this[2] = v[2];
302
- }
303
-
304
- // Copy operator
305
- get xyzw(): Vec {
306
- if (this.length < 4) {
307
- throw new Error(`Invalid vector size: ${ this.length }, 4 required`);
308
- }
309
- return new Vec(this[0], this[1], this[2], this[3]);
310
- }
311
-
312
- // Assign operator
313
- set xyzw(v: Vec) {
314
- if (this.length < 4 || v.length<4) {
315
- throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
316
- }
317
- this[0] = v[0];
318
- this[1] = v[1];
319
- this[2] = v[2];
320
- this[3] = v[3];
321
- }
322
-
323
- get rgb(): Vec {
324
- if (this.length < 3) {
325
- throw new Error(`Invalid vector size: ${this.length}, but at least 3 required`);
326
- }
327
- return new Vec(this[0],this[1],this[2]);
328
- }
329
-
330
- set rgb(v: Vec) {
331
- if (v.length<3 || this.length<3) {
332
- throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
333
- }
334
- this[0] = v[0];
335
- this[1] = v[1];
336
- this[2] = v[2];
337
- }
338
-
339
- get rg(): Vec {
340
- if (this.length<3 || this.length<3) {
341
- throw new Error(`Invalid vector size to set: l;${ this.length }, r:${this.length}`);
342
- }
343
- return new Vec(this[0], this[1]);
344
- }
345
-
346
- get gb(): Vec {
347
- if (this.length<3 || this.length<3) {
348
- throw new Error(`Invalid vector size to set: l;${ this.length }, r:${this.length}`);
349
- }
350
- return new Vec(this[1], this[2]);
351
- }
352
-
353
- get rb(): Vec {
354
- if (this.length<3 || this.length<3) {
355
- throw new Error(`Invalid vector size to set: l;${ this.length }, r:${this.length}`);
356
- }
357
- return new Vec(this[0], this[2]);
358
- }
359
-
360
- get hexColor(): string {
361
- const r = Math.round(this.r * 255);
362
- const g = Math.round(this.g * 255);
363
- const b = Math.round(this.b * 255);
364
- const hex = (color: number): string => color.toString(16).toUpperCase();
365
- return `#${ hex(r) }${ hex(g) }${ hex(b) }`;
366
- }
367
-
368
- get cssColor(): string | undefined {
369
- return `rgb(${ Math.round(this.r * 255) } ${ Math.round(this.g * 255) } ${ Math.round(this.b * 255) }${ this.length>=4 ? `, ${ this.a }` : ''})`;
370
- }
371
-
372
- get aspectRatio(): number {
373
- return this.width / this.height;
374
- }
375
-
376
- // Tuple/array setters
377
- setXY(v: [number, number]) {
378
- this[0] = v[0];
379
- this[1] = v[1];
380
- }
381
-
382
- setXZ(v: [number, number]) {
383
- if (this.length<3) {
384
- throw new Error('Invalid vector size');
385
- }
386
- this[0] = v[0];
387
- this[2] = v[1];
388
- }
389
-
390
- setYZ(v: [number, number]) {
391
- if (this.length<3) {
392
- throw new Error('Invalid vector size');
393
- }
394
- this[1] = v[0];
395
- this[2] = v[1];
396
- }
397
-
398
- setXYZ(v: [number, number, number]) {
399
- if (v.length<3 || this.length<3) {
400
- throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
401
- }
402
- this[0] = v[0];
403
- this[1] = v[1];
404
- this[2] = v[2];
405
- }
406
-
407
- setXYZW(v: [number, number, number, number]) {
408
- if (this.length < 4 || v.length<4) {
409
- throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
410
- }
411
- this[0] = v[0];
412
- this[1] = v[1];
413
- this[2] = v[2];
414
- this[3] = v[3];
415
- }
416
-
417
- setRGB(v: [number, number, number]) {
418
- if (v.length<3 || this.length<3) {
419
- throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
420
- }
421
- this[0] = v[0];
422
- this[1] = v[1];
423
- this[2] = v[2];
424
- }
425
-
426
- toString(): string {
427
- switch (this.length) {
428
- case 2:
429
- return `[${this[0]}, ${this[1]}]`;
430
- case 3:
431
- return `[${this[0]}, ${this[1]}, ${this[2]}]`;
432
- case 4:
433
- return `[${this[0]}, ${this[1]}, ${this[2]}, ${this[3]}]`;
434
- }
435
- return "[]";
436
- }
437
-
438
- toArray(): number[] {
439
- return Array.from(this);
440
- }
441
-
442
- static CheckEqualLength(v1: ArrayLike<number>, v2: ArrayLike<number>): void {
443
- checkEqualLength(v1,v2);
444
- }
445
-
446
- static Max(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec {
447
- checkEqualLength(v1,v2);
448
- switch (v1.length) {
449
- case 2:
450
- return new Vec([
451
- v1[0]>v2[0] ? v1[0] : v2[0],
452
- v1[1]>v2[1] ? v1[1] : v2[1]
453
- ]);
454
- case 3:
455
- return new Vec([
456
- v1[0]>v2[0] ? v1[0] : v2[0],
457
- v1[1]>v2[1] ? v1[1] : v2[1],
458
- v1[2]>v2[2] ? v1[2] : v2[2]
459
- ]);
460
- case 4:
461
- return new Vec([
462
- v1[0]>v2[0] ? v1[0] : v2[0],
463
- v1[1]>v2[1] ? v1[1] : v2[1],
464
- v1[2]>v2[2] ? v1[2] : v2[2],
465
- v1[3]>v2[3] ? v1[3] : v2[3]
466
- ]);
467
- default:
468
- throw new Error(`Invalid vector size: ${ v1.length }`);
469
- }
470
- }
471
-
472
- static Min(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec {
473
- checkEqualLength(v1,v2);
474
- switch (v1.length) {
475
- case 2:
476
- return new Vec([
477
- v1[0]<v2[0] ? v1[0] : v2[0],
478
- v1[1]<v2[1] ? v1[1] : v2[1]
479
- ]);
480
- case 3:
481
- return new Vec([
482
- v1[0]<v2[0] ? v1[0] : v2[0],
483
- v1[1]<v2[1] ? v1[1] : v2[1],
484
- v1[2]<v2[2] ? v1[2] : v2[2]
485
- ]);
486
- case 4:
487
- return new Vec([
488
- v1[0]<v2[0] ? v1[0] : v2[0],
489
- v1[1]<v2[1] ? v1[1] : v2[1],
490
- v1[2]<v2[2] ? v1[2] : v2[2],
491
- v1[3]<v2[3] ? v1[3] : v2[3]
492
- ]);
493
- default:
494
- throw new Error(`Invalid vector size: ${ v1.length }`);
495
- }
496
- }
497
-
498
- static Add(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec {
499
- checkEqualLength(v1,v2);
500
- switch (v1.length) {
501
- case 2:
502
- return new Vec([
503
- v1[0] + v2[0],
504
- v1[1] + v2[1]
505
- ]);
506
- case 3:
507
- return new Vec([
508
- v1[0] + v2[0],
509
- v1[1] + v2[1],
510
- v1[2] + v2[2]
511
- ]);
512
- case 4:
513
- return new Vec([
514
- v1[0] + v2[0],
515
- v1[1] + v2[1],
516
- v1[2] + v2[2],
517
- v1[3] + v2[3]
518
- ]);
519
- default:
520
- throw new Error(`Invalid vector size: ${ v1.length }`);
521
- }
522
- }
523
-
524
- static Sub(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec {
525
- checkEqualLength(v1,v2);
526
- switch (v1.length) {
527
- case 2:
528
- return new Vec([
529
- v1[0] - v2[0],
530
- v1[1] - v2[1]
531
- ]);
532
- case 3:
533
- return new Vec([
534
- v1[0] - v2[0],
535
- v1[1] - v2[1],
536
- v1[2] - v2[2]
537
- ]);
538
- case 4:
539
- return new Vec([
540
- v1[0] - v2[0],
541
- v1[1] - v2[1],
542
- v1[2] - v2[2],
543
- v1[3] - v2[3]
544
- ]);
545
- default:
546
- throw new Error(`Invalid vector size: ${ v1.length }`);
547
- }
548
- }
549
-
550
- static Magnitude(v: ArrayLike<number>): number {
551
- switch (v.length) {
552
- case 2:
553
- return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
554
- case 3:
555
- return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
556
- case 4:
557
- return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
558
- default:
559
- throw new Error(`Invalid vector size: ${ v.length }`);
560
- }
561
- }
562
-
563
- static Distance(v1: ArrayLike<number>, v2: ArrayLike<number>): number {
564
- checkEqualLength(v1,v2);
565
- return Vec.Magnitude(Vec.Sub(v1,v2));
566
- }
567
-
568
- static Dot(v1: ArrayLike<number>, v2: ArrayLike<number>): number {
569
- checkEqualLength(v1,v2);
570
- switch (v1.length) {
571
- case 2:
572
- return v1[0] * v2[0] + v1[1] * v2[1];
573
- case 3:
574
- return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
575
- case 4:
576
- return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3];
577
- default:
578
- throw new Error(`Invalid vector size: ${ v1.length }`);
579
- }
580
- }
581
-
582
- static Cross(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec | number {
583
- checkEqualLength(v1, v2);
584
- switch (v1.length) {
585
- case 2:
586
- return v1[0] * v2[1] - v1[1] * v2[0];
587
- case 3:
588
- return new Vec([
589
- v1[1] * v2[2] - v1[2] * v2[1],
590
- v1[2] * v2[0] - v1[0] * v2[2],
591
- v1[0] * v2[1] - v1[1] * v2[0],
592
- ]);
593
- default:
594
- throw new Error(`Invalid vector size for cross product: ${v1.length}`);
595
- }
596
- }
597
-
598
- static Normalized(v: ArrayLike<number>): Vec {
599
- const m = Vec.Magnitude(v);
600
- switch (v.length) {
601
- case 2:
602
- return new Vec([ v[0] / m, v[1] / m ]);
603
- case 3:
604
- return new Vec([ v[0] / m, v[1] / m, v[2] / m ]);
605
- case 4:
606
- return new Vec([ v[0] / m, v[1] / m, v[2] / m, v[3] / m ])
607
- default:
608
- throw new Error(`Invalid vector size: ${ v.length }`);
609
- }
610
- }
611
-
612
- static Mult(v: ArrayLike<number>, s: number): Vec {
613
- switch (v.length) {
614
- case 2:
615
- return new Vec([ v[0] * s, v[1] * s ]);
616
- case 3:
617
- return new Vec([ v[0] * s, v[1] * s, v[2] * s ]);
618
- case 4:
619
- return new Vec([ v[0] * s, v[1] * s, v[2] * s, v[3] * s ]);
620
- default:
621
- throw new Error(`Invalid vector size: ${ v.length }`);
622
- }
623
- }
624
-
625
- static Div(v: ArrayLike<number>, s: number): Vec {
626
- switch (v.length) {
627
- case 2:
628
- return new Vec([ v[0] / s, v[1] / s ]);
629
- case 3:
630
- return new Vec([ v[0] / s, v[1] / s, v[2] / s ]);
631
- case 4:
632
- return new Vec([ v[0] / s, v[1] / s, v[2] / s, v[3] / s ]);
633
- default:
634
- throw new Error(`Invalid vector size: ${ v.length }`);
635
- }
636
- }
637
-
638
- static Equals(v1: ArrayLike<number>, v2: ArrayLike<number>): boolean {
639
- if (v1.length != v2.length) {
640
- return false;
641
- }
642
- else {
643
- switch (v1.length) {
644
- case 2:
645
- return equals(v1[0], v2[0]) &&
646
- equals(v1[1], v2[1]);
647
- case 3:
648
- return equals(v1[0], v2[0]) &&
649
- equals(v1[1], v2[1]) &&
650
- equals(v1[2], v2[2]);
651
- case 4:
652
- return equals(v1[0], v2[0]) &&
653
- equals(v1[1], v2[1]) &&
654
- equals(v1[2], v2[2]) &&
655
- equals(v1[3], v2[3]);
656
- default:
657
- throw new Error(`Invalid vector size: ${ v1.length }`);
658
- }
659
- }
660
- }
661
-
662
- static IsZero(v: ArrayLike<number>): boolean {
663
- switch (v.length) {
664
- case 2:
665
- return isZero(v[0]) || isZero(v[1]);
666
- case 3:
667
- return isZero(v[0]) || isZero(v[1]) || isZero(v[2]);
668
- case 4:
669
- return isZero(v[0]) || isZero(v[1]) || isZero(v[2]) || isZero(v[3]);
670
- default:
671
- throw new Error(`Invalid vector size: ${ v.length }`);
672
- }
673
- }
674
-
675
- static IsNaN(v: ArrayLike<number>): boolean {
676
- switch (v.length) {
677
- case 2:
678
- return isNaN(v[0]) || isNaN(v[1]);
679
- case 3:
680
- return isNaN(v[0]) || isNaN(v[1]) || isNaN(v[2]);
681
- case 4:
682
- return isNaN(v[0]) || isNaN(v[1]) || isNaN(v[2]) || isNaN(v[3]);
683
- default:
684
- throw new Error(`Invalid vector size: ${ v.length }`);
685
- }
686
- }
687
-
688
- static Lerp(u: ArrayLike<number>, v: ArrayLike<number>, d: number): Vec {
689
- if (u.length != v.length) {
690
- throw new Error(`Different vector sizes calculating linear interpolation`);
691
- }
692
- switch (u.length) {
693
- case 2:
694
- return new Vec(
695
- lerp(u[0], v[0], d),
696
- lerp(u[1], v[1], d)
697
- );
698
- case 3:
699
- return new Vec(
700
- lerp(u[0], v[0], d),
701
- lerp(u[1], v[1], d),
702
- lerp(u[2], v[2], d)
703
- );
704
- case 4:
705
- return new Vec(
706
- lerp(u[0], v[0], d),
707
- lerp(u[1], v[1], d),
708
- lerp(u[2], v[2], d),
709
- lerp(u[3], v[3], d)
710
- );
711
- default:
712
- throw new Error(`Invalid vector size: ${ u.length }`);
713
- }
714
- }
715
-
716
- static Clamp(v: ArrayLike<number>, min: ArrayLike<number>, max: ArrayLike<number>): Vec {
717
- switch (v.length) {
718
- case 2:
719
- return new Vec(
720
- clamp(v[0], min[0], max[0]),
721
- clamp(v[1], min[1], max[1])
722
- );
723
- case 3:
724
- return new Vec(
725
- clamp(v[0], min[0], max[0]),
726
- clamp(v[1], min[1], max[1]),
727
- clamp(v[2], min[2], max[2])
728
- );
729
- case 4:
730
- return new Vec(
731
- clamp(v[0], min[0], max[0]),
732
- clamp(v[1], min[1], max[1]),
733
- clamp(v[2], min[2], max[2]),
734
- clamp(v[3], min[3], max[3])
735
- );
736
- default:
737
- throw new Error(`Invalid vector size: ${ v.length }`);
738
- }
739
- }
740
-
741
- /////// Constructors
742
- static Vec2(): Vec {
743
- return new Vec(0,0);
744
- }
745
-
746
- static Vec3(): Vec {
747
- return new Vec(0,0,0);
748
- }
749
-
750
- static Vec4(): Vec {
751
- return new Vec(0,0,0,0);
752
- }
753
- }
1
+ import { NumericArray } from "./constants";
2
+ import { isZero, equals, lerp, clamp } from "./functions";
3
+
4
+ const checkEqualLength = (v1: ArrayLike<number>, v2: ArrayLike<number>): void => {
5
+ if (v1.length!=v2.length) throw new Error(`Invalid vector length in operation`);
6
+ }
7
+
8
+ export default class Vec extends NumericArray {
9
+ constructor();
10
+ constructor(v: ArrayLike<number>);
11
+ constructor(v: ArrayLike<number>, z: number);
12
+ constructor(v: ArrayLike<number>, z: number, w: number);
13
+ constructor(x: number, y: number);
14
+ constructor(x: number, y: number, z: number);
15
+ constructor(x: number, y: number, z: number, w: number);
16
+ constructor(...args: any[]) {
17
+ switch (args.length) {
18
+ case 0:
19
+ super([0, 0]);
20
+ break;
21
+ case 1:
22
+ if (args[0].length>1 && args[0].length<5)
23
+ {
24
+ super(args[0]);
25
+ }
26
+ break;
27
+ case 2:
28
+ if (args[0].length === 2 && typeof(args[1]) === "number"
29
+ ) {
30
+ super([ args[0][0], args[0][1], args[1]]);
31
+ }
32
+ else if (args[0].length === 3 &&
33
+ typeof(args[1]) === "number"
34
+ ) {
35
+ super([ args[0][0], args[0][1], args[0][2], args[1]]);
36
+ }
37
+ else if (typeof(args[0]) === "number" &&
38
+ typeof(args[1]) === "number"
39
+ ) {
40
+ super([args[0],args[1]]);
41
+ }
42
+ break;
43
+ case 3:
44
+ if (args[0].length === 2 &&
45
+ typeof(args[1]) === "number" && typeof(args[2]) === "number"
46
+ ) {
47
+ super([ args[0][0], args[0][1], args[1], args[2]])
48
+ }
49
+ else if (typeof(args[0]) === "number" &&
50
+ typeof(args[1]) === "number" &&
51
+ typeof(args[2]) === "number"
52
+ ) {
53
+ super([args[0],args[1],args[2]]);
54
+ }
55
+ break;
56
+ case 4:
57
+ super([args[0],args[1],args[2],args[3]]);
58
+ break;
59
+ default:
60
+ throw new Error(`Invalid parameters in Vec constructor`);
61
+ }
62
+ }
63
+
64
+ normalize(): this {
65
+ const m = Vec.Magnitude(this);
66
+ switch (this.length) {
67
+ case 4:
68
+ this[3] = this[3] / m;
69
+ case 3:
70
+ this[2] = this[2] / m;
71
+ case 2:
72
+ this[1] = this[1] / m;
73
+ this[0] = this[0] / m;
74
+ break;
75
+ default:
76
+ throw new Error(`Invalid vector size: ${ this.length }`);
77
+ }
78
+ return this;
79
+ }
80
+
81
+ assign(src: ArrayLike<number>): void {
82
+ checkEqualLength(this,src);
83
+ switch (this.length) {
84
+ case 4:
85
+ this[3] = src[3];
86
+ case 3:
87
+ this[2] = src[2];
88
+ case 2:
89
+ this[1] = src[1];
90
+ this[0] = src[0];
91
+ break;
92
+ default:
93
+ throw new Error(`Invalid vector size: ${ this.length }`);
94
+ }
95
+ }
96
+
97
+
98
+ setValue(x: number, y: number, z?: number | null, w?: number | null): void {
99
+ if (this.length === 2) {
100
+ this[0] = x;
101
+ this[1] = y;
102
+ }
103
+ else if (this.length === 3 && z !== null && z !== undefined) {
104
+ this[0] = x;
105
+ this[1] = y;
106
+ this[2] = z;
107
+ }
108
+ else if (this.length === 4 && z !== null && z !== undefined && w !== null && w !== undefined) {
109
+ this[0] = x;
110
+ this[1] = y;
111
+ this[2] = z;
112
+ this[3] = w;
113
+ }
114
+ else {
115
+ throw new Error(`Invalid vector size: ${ this.length }. Trying to set x=${x}, y=${y}, z=${z}, w=${w}`);
116
+ }
117
+ }
118
+
119
+ set(array: ArrayLike<number>, offset?: number): this {
120
+ throw new Error("Vec.set() is not available. Use Vec.setValue() to set individual components or Vec.assign() to copy from another vector.");
121
+ }
122
+
123
+ scale(s: number): this {
124
+ switch (this.length) {
125
+ case 4:
126
+ this[3] = this[3] * s;
127
+ case 3:
128
+ this[2] = this[2] * s;
129
+ case 2:
130
+ this[1] = this[1] * s;
131
+ this[0] = this[0] * s;
132
+ break;
133
+ default:
134
+ throw new Error(`Invalid vector size: ${ this.length }`);
135
+ }
136
+ return this;
137
+ }
138
+
139
+ get x(): number {
140
+ return this[0];
141
+ }
142
+
143
+ get y(): number {
144
+ return this[1];
145
+ }
146
+
147
+ get z(): number {
148
+ return this[2];
149
+ }
150
+
151
+ get w(): number {
152
+ return this[3];
153
+ }
154
+
155
+ set x(v: number) {
156
+ this[0] = v;
157
+ }
158
+
159
+ set y(v: number) {
160
+ this[1] = v;
161
+ }
162
+
163
+ set z(v: number) {
164
+ this[2] = v;
165
+ }
166
+
167
+ set w(v: number) {
168
+ this[3] = v;
169
+ }
170
+
171
+ get r(): number {
172
+ return this[0];
173
+ }
174
+
175
+ get g(): number {
176
+ return this[1];
177
+ }
178
+
179
+ get b(): number {
180
+ return this[2];
181
+ }
182
+
183
+ get a(): number {
184
+ return this[3];
185
+ }
186
+
187
+ set r(v: number) {
188
+ this[0] = v;
189
+ }
190
+
191
+ set g(v: number) {
192
+ this[1] = v;
193
+ }
194
+
195
+ set b(v: number) {
196
+ this[2] = v;
197
+ }
198
+
199
+ set a(v: number) {
200
+ this[3] = v;
201
+ }
202
+
203
+ get width(): number {
204
+ switch (this.length) {
205
+ case 2:
206
+ return this[0];
207
+ case 4:
208
+ return this[2];
209
+ default:
210
+ throw new Error("Vec.width function used on non size or viewport vectors (two or four elements)");
211
+ }
212
+ }
213
+
214
+ get height(): number {
215
+ switch (this.length) {
216
+ case 2:
217
+ return this[1];
218
+ case 4:
219
+ return this[3];
220
+ default:
221
+ throw new Error("Vec.width function used on non size or viewport vectors (two or four elements)");
222
+ }
223
+ }
224
+
225
+ set width(w: number) {
226
+ this[0] = w;
227
+ }
228
+
229
+ set height(h: number) {
230
+ this[1] = h;
231
+ }
232
+
233
+ get xy(): Vec {
234
+ switch (this.length) {
235
+ case 2:
236
+ return new Vec(this);
237
+ case 3:
238
+ case 4:
239
+ return new Vec(this[0], this[1]);
240
+ default:
241
+ throw new Error(`Invalid vector size: ${ this.length }`);
242
+ }
243
+ }
244
+
245
+ get xz(): Vec {
246
+ switch (this.length) {
247
+ case 3:
248
+ case 4:
249
+ return new Vec(this[0], this[2]);
250
+ case 2:
251
+ default:
252
+ throw new Error(`Invalid vector size: ${ this.length }`);
253
+ }
254
+ }
255
+
256
+ get yz(): Vec {
257
+ switch (this.length) {
258
+ case 3:
259
+ case 4:
260
+ return new Vec(this[1], this[2]);
261
+ case 2:
262
+ default:
263
+ throw new Error(`Invalid vector size: ${ this.length }`);
264
+ }
265
+ }
266
+
267
+ set xy(v: Vec) {
268
+ this[0] = v[0];
269
+ this[1] = v[1];
270
+ }
271
+
272
+ set xz(v: Vec) {
273
+ if (this.length<3) {
274
+ throw new Error('Invalid vector size');
275
+ }
276
+ this[0] = v[0];
277
+ this[2] = v[1];
278
+ }
279
+
280
+ set yz(v: Vec) {
281
+ if (this.length<3) {
282
+ throw new Error('Invalid vector size');
283
+ }
284
+ this[1] = v[0];
285
+ this[2] = v[1];
286
+ }
287
+
288
+ get xyz(): Vec {
289
+ if (this.length < 3) {
290
+ throw new Error(`Invalid vector size: ${ this.length }`);
291
+ }
292
+ return new Vec(this[0], this[1], this[2]);
293
+ }
294
+
295
+ set xyz(v: Vec) {
296
+ if (v.length<3 || this.length<3) {
297
+ throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
298
+ }
299
+ this[0] = v[0];
300
+ this[1] = v[1];
301
+ this[2] = v[2];
302
+ }
303
+
304
+ // Copy operator
305
+ get xyzw(): Vec {
306
+ if (this.length < 4) {
307
+ throw new Error(`Invalid vector size: ${ this.length }, 4 required`);
308
+ }
309
+ return new Vec(this[0], this[1], this[2], this[3]);
310
+ }
311
+
312
+ // Assign operator
313
+ set xyzw(v: Vec) {
314
+ if (this.length < 4 || v.length<4) {
315
+ throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
316
+ }
317
+ this[0] = v[0];
318
+ this[1] = v[1];
319
+ this[2] = v[2];
320
+ this[3] = v[3];
321
+ }
322
+
323
+ get rgb(): Vec {
324
+ if (this.length < 3) {
325
+ throw new Error(`Invalid vector size: ${this.length}, but at least 3 required`);
326
+ }
327
+ return new Vec(this[0],this[1],this[2]);
328
+ }
329
+
330
+ set rgb(v: Vec) {
331
+ if (v.length<3 || this.length<3) {
332
+ throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
333
+ }
334
+ this[0] = v[0];
335
+ this[1] = v[1];
336
+ this[2] = v[2];
337
+ }
338
+
339
+ get rg(): Vec {
340
+ if (this.length<3 || this.length<3) {
341
+ throw new Error(`Invalid vector size to set: l;${ this.length }, r:${this.length}`);
342
+ }
343
+ return new Vec(this[0], this[1]);
344
+ }
345
+
346
+ get gb(): Vec {
347
+ if (this.length<3 || this.length<3) {
348
+ throw new Error(`Invalid vector size to set: l;${ this.length }, r:${this.length}`);
349
+ }
350
+ return new Vec(this[1], this[2]);
351
+ }
352
+
353
+ get rb(): Vec {
354
+ if (this.length<3 || this.length<3) {
355
+ throw new Error(`Invalid vector size to set: l;${ this.length }, r:${this.length}`);
356
+ }
357
+ return new Vec(this[0], this[2]);
358
+ }
359
+
360
+ get hexColor(): string {
361
+ const r = Math.round(this.r * 255);
362
+ const g = Math.round(this.g * 255);
363
+ const b = Math.round(this.b * 255);
364
+ const hex = (color: number): string => color.toString(16).toUpperCase();
365
+ return `#${ hex(r) }${ hex(g) }${ hex(b) }`;
366
+ }
367
+
368
+ get cssColor(): string | undefined {
369
+ return `rgb(${ Math.round(this.r * 255) } ${ Math.round(this.g * 255) } ${ Math.round(this.b * 255) }${ this.length>=4 ? `, ${ this.a }` : ''})`;
370
+ }
371
+
372
+ get aspectRatio(): number {
373
+ return this.width / this.height;
374
+ }
375
+
376
+ // Tuple/array setters
377
+ setXY(v: [number, number]) {
378
+ this[0] = v[0];
379
+ this[1] = v[1];
380
+ }
381
+
382
+ setXZ(v: [number, number]) {
383
+ if (this.length<3) {
384
+ throw new Error('Invalid vector size');
385
+ }
386
+ this[0] = v[0];
387
+ this[2] = v[1];
388
+ }
389
+
390
+ setYZ(v: [number, number]) {
391
+ if (this.length<3) {
392
+ throw new Error('Invalid vector size');
393
+ }
394
+ this[1] = v[0];
395
+ this[2] = v[1];
396
+ }
397
+
398
+ setXYZ(v: [number, number, number]) {
399
+ if (v.length<3 || this.length<3) {
400
+ throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
401
+ }
402
+ this[0] = v[0];
403
+ this[1] = v[1];
404
+ this[2] = v[2];
405
+ }
406
+
407
+ setXYZW(v: [number, number, number, number]) {
408
+ if (this.length < 4 || v.length<4) {
409
+ throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
410
+ }
411
+ this[0] = v[0];
412
+ this[1] = v[1];
413
+ this[2] = v[2];
414
+ this[3] = v[3];
415
+ }
416
+
417
+ setRGB(v: [number, number, number]) {
418
+ if (v.length<3 || this.length<3) {
419
+ throw new Error(`Invalid vector size to set: l;${ this.length }, r:${v.length}`);
420
+ }
421
+ this[0] = v[0];
422
+ this[1] = v[1];
423
+ this[2] = v[2];
424
+ }
425
+
426
+ toString(): string {
427
+ switch (this.length) {
428
+ case 2:
429
+ return `[${this[0]}, ${this[1]}]`;
430
+ case 3:
431
+ return `[${this[0]}, ${this[1]}, ${this[2]}]`;
432
+ case 4:
433
+ return `[${this[0]}, ${this[1]}, ${this[2]}, ${this[3]}]`;
434
+ }
435
+ return "[]";
436
+ }
437
+
438
+ toArray(): number[] {
439
+ return Array.from(this);
440
+ }
441
+
442
+ static CheckEqualLength(v1: ArrayLike<number>, v2: ArrayLike<number>): void {
443
+ checkEqualLength(v1,v2);
444
+ }
445
+
446
+ static Max(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec {
447
+ checkEqualLength(v1,v2);
448
+ switch (v1.length) {
449
+ case 2:
450
+ return new Vec([
451
+ v1[0]>v2[0] ? v1[0] : v2[0],
452
+ v1[1]>v2[1] ? v1[1] : v2[1]
453
+ ]);
454
+ case 3:
455
+ return new Vec([
456
+ v1[0]>v2[0] ? v1[0] : v2[0],
457
+ v1[1]>v2[1] ? v1[1] : v2[1],
458
+ v1[2]>v2[2] ? v1[2] : v2[2]
459
+ ]);
460
+ case 4:
461
+ return new Vec([
462
+ v1[0]>v2[0] ? v1[0] : v2[0],
463
+ v1[1]>v2[1] ? v1[1] : v2[1],
464
+ v1[2]>v2[2] ? v1[2] : v2[2],
465
+ v1[3]>v2[3] ? v1[3] : v2[3]
466
+ ]);
467
+ default:
468
+ throw new Error(`Invalid vector size: ${ v1.length }`);
469
+ }
470
+ }
471
+
472
+ static Min(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec {
473
+ checkEqualLength(v1,v2);
474
+ switch (v1.length) {
475
+ case 2:
476
+ return new Vec([
477
+ v1[0]<v2[0] ? v1[0] : v2[0],
478
+ v1[1]<v2[1] ? v1[1] : v2[1]
479
+ ]);
480
+ case 3:
481
+ return new Vec([
482
+ v1[0]<v2[0] ? v1[0] : v2[0],
483
+ v1[1]<v2[1] ? v1[1] : v2[1],
484
+ v1[2]<v2[2] ? v1[2] : v2[2]
485
+ ]);
486
+ case 4:
487
+ return new Vec([
488
+ v1[0]<v2[0] ? v1[0] : v2[0],
489
+ v1[1]<v2[1] ? v1[1] : v2[1],
490
+ v1[2]<v2[2] ? v1[2] : v2[2],
491
+ v1[3]<v2[3] ? v1[3] : v2[3]
492
+ ]);
493
+ default:
494
+ throw new Error(`Invalid vector size: ${ v1.length }`);
495
+ }
496
+ }
497
+
498
+ static Add(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec {
499
+ checkEqualLength(v1,v2);
500
+ switch (v1.length) {
501
+ case 2:
502
+ return new Vec([
503
+ v1[0] + v2[0],
504
+ v1[1] + v2[1]
505
+ ]);
506
+ case 3:
507
+ return new Vec([
508
+ v1[0] + v2[0],
509
+ v1[1] + v2[1],
510
+ v1[2] + v2[2]
511
+ ]);
512
+ case 4:
513
+ return new Vec([
514
+ v1[0] + v2[0],
515
+ v1[1] + v2[1],
516
+ v1[2] + v2[2],
517
+ v1[3] + v2[3]
518
+ ]);
519
+ default:
520
+ throw new Error(`Invalid vector size: ${ v1.length }`);
521
+ }
522
+ }
523
+
524
+ static Sub(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec {
525
+ checkEqualLength(v1,v2);
526
+ switch (v1.length) {
527
+ case 2:
528
+ return new Vec([
529
+ v1[0] - v2[0],
530
+ v1[1] - v2[1]
531
+ ]);
532
+ case 3:
533
+ return new Vec([
534
+ v1[0] - v2[0],
535
+ v1[1] - v2[1],
536
+ v1[2] - v2[2]
537
+ ]);
538
+ case 4:
539
+ return new Vec([
540
+ v1[0] - v2[0],
541
+ v1[1] - v2[1],
542
+ v1[2] - v2[2],
543
+ v1[3] - v2[3]
544
+ ]);
545
+ default:
546
+ throw new Error(`Invalid vector size: ${ v1.length }`);
547
+ }
548
+ }
549
+
550
+ static Magnitude(v: ArrayLike<number>): number {
551
+ switch (v.length) {
552
+ case 2:
553
+ return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
554
+ case 3:
555
+ return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
556
+ case 4:
557
+ return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
558
+ default:
559
+ throw new Error(`Invalid vector size: ${ v.length }`);
560
+ }
561
+ }
562
+
563
+ static Distance(v1: ArrayLike<number>, v2: ArrayLike<number>): number {
564
+ checkEqualLength(v1,v2);
565
+ return Vec.Magnitude(Vec.Sub(v1,v2));
566
+ }
567
+
568
+ static Dot(v1: ArrayLike<number>, v2: ArrayLike<number>): number {
569
+ checkEqualLength(v1,v2);
570
+ switch (v1.length) {
571
+ case 2:
572
+ return v1[0] * v2[0] + v1[1] * v2[1];
573
+ case 3:
574
+ return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
575
+ case 4:
576
+ return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3];
577
+ default:
578
+ throw new Error(`Invalid vector size: ${ v1.length }`);
579
+ }
580
+ }
581
+
582
+ static Cross(v1: ArrayLike<number>, v2: ArrayLike<number>): Vec | number {
583
+ checkEqualLength(v1, v2);
584
+ switch (v1.length) {
585
+ case 2:
586
+ return v1[0] * v2[1] - v1[1] * v2[0];
587
+ case 3:
588
+ return new Vec([
589
+ v1[1] * v2[2] - v1[2] * v2[1],
590
+ v1[2] * v2[0] - v1[0] * v2[2],
591
+ v1[0] * v2[1] - v1[1] * v2[0],
592
+ ]);
593
+ default:
594
+ throw new Error(`Invalid vector size for cross product: ${v1.length}`);
595
+ }
596
+ }
597
+
598
+ static Normalized(v: ArrayLike<number>): Vec {
599
+ const m = Vec.Magnitude(v);
600
+ switch (v.length) {
601
+ case 2:
602
+ return new Vec([ v[0] / m, v[1] / m ]);
603
+ case 3:
604
+ return new Vec([ v[0] / m, v[1] / m, v[2] / m ]);
605
+ case 4:
606
+ return new Vec([ v[0] / m, v[1] / m, v[2] / m, v[3] / m ])
607
+ default:
608
+ throw new Error(`Invalid vector size: ${ v.length }`);
609
+ }
610
+ }
611
+
612
+ static Mult(v: ArrayLike<number>, s: number): Vec {
613
+ switch (v.length) {
614
+ case 2:
615
+ return new Vec([ v[0] * s, v[1] * s ]);
616
+ case 3:
617
+ return new Vec([ v[0] * s, v[1] * s, v[2] * s ]);
618
+ case 4:
619
+ return new Vec([ v[0] * s, v[1] * s, v[2] * s, v[3] * s ]);
620
+ default:
621
+ throw new Error(`Invalid vector size: ${ v.length }`);
622
+ }
623
+ }
624
+
625
+ static Div(v: ArrayLike<number>, s: number): Vec {
626
+ switch (v.length) {
627
+ case 2:
628
+ return new Vec([ v[0] / s, v[1] / s ]);
629
+ case 3:
630
+ return new Vec([ v[0] / s, v[1] / s, v[2] / s ]);
631
+ case 4:
632
+ return new Vec([ v[0] / s, v[1] / s, v[2] / s, v[3] / s ]);
633
+ default:
634
+ throw new Error(`Invalid vector size: ${ v.length }`);
635
+ }
636
+ }
637
+
638
+ static Equals(v1: ArrayLike<number>, v2: ArrayLike<number>): boolean {
639
+ if (v1.length != v2.length) {
640
+ return false;
641
+ }
642
+ else {
643
+ switch (v1.length) {
644
+ case 2:
645
+ return equals(v1[0], v2[0]) &&
646
+ equals(v1[1], v2[1]);
647
+ case 3:
648
+ return equals(v1[0], v2[0]) &&
649
+ equals(v1[1], v2[1]) &&
650
+ equals(v1[2], v2[2]);
651
+ case 4:
652
+ return equals(v1[0], v2[0]) &&
653
+ equals(v1[1], v2[1]) &&
654
+ equals(v1[2], v2[2]) &&
655
+ equals(v1[3], v2[3]);
656
+ default:
657
+ throw new Error(`Invalid vector size: ${ v1.length }`);
658
+ }
659
+ }
660
+ }
661
+
662
+ static IsZero(v: ArrayLike<number>): boolean {
663
+ switch (v.length) {
664
+ case 2:
665
+ return isZero(v[0]) || isZero(v[1]);
666
+ case 3:
667
+ return isZero(v[0]) || isZero(v[1]) || isZero(v[2]);
668
+ case 4:
669
+ return isZero(v[0]) || isZero(v[1]) || isZero(v[2]) || isZero(v[3]);
670
+ default:
671
+ throw new Error(`Invalid vector size: ${ v.length }`);
672
+ }
673
+ }
674
+
675
+ static IsNaN(v: ArrayLike<number>): boolean {
676
+ switch (v.length) {
677
+ case 2:
678
+ return isNaN(v[0]) || isNaN(v[1]);
679
+ case 3:
680
+ return isNaN(v[0]) || isNaN(v[1]) || isNaN(v[2]);
681
+ case 4:
682
+ return isNaN(v[0]) || isNaN(v[1]) || isNaN(v[2]) || isNaN(v[3]);
683
+ default:
684
+ throw new Error(`Invalid vector size: ${ v.length }`);
685
+ }
686
+ }
687
+
688
+ static Lerp(u: ArrayLike<number>, v: ArrayLike<number>, d: number): Vec {
689
+ if (u.length != v.length) {
690
+ throw new Error(`Different vector sizes calculating linear interpolation`);
691
+ }
692
+ switch (u.length) {
693
+ case 2:
694
+ return new Vec(
695
+ lerp(u[0], v[0], d),
696
+ lerp(u[1], v[1], d)
697
+ );
698
+ case 3:
699
+ return new Vec(
700
+ lerp(u[0], v[0], d),
701
+ lerp(u[1], v[1], d),
702
+ lerp(u[2], v[2], d)
703
+ );
704
+ case 4:
705
+ return new Vec(
706
+ lerp(u[0], v[0], d),
707
+ lerp(u[1], v[1], d),
708
+ lerp(u[2], v[2], d),
709
+ lerp(u[3], v[3], d)
710
+ );
711
+ default:
712
+ throw new Error(`Invalid vector size: ${ u.length }`);
713
+ }
714
+ }
715
+
716
+ static Clamp(v: ArrayLike<number>, min: ArrayLike<number>, max: ArrayLike<number>): Vec {
717
+ switch (v.length) {
718
+ case 2:
719
+ return new Vec(
720
+ clamp(v[0], min[0], max[0]),
721
+ clamp(v[1], min[1], max[1])
722
+ );
723
+ case 3:
724
+ return new Vec(
725
+ clamp(v[0], min[0], max[0]),
726
+ clamp(v[1], min[1], max[1]),
727
+ clamp(v[2], min[2], max[2])
728
+ );
729
+ case 4:
730
+ return new Vec(
731
+ clamp(v[0], min[0], max[0]),
732
+ clamp(v[1], min[1], max[1]),
733
+ clamp(v[2], min[2], max[2]),
734
+ clamp(v[3], min[3], max[3])
735
+ );
736
+ default:
737
+ throw new Error(`Invalid vector size: ${ v.length }`);
738
+ }
739
+ }
740
+
741
+ /////// Constructors
742
+ static Vec2(): Vec {
743
+ return new Vec(0,0);
744
+ }
745
+
746
+ static Vec3(): Vec {
747
+ return new Vec(0,0,0);
748
+ }
749
+
750
+ static Vec4(): Vec {
751
+ return new Vec(0,0,0,0);
752
+ }
753
+ }