emeraldengine 3.0.0 → 3.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/README.md +1498 -1659
- package/dist/types/index.d.ts +4 -1
- package/dist/types/src/Animator.d.ts +1 -1
- package/dist/types/src/CollisionLayers.d.ts +2 -2
- package/dist/types/src/Color.d.ts +1 -0
- package/dist/types/src/Drawable.d.ts +1 -1
- package/dist/types/src/EmeraldDB.d.ts +2 -2
- package/dist/types/src/InstancedTexture.d.ts +17 -2
- package/dist/types/src/Material.d.ts +2 -2
- package/dist/types/src/MathUtils.d.ts +2 -1
- package/dist/types/src/ParticleEmitter.d.ts +1 -1
- package/dist/types/src/Physics.d.ts +148 -18
- package/dist/types/src/Scene.d.ts +1 -1
- package/dist/types/src/Shaders.d.ts +2 -2
- package/dist/types/src/Tilemap.d.ts +1 -1
- package/dist/types/src/UI.d.ts +1 -1
- package/dist/types/src/components/Behaviour.d.ts +2 -2
- package/dist/types/src/components/Collider.d.ts +7 -1
- package/dist/types/src/components/GameObject.d.ts +2 -2
- package/dist/types/src/components/PolygonCollider.d.ts +33 -0
- package/dist/types/src/components/RigidBody.d.ts +281 -8
- package/dist/types/src/importers/Aseprite.d.ts +2 -2
- package/dist/types/src/importers/ForgeLevel.d.ts +97 -0
- package/dist/types/src/importers/TiledMap.d.ts +1 -1
- package/dist/types/src/managers/EventManager.d.ts +1 -1
- package/dist/types/src/managers/Gamepad.d.ts +102 -0
- package/dist/types/src/managers/InputManager.d.ts +93 -2
- package/dist/types/src/managers/NetworkManager.d.ts +2 -2
- package/dist/types/src/managers/RenderStats.d.ts +1 -1
- package/dist/types/src/managers/TextureManager.d.ts +1 -1
- package/dist/types/src/physics/AABB.d.ts +92 -0
- package/dist/types/src/physics/Body.d.ts +435 -0
- package/dist/types/src/physics/BodyType.d.ts +6 -0
- package/dist/types/src/physics/BroadPhase.d.ts +210 -0
- package/dist/types/src/physics/Collision.d.ts +102 -0
- package/dist/types/src/physics/Contact.d.ts +206 -0
- package/dist/types/src/physics/ContactSolver.d.ts +108 -0
- package/dist/types/src/physics/Distance.d.ts +54 -0
- package/dist/types/src/physics/DistanceJoint.d.ts +90 -0
- package/dist/types/src/physics/Fixture.d.ts +221 -0
- package/dist/types/src/physics/Island.d.ts +52 -0
- package/dist/types/src/physics/Joint.d.ts +59 -0
- package/dist/types/src/physics/Math2D.d.ts +371 -0
- package/dist/types/src/physics/RevoluteJoint.d.ts +119 -0
- package/dist/types/src/physics/Settings.d.ts +22 -0
- package/dist/types/src/physics/Shapes.d.ts +207 -0
- package/dist/types/src/physics/TimeOfImpact.d.ts +22 -0
- package/dist/types/src/physics/World.d.ts +274 -0
- package/dist/types/src/physics/index.d.ts +34 -0
- package/index.js +6 -0
- package/package.json +2 -3
- package/src/Animator.js +1 -1
- package/src/CollisionLayers.js +3 -3
- package/src/Color.js +8 -0
- package/src/Drawable.js +1 -1
- package/src/Emerald.js +1 -1
- package/src/EmeraldDB.js +2 -2
- package/src/InstancedTexture.js +57 -9
- package/src/Material.js +2 -2
- package/src/MathUtils.js +2 -1
- package/src/ParticleEmitter.js +1 -1
- package/src/Physics.js +270 -60
- package/src/Scene.js +1 -1
- package/src/Shaders.js +20 -20
- package/src/Tilemap.js +1 -1
- package/src/UI.js +1 -1
- package/src/components/Behaviour.js +2 -2
- package/src/components/BoxCollider.js +7 -9
- package/src/components/BoxColliderDebug.js +3 -4
- package/src/components/CircleCollider.js +7 -9
- package/src/components/CircleColliderDebug.js +3 -2
- package/src/components/Collider.js +13 -3
- package/src/components/GameObject.js +2 -2
- package/src/components/PolygonCollider.js +55 -0
- package/src/components/RigidBody.js +441 -14
- package/src/importers/Aseprite.js +2 -2
- package/src/importers/ForgeLevel.js +581 -0
- package/src/importers/TiledMap.js +1 -1
- package/src/managers/EventManager.js +1 -1
- package/src/managers/Gamepad.js +126 -0
- package/src/managers/InputManager.js +129 -3
- package/src/managers/NetworkManager.js +2 -2
- package/src/managers/RenderStats.js +1 -1
- package/src/managers/TextureManager.js +1 -1
- package/src/physics/AABB.js +207 -0
- package/src/physics/Body.js +862 -0
- package/src/physics/BodyType.js +16 -0
- package/src/physics/BroadPhase.js +641 -0
- package/src/physics/Collision.js +534 -0
- package/src/physics/Contact.js +500 -0
- package/src/physics/ContactSolver.js +526 -0
- package/src/physics/Distance.js +403 -0
- package/src/physics/DistanceJoint.js +227 -0
- package/src/physics/Fixture.js +346 -0
- package/src/physics/Island.js +203 -0
- package/src/physics/Joint.js +78 -0
- package/src/physics/Math2D.js +573 -0
- package/src/physics/RevoluteJoint.js +278 -0
- package/src/physics/Settings.js +78 -0
- package/src/physics/Shapes.js +549 -0
- package/src/physics/TimeOfImpact.js +87 -0
- package/src/physics/World.js +731 -0
- package/src/physics/index.js +79 -0
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Math primitives for the Emerald physics engine.
|
|
3
|
+
* @description Everything here works in *physics units* (meters, radians), not
|
|
4
|
+
* world/pixel units. The conversion happens in {@link Physics} and
|
|
5
|
+
* {@link RigidBody}, so nothing below ever needs to know about the pixel scale.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @class Vec2
|
|
10
|
+
* @description A 2D vector in physics space. Instance methods mutate in place
|
|
11
|
+
* (used in the hot solver paths); the statics allocate a new vector. Accepts
|
|
12
|
+
* either two numbers or any `{ x, y }` object.
|
|
13
|
+
* @param {number|Object} [x=0] - The x coordinate, or an `{ x, y }` object
|
|
14
|
+
* @param {number} [y=0] - The y coordinate
|
|
15
|
+
*/
|
|
16
|
+
class Vec2 {
|
|
17
|
+
constructor(x = 0, y = 0) {
|
|
18
|
+
if (typeof x === "object" && x !== null) {
|
|
19
|
+
this.x = x.x || 0;
|
|
20
|
+
this.y = x.y || 0;
|
|
21
|
+
} else {
|
|
22
|
+
this.x = x;
|
|
23
|
+
this.y = y;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @method set
|
|
29
|
+
* @description Sets both components in place.
|
|
30
|
+
* @param {number} x
|
|
31
|
+
* @param {number} y
|
|
32
|
+
* @returns {Vec2} - this
|
|
33
|
+
*/
|
|
34
|
+
set(x, y) {
|
|
35
|
+
this.x = x;
|
|
36
|
+
this.y = y;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @method copy
|
|
42
|
+
* @description Copies another vector's components into this one.
|
|
43
|
+
* @param {Object} v - Any `{ x, y }`
|
|
44
|
+
* @returns {Vec2} - this
|
|
45
|
+
*/
|
|
46
|
+
copy(v) {
|
|
47
|
+
this.x = v.x;
|
|
48
|
+
this.y = v.y;
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @method clone
|
|
54
|
+
* @description Returns an independent copy.
|
|
55
|
+
* @returns {Vec2}
|
|
56
|
+
*/
|
|
57
|
+
clone() {
|
|
58
|
+
return new Vec2(this.x, this.y);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @method setZero
|
|
63
|
+
* @description Zeroes both components in place.
|
|
64
|
+
* @returns {Vec2} - this
|
|
65
|
+
*/
|
|
66
|
+
setZero() {
|
|
67
|
+
this.x = 0;
|
|
68
|
+
this.y = 0;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @method add
|
|
74
|
+
* @description Adds another vector in place.
|
|
75
|
+
* @param {Object} v
|
|
76
|
+
* @returns {Vec2} - this
|
|
77
|
+
*/
|
|
78
|
+
add(v) {
|
|
79
|
+
this.x += v.x;
|
|
80
|
+
this.y += v.y;
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @method addMul
|
|
86
|
+
* @description Adds `s * v` in place. The workhorse of the solver.
|
|
87
|
+
* @param {number} s
|
|
88
|
+
* @param {Object} v
|
|
89
|
+
* @returns {Vec2} - this
|
|
90
|
+
*/
|
|
91
|
+
addMul(s, v) {
|
|
92
|
+
this.x += s * v.x;
|
|
93
|
+
this.y += s * v.y;
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @method sub
|
|
99
|
+
* @description Subtracts another vector in place.
|
|
100
|
+
* @param {Object} v
|
|
101
|
+
* @returns {Vec2} - this
|
|
102
|
+
*/
|
|
103
|
+
sub(v) {
|
|
104
|
+
this.x -= v.x;
|
|
105
|
+
this.y -= v.y;
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @method subMul
|
|
111
|
+
* @description Subtracts `s * v` in place.
|
|
112
|
+
* @param {number} s
|
|
113
|
+
* @param {Object} v
|
|
114
|
+
* @returns {Vec2} - this
|
|
115
|
+
*/
|
|
116
|
+
subMul(s, v) {
|
|
117
|
+
this.x -= s * v.x;
|
|
118
|
+
this.y -= s * v.y;
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @method mul
|
|
124
|
+
* @description Scales in place.
|
|
125
|
+
* @param {number} s
|
|
126
|
+
* @returns {Vec2} - this
|
|
127
|
+
*/
|
|
128
|
+
mul(s) {
|
|
129
|
+
this.x *= s;
|
|
130
|
+
this.y *= s;
|
|
131
|
+
return this;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @method neg
|
|
136
|
+
* @description Negates in place.
|
|
137
|
+
* @returns {Vec2} - this
|
|
138
|
+
*/
|
|
139
|
+
neg() {
|
|
140
|
+
this.x = -this.x;
|
|
141
|
+
this.y = -this.y;
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @method length
|
|
147
|
+
* @description Euclidean length.
|
|
148
|
+
* @returns {number}
|
|
149
|
+
*/
|
|
150
|
+
length() {
|
|
151
|
+
return Math.sqrt(this.x * this.x + this.y * this.y);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @method lengthSquared
|
|
156
|
+
* @description Squared length (no sqrt).
|
|
157
|
+
* @returns {number}
|
|
158
|
+
*/
|
|
159
|
+
lengthSquared() {
|
|
160
|
+
return this.x * this.x + this.y * this.y;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @method normalize
|
|
165
|
+
* @description Normalizes in place and returns the previous length. A
|
|
166
|
+
* zero-length vector is left untouched (and reports 0).
|
|
167
|
+
* @returns {number} - The length before normalizing
|
|
168
|
+
*/
|
|
169
|
+
normalize() {
|
|
170
|
+
const len = this.length();
|
|
171
|
+
if (len < EPSILON) return 0;
|
|
172
|
+
const inv = 1 / len;
|
|
173
|
+
this.x *= inv;
|
|
174
|
+
this.y *= inv;
|
|
175
|
+
return len;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @method isValid
|
|
180
|
+
* @description True when both components are finite.
|
|
181
|
+
* @returns {boolean}
|
|
182
|
+
*/
|
|
183
|
+
isValid() {
|
|
184
|
+
return Number.isFinite(this.x) && Number.isFinite(this.y);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* @method zero
|
|
189
|
+
* @description Returns a fresh zero vector.
|
|
190
|
+
* @returns {Vec2}
|
|
191
|
+
*/
|
|
192
|
+
static zero() {
|
|
193
|
+
return new Vec2(0, 0);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* @method add
|
|
198
|
+
* @description a + b as a new vector.
|
|
199
|
+
* @param {Object} a
|
|
200
|
+
* @param {Object} b
|
|
201
|
+
* @returns {Vec2}
|
|
202
|
+
*/
|
|
203
|
+
static add(a, b) {
|
|
204
|
+
return new Vec2(a.x + b.x, a.y + b.y);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* @method sub
|
|
209
|
+
* @description a - b as a new vector.
|
|
210
|
+
* @param {Object} a
|
|
211
|
+
* @param {Object} b
|
|
212
|
+
* @returns {Vec2}
|
|
213
|
+
*/
|
|
214
|
+
static sub(a, b) {
|
|
215
|
+
return new Vec2(a.x - b.x, a.y - b.y);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* @method mul
|
|
220
|
+
* @description s * v as a new vector (either argument order works).
|
|
221
|
+
* @param {number|Object} a
|
|
222
|
+
* @param {number|Object} b
|
|
223
|
+
* @returns {Vec2}
|
|
224
|
+
*/
|
|
225
|
+
static mul(a, b) {
|
|
226
|
+
if (typeof a === "number") return new Vec2(a * b.x, a * b.y);
|
|
227
|
+
return new Vec2(a.x * b, a.y * b);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @method combine
|
|
232
|
+
* @description sa * a + sb * b as a new vector.
|
|
233
|
+
* @param {number} sa
|
|
234
|
+
* @param {Object} a
|
|
235
|
+
* @param {number} sb
|
|
236
|
+
* @param {Object} b
|
|
237
|
+
* @returns {Vec2}
|
|
238
|
+
*/
|
|
239
|
+
static combine(sa, a, sb, b) {
|
|
240
|
+
return new Vec2(sa * a.x + sb * b.x, sa * a.y + sb * b.y);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @method neg
|
|
245
|
+
* @description -v as a new vector.
|
|
246
|
+
* @param {Object} v
|
|
247
|
+
* @returns {Vec2}
|
|
248
|
+
*/
|
|
249
|
+
static neg(v) {
|
|
250
|
+
return new Vec2(-v.x, -v.y);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @method dot
|
|
255
|
+
* @description Dot product.
|
|
256
|
+
* @param {Object} a
|
|
257
|
+
* @param {Object} b
|
|
258
|
+
* @returns {number}
|
|
259
|
+
*/
|
|
260
|
+
static dot(a, b) {
|
|
261
|
+
return a.x * b.x + a.y * b.y;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @method cross
|
|
266
|
+
* @description 2D cross product (the z of the 3D cross): a.x*b.y - a.y*b.x.
|
|
267
|
+
* @param {Object} a
|
|
268
|
+
* @param {Object} b
|
|
269
|
+
* @returns {number}
|
|
270
|
+
*/
|
|
271
|
+
static cross(a, b) {
|
|
272
|
+
return a.x * b.y - a.y * b.x;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @method crossVS
|
|
277
|
+
* @description Cross of a vector with a scalar: (v.y * s, -v.x * s).
|
|
278
|
+
* @param {Object} v
|
|
279
|
+
* @param {number} s
|
|
280
|
+
* @returns {Vec2}
|
|
281
|
+
*/
|
|
282
|
+
static crossVS(v, s) {
|
|
283
|
+
return new Vec2(s * v.y, -s * v.x);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* @method crossSV
|
|
288
|
+
* @description Cross of a scalar with a vector: (-s * v.y, s * v.x). This is
|
|
289
|
+
* how angular velocity turns into linear velocity at an offset.
|
|
290
|
+
* @param {number} s
|
|
291
|
+
* @param {Object} v
|
|
292
|
+
* @returns {Vec2}
|
|
293
|
+
*/
|
|
294
|
+
static crossSV(s, v) {
|
|
295
|
+
return new Vec2(-s * v.y, s * v.x);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @method distance
|
|
300
|
+
* @description Distance between two points.
|
|
301
|
+
* @param {Object} a
|
|
302
|
+
* @param {Object} b
|
|
303
|
+
* @returns {number}
|
|
304
|
+
*/
|
|
305
|
+
static distance(a, b) {
|
|
306
|
+
const dx = a.x - b.x;
|
|
307
|
+
const dy = a.y - b.y;
|
|
308
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* @method distanceSquared
|
|
313
|
+
* @description Squared distance between two points.
|
|
314
|
+
* @param {Object} a
|
|
315
|
+
* @param {Object} b
|
|
316
|
+
* @returns {number}
|
|
317
|
+
*/
|
|
318
|
+
static distanceSquared(a, b) {
|
|
319
|
+
const dx = a.x - b.x;
|
|
320
|
+
const dy = a.y - b.y;
|
|
321
|
+
return dx * dx + dy * dy;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* @method lerp
|
|
326
|
+
* @description Linear interpolation between two points.
|
|
327
|
+
* @param {Object} a
|
|
328
|
+
* @param {Object} b
|
|
329
|
+
* @param {number} t
|
|
330
|
+
* @returns {Vec2}
|
|
331
|
+
*/
|
|
332
|
+
static lerp(a, b, t) {
|
|
333
|
+
return new Vec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* @class Rot
|
|
339
|
+
* @description A 2D rotation stored as sine/cosine, so rotating a vector never
|
|
340
|
+
* needs a trig call in the inner loop.
|
|
341
|
+
* @param {number} [angle=0] - Angle in radians
|
|
342
|
+
*/
|
|
343
|
+
class Rot {
|
|
344
|
+
constructor(angle = 0) {
|
|
345
|
+
this.s = Math.sin(angle);
|
|
346
|
+
this.c = Math.cos(angle);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @method set
|
|
351
|
+
* @description Sets the rotation from an angle in radians.
|
|
352
|
+
* @param {number} angle
|
|
353
|
+
* @returns {Rot} - this
|
|
354
|
+
*/
|
|
355
|
+
set(angle) {
|
|
356
|
+
this.s = Math.sin(angle);
|
|
357
|
+
this.c = Math.cos(angle);
|
|
358
|
+
return this;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* @method copy
|
|
363
|
+
* @description Copies another rotation.
|
|
364
|
+
* @param {Rot} r
|
|
365
|
+
* @returns {Rot} - this
|
|
366
|
+
*/
|
|
367
|
+
copy(r) {
|
|
368
|
+
this.s = r.s;
|
|
369
|
+
this.c = r.c;
|
|
370
|
+
return this;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* @method setIdentity
|
|
375
|
+
* @description Resets to zero rotation.
|
|
376
|
+
* @returns {Rot} - this
|
|
377
|
+
*/
|
|
378
|
+
setIdentity() {
|
|
379
|
+
this.s = 0;
|
|
380
|
+
this.c = 1;
|
|
381
|
+
return this;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* @method getAngle
|
|
386
|
+
* @description Returns the angle in radians.
|
|
387
|
+
* @returns {number}
|
|
388
|
+
*/
|
|
389
|
+
getAngle() {
|
|
390
|
+
return Math.atan2(this.s, this.c);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* @method mulVec
|
|
395
|
+
* @description Rotates a vector by `q` into a new vector.
|
|
396
|
+
* @param {Rot} q
|
|
397
|
+
* @param {Object} v
|
|
398
|
+
* @returns {Vec2}
|
|
399
|
+
*/
|
|
400
|
+
static mulVec(q, v) {
|
|
401
|
+
return new Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* @method mulTVec
|
|
406
|
+
* @description Inverse-rotates a vector by `q` (world direction -> local).
|
|
407
|
+
* @param {Rot} q
|
|
408
|
+
* @param {Object} v
|
|
409
|
+
* @returns {Vec2}
|
|
410
|
+
*/
|
|
411
|
+
static mulTVec(q, v) {
|
|
412
|
+
return new Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* @class Transform2
|
|
418
|
+
* @description A rigid transform: a translation `p` plus a rotation `q`. Named
|
|
419
|
+
* Transform2 so it never collides with the engine's renderable `Transform`.
|
|
420
|
+
*/
|
|
421
|
+
class Transform2 {
|
|
422
|
+
constructor() {
|
|
423
|
+
this.p = new Vec2();
|
|
424
|
+
this.q = new Rot();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* @method setIdentity
|
|
429
|
+
* @description Resets to the identity transform.
|
|
430
|
+
* @returns {Transform2} - this
|
|
431
|
+
*/
|
|
432
|
+
setIdentity() {
|
|
433
|
+
this.p.setZero();
|
|
434
|
+
this.q.setIdentity();
|
|
435
|
+
return this;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* @method set
|
|
440
|
+
* @description Sets position and angle.
|
|
441
|
+
* @param {Object} position
|
|
442
|
+
* @param {number} angle
|
|
443
|
+
* @returns {Transform2} - this
|
|
444
|
+
*/
|
|
445
|
+
set(position, angle) {
|
|
446
|
+
this.p.copy(position);
|
|
447
|
+
this.q.set(angle);
|
|
448
|
+
return this;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* @method copy
|
|
453
|
+
* @description Copies another transform.
|
|
454
|
+
* @param {Transform2} xf
|
|
455
|
+
* @returns {Transform2} - this
|
|
456
|
+
*/
|
|
457
|
+
copy(xf) {
|
|
458
|
+
this.p.copy(xf.p);
|
|
459
|
+
this.q.copy(xf.q);
|
|
460
|
+
return this;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* @method mulVec
|
|
465
|
+
* @description Transforms a local point into world space.
|
|
466
|
+
* @param {Transform2} xf
|
|
467
|
+
* @param {Object} v
|
|
468
|
+
* @returns {Vec2}
|
|
469
|
+
*/
|
|
470
|
+
static mulVec(xf, v) {
|
|
471
|
+
return new Vec2(
|
|
472
|
+
xf.q.c * v.x - xf.q.s * v.y + xf.p.x,
|
|
473
|
+
xf.q.s * v.x + xf.q.c * v.y + xf.p.y
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* @method mulTVec
|
|
479
|
+
* @description Transforms a world point into local space.
|
|
480
|
+
* @param {Transform2} xf
|
|
481
|
+
* @param {Object} v
|
|
482
|
+
* @returns {Vec2}
|
|
483
|
+
*/
|
|
484
|
+
static mulTVec(xf, v) {
|
|
485
|
+
const px = v.x - xf.p.x;
|
|
486
|
+
const py = v.y - xf.p.y;
|
|
487
|
+
return new Vec2(xf.q.c * px + xf.q.s * py, -xf.q.s * px + xf.q.c * py);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* @class Sweep
|
|
493
|
+
* @description The motion of a body's center of mass across one step, used by
|
|
494
|
+
* continuous collision detection to reconstruct where the body was at any
|
|
495
|
+
* fraction of the step.
|
|
496
|
+
*/
|
|
497
|
+
class Sweep {
|
|
498
|
+
constructor() {
|
|
499
|
+
/** Local center of mass */
|
|
500
|
+
this.localCenter = new Vec2();
|
|
501
|
+
/** World center at the start of the step */
|
|
502
|
+
this.c0 = new Vec2();
|
|
503
|
+
/** World center now */
|
|
504
|
+
this.c = new Vec2();
|
|
505
|
+
/** Angle at the start of the step */
|
|
506
|
+
this.a0 = 0;
|
|
507
|
+
/** Angle now */
|
|
508
|
+
this.a = 0;
|
|
509
|
+
/** Fraction of the step `c0`/`a0` correspond to (0..1) */
|
|
510
|
+
this.alpha0 = 0;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* @method getTransform
|
|
515
|
+
* @description Writes the body transform at fraction `beta` of the sweep into
|
|
516
|
+
* `xf`. beta 0 is the start of the (remaining) sweep, 1 is the end.
|
|
517
|
+
* @param {Transform2} xf - Output transform
|
|
518
|
+
* @param {number} beta - Interpolation fraction
|
|
519
|
+
* @returns {Transform2} - xf
|
|
520
|
+
*/
|
|
521
|
+
getTransform(xf, beta) {
|
|
522
|
+
const angle = (1 - beta) * this.a0 + beta * this.a;
|
|
523
|
+
xf.q.set(angle);
|
|
524
|
+
xf.p.x = (1 - beta) * this.c0.x + beta * this.c.x;
|
|
525
|
+
xf.p.y = (1 - beta) * this.c0.y + beta * this.c.y;
|
|
526
|
+
xf.p.x -= xf.q.c * this.localCenter.x - xf.q.s * this.localCenter.y;
|
|
527
|
+
xf.p.y -= xf.q.s * this.localCenter.x + xf.q.c * this.localCenter.y;
|
|
528
|
+
return xf;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* @method advance
|
|
533
|
+
* @description Moves the start of the sweep forward to fraction `alpha` of
|
|
534
|
+
* the original span, so later TOI queries only consider the remaining motion.
|
|
535
|
+
* @param {number} alpha - Absolute fraction of the original sweep
|
|
536
|
+
*/
|
|
537
|
+
advance(alpha) {
|
|
538
|
+
const beta = (alpha - this.alpha0) / (1 - this.alpha0);
|
|
539
|
+
this.c0.x += beta * (this.c.x - this.c0.x);
|
|
540
|
+
this.c0.y += beta * (this.c.y - this.c0.y);
|
|
541
|
+
this.a0 += beta * (this.a - this.a0);
|
|
542
|
+
this.alpha0 = alpha;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* @method normalize
|
|
547
|
+
* @description Keeps the sweep angles near zero so long-lived spinning bodies
|
|
548
|
+
* don't lose float precision.
|
|
549
|
+
*/
|
|
550
|
+
normalize() {
|
|
551
|
+
const twoPi = 2 * Math.PI;
|
|
552
|
+
const d = twoPi * Math.floor(this.a0 / twoPi);
|
|
553
|
+
this.a0 -= d;
|
|
554
|
+
this.a -= d;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const EPSILON = 1.1920929e-7;
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* @function clamp
|
|
562
|
+
* @description Clamps a number to [min, max].
|
|
563
|
+
* @param {number} value
|
|
564
|
+
* @param {number} min
|
|
565
|
+
* @param {number} max
|
|
566
|
+
* @returns {number}
|
|
567
|
+
* @private
|
|
568
|
+
*/
|
|
569
|
+
function clamp(value, min, max) {
|
|
570
|
+
return value < min ? min : value > max ? max : value;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
export { Vec2, Rot, Transform2, Sweep, clamp, EPSILON };
|