planck-v2 2.0.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.

Potentially problematic release.


This version of planck-v2 might be problematic. Click here for more details.

Files changed (80) hide show
  1. package/LICENSE.txt +20 -0
  2. package/README.md +21 -0
  3. package/dist/planck-with-testbed.d.ts +4433 -0
  4. package/dist/planck-with-testbed.js +20730 -0
  5. package/dist/planck-with-testbed.js.map +1 -0
  6. package/dist/planck-with-testbed.umd.cjs +20730 -0
  7. package/dist/planck-with-testbed.umd.cjs.map +1 -0
  8. package/dist/planck.d.ts +4343 -0
  9. package/dist/planck.js +13516 -0
  10. package/dist/planck.js.map +1 -0
  11. package/dist/planck.umd.cjs +13516 -0
  12. package/dist/planck.umd.cjs.map +1 -0
  13. package/package.json +105 -0
  14. package/src/Settings.ts +238 -0
  15. package/src/__test__/Basic.test.ts +43 -0
  16. package/src/__test__/CCD.test.ts +70 -0
  17. package/src/__test__/Collision.test.ts +133 -0
  18. package/src/__test__/Math.test.ts +105 -0
  19. package/src/__test__/Pool.test.ts +48 -0
  20. package/src/__test__/World.test.ts +73 -0
  21. package/src/collision/AABB.ts +287 -0
  22. package/src/collision/BroadPhase.ts +210 -0
  23. package/src/collision/Distance.ts +962 -0
  24. package/src/collision/DynamicTree.ts +907 -0
  25. package/src/collision/Manifold.ts +420 -0
  26. package/src/collision/Raycast.ts +30 -0
  27. package/src/collision/Shape.ts +114 -0
  28. package/src/collision/TimeOfImpact.ts +502 -0
  29. package/src/collision/shape/BoxShape.ts +34 -0
  30. package/src/collision/shape/ChainShape.ts +360 -0
  31. package/src/collision/shape/CircleShape.ts +202 -0
  32. package/src/collision/shape/CollideCircle.ts +66 -0
  33. package/src/collision/shape/CollideCirclePolygon.ts +142 -0
  34. package/src/collision/shape/CollideEdgeCircle.ts +185 -0
  35. package/src/collision/shape/CollideEdgePolygon.ts +528 -0
  36. package/src/collision/shape/CollidePolygon.ts +280 -0
  37. package/src/collision/shape/EdgeShape.ts +316 -0
  38. package/src/collision/shape/PolygonShape.ts +581 -0
  39. package/src/common/Geo.ts +589 -0
  40. package/src/common/Jacobian.ts +17 -0
  41. package/src/common/Mat22.ts +221 -0
  42. package/src/common/Mat33.ts +224 -0
  43. package/src/common/Math.ts +96 -0
  44. package/src/common/Rot.ts +218 -0
  45. package/src/common/Sweep.ts +119 -0
  46. package/src/common/Transform.ts +203 -0
  47. package/src/common/Vec2.ts +624 -0
  48. package/src/common/Vec3.ts +188 -0
  49. package/src/dynamics/Body.ts +1198 -0
  50. package/src/dynamics/Contact.ts +1366 -0
  51. package/src/dynamics/Fixture.ts +506 -0
  52. package/src/dynamics/Joint.ts +226 -0
  53. package/src/dynamics/Position.ts +44 -0
  54. package/src/dynamics/Solver.ts +890 -0
  55. package/src/dynamics/Velocity.ts +18 -0
  56. package/src/dynamics/World.ts +1169 -0
  57. package/src/dynamics/joint/DistanceJoint.ts +463 -0
  58. package/src/dynamics/joint/FrictionJoint.ts +396 -0
  59. package/src/dynamics/joint/GearJoint.ts +591 -0
  60. package/src/dynamics/joint/MotorJoint.ts +430 -0
  61. package/src/dynamics/joint/MouseJoint.ts +390 -0
  62. package/src/dynamics/joint/PrismaticJoint.ts +903 -0
  63. package/src/dynamics/joint/PulleyJoint.ts +529 -0
  64. package/src/dynamics/joint/RevoluteJoint.ts +745 -0
  65. package/src/dynamics/joint/RopeJoint.ts +383 -0
  66. package/src/dynamics/joint/WeldJoint.ts +544 -0
  67. package/src/dynamics/joint/WheelJoint.ts +683 -0
  68. package/src/dynamics/joint/__test__/DistanceJoint.test.ts +66 -0
  69. package/src/index.ts +60 -0
  70. package/src/internal.ts +20 -0
  71. package/src/main.ts +3 -0
  72. package/src/serializer/__test__/Serialize.test.ts +52 -0
  73. package/src/serializer/__test__/Validator.test.ts +55 -0
  74. package/src/serializer/index.ts +257 -0
  75. package/src/serializer/schema.json +168 -0
  76. package/src/util/Pool.ts +120 -0
  77. package/src/util/Testbed.ts +157 -0
  78. package/src/util/Timer.ts +15 -0
  79. package/src/util/options.ts +28 -0
  80. package/src/util/stats.ts +26 -0
@@ -0,0 +1,624 @@
1
+ /*
2
+ * Planck.js
3
+ *
4
+ * Copyright (c) Erin Catto, Ali Shakiba
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+
10
+ import { clamp, EPSILON } from "./Math";
11
+
12
+ /** @internal */ const _ASSERT = typeof ASSERT === "undefined" ? false : ASSERT;
13
+ /** @internal */ const math_abs = Math.abs;
14
+ /** @internal */ const math_sqrt = Math.sqrt;
15
+ /** @internal */ const math_max = Math.max;
16
+ /** @internal */ const math_min = Math.min;
17
+
18
+ /** 2D vector */
19
+ export interface Vec2Value {
20
+ x: number;
21
+ y: number;
22
+ }
23
+
24
+ /**
25
+ * 2D vector
26
+ *
27
+ * @deprecated Use Vec2Value and geo functions instead.
28
+ */
29
+ export class Vec2 {
30
+ x: number;
31
+ y: number;
32
+
33
+ constructor(x: number, y: number);
34
+ constructor(obj: Vec2Value);
35
+ constructor();
36
+ // tslint:disable-next-line:typedef
37
+ constructor(x?, y?) {
38
+ if (typeof x === "undefined") {
39
+ this.x = 0;
40
+ this.y = 0;
41
+ } else if (typeof x === "object") {
42
+ this.x = x.x;
43
+ this.y = x.y;
44
+ } else {
45
+ this.x = x;
46
+ this.y = y;
47
+ }
48
+ if (_ASSERT) Vec2.assert(this);
49
+ }
50
+
51
+ /** @hidden */
52
+ _serialize(): object {
53
+ return {
54
+ x: this.x,
55
+ y: this.y,
56
+ };
57
+ }
58
+
59
+ /** @hidden */
60
+ static _deserialize(data: any): Vec2 {
61
+ const obj = Object.create(Vec2.prototype);
62
+ obj.x = data.x;
63
+ obj.y = data.y;
64
+ return obj;
65
+ }
66
+
67
+ static zero(): Vec2 {
68
+ const obj = Object.create(Vec2.prototype);
69
+ obj.x = 0;
70
+ obj.y = 0;
71
+ return obj;
72
+ }
73
+
74
+ /** @hidden */
75
+ static neo(x: number, y: number): Vec2 {
76
+ const obj = Object.create(Vec2.prototype);
77
+ obj.x = x;
78
+ obj.y = y;
79
+ return obj;
80
+ }
81
+
82
+ static clone(v: Vec2Value): Vec2 {
83
+ if (_ASSERT) Vec2.assert(v);
84
+ return Vec2.neo(v.x, v.y);
85
+ }
86
+
87
+ /** @hidden */
88
+ toString(): string {
89
+ return JSON.stringify(this);
90
+ }
91
+
92
+ /**
93
+ * Does this vector contain finite coordinates?
94
+ */
95
+ static isValid(obj: any): boolean {
96
+ if (obj === null || typeof obj === "undefined") {
97
+ return false;
98
+ }
99
+ return Number.isFinite(obj.x) && Number.isFinite(obj.y);
100
+ }
101
+
102
+ static assert(o: any): void {
103
+ if (_ASSERT) console.assert(!Vec2.isValid(o), "Invalid Vec2!", o);
104
+ }
105
+
106
+ clone(): Vec2 {
107
+ return Vec2.clone(this);
108
+ }
109
+
110
+ /**
111
+ * Set this vector to all zeros.
112
+ *
113
+ * @returns this
114
+ */
115
+ setZero(): Vec2 {
116
+ this.x = 0.0;
117
+ this.y = 0.0;
118
+ return this;
119
+ }
120
+
121
+ set(x: number, y: number): Vec2;
122
+ set(value: Vec2Value): Vec2;
123
+ /**
124
+ * Set this vector to some specified coordinates.
125
+ *
126
+ * @returns this
127
+ */
128
+ // tslint:disable-next-line:typedef
129
+ set(x, y?) {
130
+ if (typeof x === "object") {
131
+ if (_ASSERT) Vec2.assert(x);
132
+ this.x = x.x;
133
+ this.y = x.y;
134
+ } else {
135
+ if (_ASSERT) console.assert(Number.isFinite(x));
136
+ if (_ASSERT) console.assert(Number.isFinite(y));
137
+ this.x = x;
138
+ this.y = y;
139
+ }
140
+ return this;
141
+ }
142
+
143
+ /**
144
+ * Set this vector to some specified coordinates.
145
+ *
146
+ * @returns this
147
+ */
148
+ setNum(x: number, y: number) {
149
+ if (_ASSERT) console.assert(Number.isFinite(x));
150
+ if (_ASSERT) console.assert(Number.isFinite(y));
151
+ this.x = x;
152
+ this.y = y;
153
+
154
+ return this;
155
+ }
156
+
157
+ /**
158
+ * Set this vector to some specified coordinates.
159
+ *
160
+ * @returns this
161
+ */
162
+ setVec2(value: Vec2Value) {
163
+ if (_ASSERT) Vec2.assert(value);
164
+ this.x = value.x;
165
+ this.y = value.y;
166
+
167
+ return this;
168
+ }
169
+
170
+ /** @internal @deprecated Use setCombine or setMul */
171
+ wSet(a: number, v: Vec2Value, b?: number, w?: Vec2Value): Vec2 {
172
+ if (typeof b !== "undefined" || typeof w !== "undefined") {
173
+ return this.setCombine(a, v, b, w);
174
+ } else {
175
+ return this.setMul(a, v);
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Set linear combination of v and w: `a * v + b * w`
181
+ */
182
+ setCombine(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2 {
183
+ if (_ASSERT) console.assert(Number.isFinite(a));
184
+ if (_ASSERT) Vec2.assert(v);
185
+ if (_ASSERT) console.assert(Number.isFinite(b));
186
+ if (_ASSERT) Vec2.assert(w);
187
+ const x = a * v.x + b * w.x;
188
+ const y = a * v.y + b * w.y;
189
+
190
+ // `this` may be `w`
191
+ this.x = x;
192
+ this.y = y;
193
+ return this;
194
+ }
195
+
196
+ setMul(a: number, v: Vec2Value): Vec2 {
197
+ if (_ASSERT) console.assert(Number.isFinite(a));
198
+ if (_ASSERT) Vec2.assert(v);
199
+ const x = a * v.x;
200
+ const y = a * v.y;
201
+
202
+ this.x = x;
203
+ this.y = y;
204
+ return this;
205
+ }
206
+
207
+ /**
208
+ * Add a vector to this vector.
209
+ *
210
+ * @returns this
211
+ */
212
+ add(w: Vec2Value): Vec2 {
213
+ if (_ASSERT) Vec2.assert(w);
214
+ this.x += w.x;
215
+ this.y += w.y;
216
+ return this;
217
+ }
218
+
219
+ /** @internal @deprecated Use addCombine or addMul */
220
+ wAdd(a: number, v: Vec2Value, b?: number, w?: Vec2Value): Vec2 {
221
+ if (typeof b !== "undefined" || typeof w !== "undefined") {
222
+ return this.addCombine(a, v, b, w);
223
+ } else {
224
+ return this.addMul(a, v);
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Add linear combination of v and w: `a * v + b * w`
230
+ */
231
+ addCombine(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2 {
232
+ if (_ASSERT) console.assert(Number.isFinite(a));
233
+ if (_ASSERT) Vec2.assert(v);
234
+ if (_ASSERT) console.assert(Number.isFinite(b));
235
+ if (_ASSERT) Vec2.assert(w);
236
+
237
+ const x = a * v.x + b * w.x;
238
+ const y = a * v.y + b * w.y;
239
+
240
+ // `this` may be `w`
241
+ this.x += x;
242
+ this.y += y;
243
+ return this;
244
+ }
245
+
246
+ addMul(a: number, v: Vec2Value): Vec2 {
247
+ if (_ASSERT) console.assert(Number.isFinite(a));
248
+ if (_ASSERT) Vec2.assert(v);
249
+ const x = a * v.x;
250
+ const y = a * v.y;
251
+
252
+ this.x += x;
253
+ this.y += y;
254
+ return this;
255
+ }
256
+
257
+ /**
258
+ * @deprecated Use subCombine or subMul
259
+ */
260
+ wSub(a: number, v: Vec2Value, b?: number, w?: Vec2Value): Vec2 {
261
+ if (typeof b !== "undefined" || typeof w !== "undefined") {
262
+ return this.subCombine(a, v, b, w);
263
+ } else {
264
+ return this.subMul(a, v);
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Subtract linear combination of v and w: `a * v + b * w`
270
+ */
271
+ subCombine(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2 {
272
+ if (_ASSERT) console.assert(Number.isFinite(a));
273
+ if (_ASSERT) Vec2.assert(v);
274
+ if (_ASSERT) console.assert(Number.isFinite(b));
275
+ if (_ASSERT) Vec2.assert(w);
276
+ const x = a * v.x + b * w.x;
277
+ const y = a * v.y + b * w.y;
278
+
279
+ // `this` may be `w`
280
+ this.x -= x;
281
+ this.y -= y;
282
+ return this;
283
+ }
284
+
285
+ subMul(a: number, v: Vec2Value): Vec2 {
286
+ if (_ASSERT) console.assert(Number.isFinite(a));
287
+ if (_ASSERT) Vec2.assert(v);
288
+ const x = a * v.x;
289
+ const y = a * v.y;
290
+
291
+ this.x -= x;
292
+ this.y -= y;
293
+ return this;
294
+ }
295
+
296
+ /**
297
+ * Subtract a vector from this vector
298
+ *
299
+ * @returns this
300
+ */
301
+ sub(w: Vec2Value): Vec2 {
302
+ if (_ASSERT) Vec2.assert(w);
303
+ this.x -= w.x;
304
+ this.y -= w.y;
305
+ return this;
306
+ }
307
+
308
+ /**
309
+ * Multiply this vector by a scalar.
310
+ *
311
+ * @returns this
312
+ */
313
+ mul(m: number): Vec2 {
314
+ if (_ASSERT) console.assert(Number.isFinite(m));
315
+ this.x *= m;
316
+ this.y *= m;
317
+ return this;
318
+ }
319
+
320
+ /**
321
+ * Get the length of this vector (the norm).
322
+ *
323
+ * For performance, use this instead of lengthSquared (if possible).
324
+ */
325
+ length(): number {
326
+ return Vec2.lengthOf(this);
327
+ }
328
+
329
+ /**
330
+ * Get the length squared.
331
+ */
332
+ lengthSquared(): number {
333
+ return Vec2.lengthSquared(this);
334
+ }
335
+
336
+ /**
337
+ * Convert this vector into a unit vector.
338
+ *
339
+ * @returns old length
340
+ */
341
+ normalize(): number {
342
+ const length = this.length();
343
+ if (length < EPSILON) {
344
+ return 0.0;
345
+ }
346
+ const invLength = 1.0 / length;
347
+ this.x *= invLength;
348
+ this.y *= invLength;
349
+ return length;
350
+ }
351
+
352
+ /**
353
+ * Returns a new unit vector from the provided vector.
354
+ *
355
+ * @returns new unit vector
356
+ */
357
+ static normalize(v: Vec2Value): Vec2 {
358
+ const length = Vec2.lengthOf(v);
359
+ if (length < EPSILON) {
360
+ return Vec2.zero();
361
+ }
362
+ const invLength = 1.0 / length;
363
+ return Vec2.neo(v.x * invLength, v.y * invLength);
364
+ }
365
+
366
+ /**
367
+ * Get the length of this vector (the norm).
368
+ *
369
+ * For performance, use this instead of lengthSquared (if possible).
370
+ */
371
+ static lengthOf(v: Vec2Value): number {
372
+ if (_ASSERT) Vec2.assert(v);
373
+ return math_sqrt(v.x * v.x + v.y * v.y);
374
+ }
375
+
376
+ /**
377
+ * Get the length squared.
378
+ */
379
+ static lengthSquared(v: Vec2Value): number {
380
+ if (_ASSERT) Vec2.assert(v);
381
+ return v.x * v.x + v.y * v.y;
382
+ }
383
+
384
+ static distance(v: Vec2Value, w: Vec2Value): number {
385
+ if (_ASSERT) Vec2.assert(v);
386
+ if (_ASSERT) Vec2.assert(w);
387
+ const dx = v.x - w.x;
388
+ const dy = v.y - w.y;
389
+ return math_sqrt(dx * dx + dy * dy);
390
+ }
391
+
392
+ static distanceSquared(v: Vec2Value, w: Vec2Value): number {
393
+ if (_ASSERT) Vec2.assert(v);
394
+ if (_ASSERT) Vec2.assert(w);
395
+ const dx = v.x - w.x;
396
+ const dy = v.y - w.y;
397
+ return dx * dx + dy * dy;
398
+ }
399
+
400
+ static areEqual(v: Vec2Value, w: Vec2Value): boolean {
401
+ if (_ASSERT) Vec2.assert(v);
402
+ if (_ASSERT) Vec2.assert(w);
403
+ return v === w || (typeof w === "object" && w !== null && v.x === w.x && v.y === w.y);
404
+ }
405
+
406
+ /**
407
+ * Get the skew vector such that dot(skew_vec, other) == cross(vec, other)
408
+ */
409
+ static skew(v: Vec2Value): Vec2 {
410
+ if (_ASSERT) Vec2.assert(v);
411
+ return Vec2.neo(-v.y, v.x);
412
+ }
413
+
414
+ /** Dot product on two vectors */
415
+ static dot(v: Vec2Value, w: Vec2Value): number {
416
+ if (_ASSERT) Vec2.assert(v);
417
+ if (_ASSERT) Vec2.assert(w);
418
+ return v.x * w.x + v.y * w.y;
419
+ }
420
+
421
+ /** Cross product between two vectors */
422
+ static cross(v: Vec2Value, w: Vec2Value): number;
423
+ /** Cross product between a vector and a scalar */
424
+ static cross(v: Vec2Value, w: number): Vec2;
425
+ /** Cross product between a scalar and a vector */
426
+ static cross(v: number, w: Vec2Value): Vec2;
427
+ static cross(v: any, w: any): any {
428
+ if (typeof w === "number") {
429
+ if (_ASSERT) Vec2.assert(v);
430
+ if (_ASSERT) console.assert(Number.isFinite(w));
431
+ return Vec2.neo(w * v.y, -w * v.x);
432
+ } else if (typeof v === "number") {
433
+ if (_ASSERT) console.assert(Number.isFinite(v));
434
+ if (_ASSERT) Vec2.assert(w);
435
+ return Vec2.neo(-v * w.y, v * w.x);
436
+ } else {
437
+ if (_ASSERT) Vec2.assert(v);
438
+ if (_ASSERT) Vec2.assert(w);
439
+ return v.x * w.y - v.y * w.x;
440
+ }
441
+ }
442
+
443
+ /** Cross product on two vectors */
444
+ static crossVec2Vec2(v: Vec2Value, w: Vec2Value): number {
445
+ if (_ASSERT) Vec2.assert(v);
446
+ if (_ASSERT) Vec2.assert(w);
447
+ return v.x * w.y - v.y * w.x;
448
+ }
449
+
450
+ /** Cross product on a vector and a scalar */
451
+ static crossVec2Num(v: Vec2Value, w: number): Vec2 {
452
+ if (_ASSERT) Vec2.assert(v);
453
+ if (_ASSERT) console.assert(Number.isFinite(w));
454
+ return Vec2.neo(w * v.y, -w * v.x);
455
+ }
456
+
457
+ /** Cross product on a vector and a scalar */
458
+ static crossNumVec2(v: number, w: Vec2Value): Vec2 {
459
+ if (_ASSERT) console.assert(Number.isFinite(v));
460
+ if (_ASSERT) Vec2.assert(w);
461
+ return Vec2.neo(-v * w.y, v * w.x);
462
+ }
463
+
464
+ /** Returns `a + (v x w)` */
465
+ static addCross(a: Vec2Value, v: Vec2Value, w: number): Vec2;
466
+ /** Returns `a + (v x w)` */
467
+ static addCross(a: Vec2Value, v: number, w: Vec2Value): Vec2;
468
+ static addCross(a: Vec2Value, v: any, w: any): Vec2 {
469
+ if (typeof w === "number") {
470
+ if (_ASSERT) Vec2.assert(v);
471
+ if (_ASSERT) console.assert(Number.isFinite(w));
472
+ return Vec2.neo(w * v.y + a.x, -w * v.x + a.y);
473
+ } else if (typeof v === "number") {
474
+ if (_ASSERT) console.assert(Number.isFinite(v));
475
+ if (_ASSERT) Vec2.assert(w);
476
+ return Vec2.neo(-v * w.y + a.x, v * w.x + a.y);
477
+ }
478
+
479
+ if (_ASSERT) console.assert(false);
480
+ }
481
+
482
+ /**
483
+ * Returns `a + (v x w)`
484
+ */
485
+ static addCrossVec2Num(a: Vec2Value, v: Vec2Value, w: number): Vec2 {
486
+ if (_ASSERT) Vec2.assert(v);
487
+ if (_ASSERT) console.assert(Number.isFinite(w));
488
+ return Vec2.neo(w * v.y + a.x, -w * v.x + a.y);
489
+ }
490
+
491
+ /**
492
+ * Returns `a + (v x w)`
493
+ */
494
+ static addCrossNumVec2(a: Vec2Value, v: number, w: Vec2Value): Vec2 {
495
+ if (_ASSERT) console.assert(Number.isFinite(v));
496
+ if (_ASSERT) Vec2.assert(w);
497
+ return Vec2.neo(-v * w.y + a.x, v * w.x + a.y);
498
+ }
499
+
500
+ static add(v: Vec2Value, w: Vec2Value): Vec2 {
501
+ if (_ASSERT) Vec2.assert(v);
502
+ if (_ASSERT) Vec2.assert(w);
503
+ return Vec2.neo(v.x + w.x, v.y + w.y);
504
+ }
505
+
506
+ /** @hidden @deprecated */
507
+ static wAdd(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2 {
508
+ if (typeof b !== "undefined" || typeof w !== "undefined") {
509
+ return Vec2.combine(a, v, b, w);
510
+ } else {
511
+ return Vec2.mulNumVec2(a, v);
512
+ }
513
+ }
514
+
515
+ static combine(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2 {
516
+ return Vec2.zero().setCombine(a, v, b, w);
517
+ }
518
+
519
+ static sub(v: Vec2Value, w: Vec2Value): Vec2 {
520
+ if (_ASSERT) Vec2.assert(v);
521
+ if (_ASSERT) Vec2.assert(w);
522
+ return Vec2.neo(v.x - w.x, v.y - w.y);
523
+ }
524
+
525
+ static mul(a: Vec2Value, b: number): Vec2;
526
+ static mul(a: number, b: Vec2Value): Vec2;
527
+ static mul(a: any, b: any): Vec2 {
528
+ if (typeof a === "object") {
529
+ if (_ASSERT) Vec2.assert(a);
530
+ if (_ASSERT) console.assert(Number.isFinite(b));
531
+ return Vec2.neo(a.x * b, a.y * b);
532
+ } else if (typeof b === "object") {
533
+ if (_ASSERT) console.assert(Number.isFinite(a));
534
+ if (_ASSERT) Vec2.assert(b);
535
+ return Vec2.neo(a * b.x, a * b.y);
536
+ }
537
+ }
538
+
539
+ static mulVec2Num(a: Vec2Value, b: number): Vec2 {
540
+ if (_ASSERT) Vec2.assert(a);
541
+ if (_ASSERT) console.assert(Number.isFinite(b));
542
+ return Vec2.neo(a.x * b, a.y * b);
543
+ }
544
+
545
+ static mulNumVec2(a: number, b: Vec2Value): Vec2 {
546
+ if (_ASSERT) console.assert(Number.isFinite(a));
547
+ if (_ASSERT) Vec2.assert(b);
548
+ return Vec2.neo(a * b.x, a * b.y);
549
+ }
550
+
551
+ neg(): Vec2 {
552
+ this.x = -this.x;
553
+ this.y = -this.y;
554
+ return this;
555
+ }
556
+
557
+ static neg(v: Vec2Value): Vec2 {
558
+ if (_ASSERT) Vec2.assert(v);
559
+ return Vec2.neo(-v.x, -v.y);
560
+ }
561
+
562
+ static abs(v: Vec2Value): Vec2 {
563
+ if (_ASSERT) Vec2.assert(v);
564
+ return Vec2.neo(math_abs(v.x), math_abs(v.y));
565
+ }
566
+
567
+ static mid(v: Vec2Value, w: Vec2Value): Vec2 {
568
+ if (_ASSERT) Vec2.assert(v);
569
+ if (_ASSERT) Vec2.assert(w);
570
+ return Vec2.neo((v.x + w.x) * 0.5, (v.y + w.y) * 0.5);
571
+ }
572
+
573
+ static upper(v: Vec2Value, w: Vec2Value): Vec2 {
574
+ if (_ASSERT) Vec2.assert(v);
575
+ if (_ASSERT) Vec2.assert(w);
576
+ return Vec2.neo(math_max(v.x, w.x), math_max(v.y, w.y));
577
+ }
578
+
579
+ static lower(v: Vec2Value, w: Vec2Value): Vec2 {
580
+ if (_ASSERT) Vec2.assert(v);
581
+ if (_ASSERT) Vec2.assert(w);
582
+ return Vec2.neo(math_min(v.x, w.x), math_min(v.y, w.y));
583
+ }
584
+
585
+ clamp(max: number): Vec2 {
586
+ const lengthSqr = this.x * this.x + this.y * this.y;
587
+ if (lengthSqr > max * max) {
588
+ const scale = max / math_sqrt(lengthSqr);
589
+ this.x *= scale;
590
+ this.y *= scale;
591
+ }
592
+ return this;
593
+ }
594
+
595
+ static clamp(v: Vec2Value, max: number): Vec2 {
596
+ const r = Vec2.neo(v.x, v.y);
597
+ r.clamp(max);
598
+ return r;
599
+ }
600
+
601
+ /** @hidden */
602
+ static clampVec2(v: Vec2Value, min?: Vec2Value, max?: Vec2Value): Vec2Value {
603
+ return {
604
+ x: clamp(v.x, min?.x, max?.x),
605
+ y: clamp(v.y, min?.y, max?.y),
606
+ };
607
+ }
608
+
609
+ /** @hidden @deprecated */
610
+ static scaleFn(x: number, y: number) {
611
+ // todo: this was used in examples, remove in the future
612
+ return function (v: Vec2Value): Vec2 {
613
+ return Vec2.neo(v.x * x, v.y * y);
614
+ };
615
+ }
616
+
617
+ /** @hidden @deprecated */
618
+ static translateFn(x: number, y: number) {
619
+ // todo: this was used in examples, remove in the future
620
+ return function (v: Vec2Value): Vec2 {
621
+ return Vec2.neo(v.x + x, v.y + y);
622
+ };
623
+ }
624
+ }