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,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class BroadPhase
|
|
3
|
+
* @description Keeps the AABB tree and the list of proxies that moved since the
|
|
4
|
+
* last step, and turns those into the candidate pairs the narrowphase looks at.
|
|
5
|
+
*/
|
|
6
|
+
export class BroadPhase {
|
|
7
|
+
/** @private */
|
|
8
|
+
private tree;
|
|
9
|
+
/** @private */
|
|
10
|
+
private moveBuffer;
|
|
11
|
+
/** @private */
|
|
12
|
+
private proxyCount;
|
|
13
|
+
/**
|
|
14
|
+
* @method createProxy
|
|
15
|
+
* @description Adds a fixture proxy and queues it for pairing.
|
|
16
|
+
* @param {AABB} aabb
|
|
17
|
+
* @param {Object} userData
|
|
18
|
+
* @returns {number} - Proxy id
|
|
19
|
+
*/
|
|
20
|
+
createProxy(aabb: AABB, userData: any): number;
|
|
21
|
+
/**
|
|
22
|
+
* @method destroyProxy
|
|
23
|
+
* @description Removes a fixture proxy.
|
|
24
|
+
* @param {number} id
|
|
25
|
+
*/
|
|
26
|
+
destroyProxy(id: number): void;
|
|
27
|
+
/**
|
|
28
|
+
* @method moveProxy
|
|
29
|
+
* @description Updates a proxy's box, queueing it for re-pairing if the tree
|
|
30
|
+
* actually had to move it.
|
|
31
|
+
* @param {number} id
|
|
32
|
+
* @param {AABB} aabb
|
|
33
|
+
* @param {Object} displacement
|
|
34
|
+
*/
|
|
35
|
+
moveProxy(id: number, aabb: AABB, displacement: any): void;
|
|
36
|
+
/**
|
|
37
|
+
* @method touchProxy
|
|
38
|
+
* @description Forces a proxy to be re-paired next update even though it
|
|
39
|
+
* didn't move (used when a fixture's filter changes).
|
|
40
|
+
* @param {number} id
|
|
41
|
+
*/
|
|
42
|
+
touchProxy(id: number): void;
|
|
43
|
+
/** @private */
|
|
44
|
+
private bufferMove;
|
|
45
|
+
/** @private */
|
|
46
|
+
private unbufferMove;
|
|
47
|
+
/**
|
|
48
|
+
* @method getFatAABB
|
|
49
|
+
* @description Returns a proxy's fattened AABB.
|
|
50
|
+
* @param {number} id
|
|
51
|
+
* @returns {AABB}
|
|
52
|
+
*/
|
|
53
|
+
getFatAABB(id: number): AABB;
|
|
54
|
+
/**
|
|
55
|
+
* @method getUserData
|
|
56
|
+
* @description Returns a proxy's payload.
|
|
57
|
+
* @param {number} id
|
|
58
|
+
* @returns {Object}
|
|
59
|
+
*/
|
|
60
|
+
getUserData(id: number): any;
|
|
61
|
+
/**
|
|
62
|
+
* @method testOverlap
|
|
63
|
+
* @description True when two proxies' fat AABBs overlap.
|
|
64
|
+
* @param {number} idA
|
|
65
|
+
* @param {number} idB
|
|
66
|
+
* @returns {boolean}
|
|
67
|
+
*/
|
|
68
|
+
testOverlap(idA: number, idB: number): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* @method query
|
|
71
|
+
* @description Forwards an AABB query to the tree.
|
|
72
|
+
* @param {AABB} aabb
|
|
73
|
+
* @param {Function} callback
|
|
74
|
+
*/
|
|
75
|
+
query(aabb: AABB, callback: Function): void;
|
|
76
|
+
/**
|
|
77
|
+
* @method rayCast
|
|
78
|
+
* @description Forwards a ray cast to the tree.
|
|
79
|
+
* @param {Object} input
|
|
80
|
+
* @param {Function} callback
|
|
81
|
+
*/
|
|
82
|
+
rayCast(input: any, callback: Function): void;
|
|
83
|
+
/**
|
|
84
|
+
* @method updatePairs
|
|
85
|
+
* @description Emits `callback(userDataA, userDataB)` once for every new
|
|
86
|
+
* overlapping pair among the proxies that moved. Pairs are de-duplicated, so
|
|
87
|
+
* two proxies moving towards each other still report once.
|
|
88
|
+
* @param {Function} callback
|
|
89
|
+
*/
|
|
90
|
+
updatePairs(callback: Function): void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @class DynamicTree
|
|
94
|
+
* @description A balanced tree of axis-aligned boxes over every fixture in the
|
|
95
|
+
* world. Leaves are stored with a "fat" AABB so a body can jiggle a little
|
|
96
|
+
* without forcing a re-insert, and the tree is rebalanced with rotations on the
|
|
97
|
+
* way back up after each change. Every broadphase query, world raycast and
|
|
98
|
+
* continuous-collision sweep goes through it.
|
|
99
|
+
*/
|
|
100
|
+
export class DynamicTree {
|
|
101
|
+
/** @private */
|
|
102
|
+
private root;
|
|
103
|
+
/** @private */
|
|
104
|
+
private nodes;
|
|
105
|
+
/** @private */
|
|
106
|
+
private freeList;
|
|
107
|
+
/** @private */
|
|
108
|
+
private nodeCount;
|
|
109
|
+
/**
|
|
110
|
+
* @method allocateNode
|
|
111
|
+
* @description Takes a node from the free list, growing the pool if needed.
|
|
112
|
+
* @returns {number} - The node id
|
|
113
|
+
* @private
|
|
114
|
+
*/
|
|
115
|
+
private allocateNode;
|
|
116
|
+
/**
|
|
117
|
+
* @method freeNode
|
|
118
|
+
* @description Returns a node to the free list.
|
|
119
|
+
* @param {number} id
|
|
120
|
+
* @private
|
|
121
|
+
*/
|
|
122
|
+
private freeNode;
|
|
123
|
+
/**
|
|
124
|
+
* @method createProxy
|
|
125
|
+
* @description Adds a fixture proxy to the tree.
|
|
126
|
+
* @param {AABB} aabb - The tight world AABB
|
|
127
|
+
* @param {Object} userData - The FixtureProxy this leaf stands for
|
|
128
|
+
* @returns {number} - The proxy id
|
|
129
|
+
*/
|
|
130
|
+
createProxy(aabb: AABB, userData: any): number;
|
|
131
|
+
/**
|
|
132
|
+
* @method destroyProxy
|
|
133
|
+
* @description Removes a proxy from the tree.
|
|
134
|
+
* @param {number} id
|
|
135
|
+
*/
|
|
136
|
+
destroyProxy(id: number): void;
|
|
137
|
+
/**
|
|
138
|
+
* @method moveProxy
|
|
139
|
+
* @description Re-fits a proxy whose fixture moved. Returns false (and does
|
|
140
|
+
* nothing) while the new box still fits inside the fat one.
|
|
141
|
+
* @param {number} id
|
|
142
|
+
* @param {AABB} aabb - The new tight AABB
|
|
143
|
+
* @param {Object} displacement - How far the body moved this step
|
|
144
|
+
* @returns {boolean} - Whether the proxy was actually re-inserted
|
|
145
|
+
*/
|
|
146
|
+
moveProxy(id: number, aabb: AABB, displacement: any): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* @method getFatAABB
|
|
149
|
+
* @description Returns the stored (fattened) AABB of a proxy.
|
|
150
|
+
* @param {number} id
|
|
151
|
+
* @returns {AABB}
|
|
152
|
+
*/
|
|
153
|
+
getFatAABB(id: number): AABB;
|
|
154
|
+
/**
|
|
155
|
+
* @method getUserData
|
|
156
|
+
* @description Returns the proxy payload of a leaf.
|
|
157
|
+
* @param {number} id
|
|
158
|
+
* @returns {Object}
|
|
159
|
+
*/
|
|
160
|
+
getUserData(id: number): any;
|
|
161
|
+
/**
|
|
162
|
+
* @method insertLeaf
|
|
163
|
+
* @description Inserts a leaf, choosing the sibling that grows the tree's
|
|
164
|
+
* total surface area least, then rebalancing on the way back to the root.
|
|
165
|
+
* @param {number} leaf
|
|
166
|
+
* @private
|
|
167
|
+
*/
|
|
168
|
+
private insertLeaf;
|
|
169
|
+
/**
|
|
170
|
+
* @method removeLeaf
|
|
171
|
+
* @description Unlinks a leaf and collapses its now-single-child parent.
|
|
172
|
+
* @param {number} leaf
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
private removeLeaf;
|
|
176
|
+
/**
|
|
177
|
+
* @method balance
|
|
178
|
+
* @description One AVL-style rotation at `iA` if its subtrees differ in
|
|
179
|
+
* height by more than one. Keeps queries logarithmic.
|
|
180
|
+
* @param {number} iA
|
|
181
|
+
* @returns {number} - The new root of that subtree
|
|
182
|
+
* @private
|
|
183
|
+
*/
|
|
184
|
+
private balance;
|
|
185
|
+
/**
|
|
186
|
+
* @method query
|
|
187
|
+
* @description Calls `callback(proxyId)` for every leaf whose fat AABB
|
|
188
|
+
* overlaps `aabb`. Returning false from the callback stops the query.
|
|
189
|
+
* @param {AABB} aabb
|
|
190
|
+
* @param {Function} callback
|
|
191
|
+
*/
|
|
192
|
+
query(aabb: AABB, callback: Function): void;
|
|
193
|
+
/**
|
|
194
|
+
* @method rayCast
|
|
195
|
+
* @description Walks the tree along a ray, calling
|
|
196
|
+
* `callback(subInput, proxyId)`. The callback returns the new max fraction
|
|
197
|
+
* (0 terminates the cast), which lets the traversal shrink as it finds hits.
|
|
198
|
+
* @param {Object} input - `{ p1, p2, maxFraction }`
|
|
199
|
+
* @param {Function} callback
|
|
200
|
+
*/
|
|
201
|
+
rayCast(input: any, callback: Function): void;
|
|
202
|
+
/**
|
|
203
|
+
* @method getHeight
|
|
204
|
+
* @description Height of the tree (0 when empty), useful when profiling.
|
|
205
|
+
* @returns {number}
|
|
206
|
+
*/
|
|
207
|
+
getHeight(): number;
|
|
208
|
+
}
|
|
209
|
+
export const NULL_NODE: -1;
|
|
210
|
+
import AABB from "./AABB.js";
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class Manifold
|
|
3
|
+
* @description Up to two contact points plus the frame they are expressed in.
|
|
4
|
+
* Two points is all a 2D convex-convex overlap can produce, and it is exactly
|
|
5
|
+
* what a stable resting contact (a box on the ground) needs.
|
|
6
|
+
*/
|
|
7
|
+
export class Manifold {
|
|
8
|
+
type: number;
|
|
9
|
+
localNormal: Vec2;
|
|
10
|
+
localPoint: Vec2;
|
|
11
|
+
points: ManifoldPoint[];
|
|
12
|
+
pointCount: number;
|
|
13
|
+
/**
|
|
14
|
+
* @method reset
|
|
15
|
+
* @description Empties the manifold.
|
|
16
|
+
*/
|
|
17
|
+
reset(): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @class ManifoldPoint
|
|
21
|
+
* @description A single contact point, stored in the reference body's local
|
|
22
|
+
* frame so it stays valid as the bodies move within a step.
|
|
23
|
+
*/
|
|
24
|
+
export class ManifoldPoint {
|
|
25
|
+
localPoint: Vec2;
|
|
26
|
+
normalImpulse: number;
|
|
27
|
+
tangentImpulse: number;
|
|
28
|
+
id: number;
|
|
29
|
+
}
|
|
30
|
+
export type ManifoldType = ManifoldType;
|
|
31
|
+
export namespace ManifoldType {
|
|
32
|
+
let CIRCLES: number;
|
|
33
|
+
let FACE_A: number;
|
|
34
|
+
let FACE_B: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @class WorldManifold
|
|
38
|
+
* @description A manifold converted into world space: the collision normal
|
|
39
|
+
* (always pointing from body A to body B), the contact points, and how deeply
|
|
40
|
+
* each one is penetrating (negative means overlapping).
|
|
41
|
+
*/
|
|
42
|
+
export class WorldManifold {
|
|
43
|
+
normal: Vec2;
|
|
44
|
+
points: Vec2[];
|
|
45
|
+
separations: number[];
|
|
46
|
+
pointCount: number;
|
|
47
|
+
/**
|
|
48
|
+
* @method initialize
|
|
49
|
+
* @description Fills this world manifold from a local manifold.
|
|
50
|
+
* @param {Manifold} manifold
|
|
51
|
+
* @param {Transform2} xfA
|
|
52
|
+
* @param {number} radiusA
|
|
53
|
+
* @param {Transform2} xfB
|
|
54
|
+
* @param {number} radiusB
|
|
55
|
+
* @returns {WorldManifold} - this
|
|
56
|
+
*/
|
|
57
|
+
initialize(manifold: Manifold, xfA: Transform2, radiusA: number, xfB: Transform2, radiusB: number): WorldManifold;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @function collideCircles
|
|
61
|
+
* @description Builds the manifold for two circles.
|
|
62
|
+
* @param {Manifold} manifold - Output manifold
|
|
63
|
+
* @param {CircleShape} circleA
|
|
64
|
+
* @param {Transform2} xfA
|
|
65
|
+
* @param {CircleShape} circleB
|
|
66
|
+
* @param {Transform2} xfB
|
|
67
|
+
*/
|
|
68
|
+
export function collideCircles(manifold: Manifold, circleA: CircleShape, xfA: Transform2, circleB: CircleShape, xfB: Transform2): void;
|
|
69
|
+
/**
|
|
70
|
+
* @function collidePolygonAndCircle
|
|
71
|
+
* @description Builds the manifold for a polygon against a circle. The circle
|
|
72
|
+
* is pushed into the polygon's frame, then tested against the closest face,
|
|
73
|
+
* falling back to the nearest corner when it sits past the face's edge.
|
|
74
|
+
* @param {Manifold} manifold - Output manifold
|
|
75
|
+
* @param {PolygonShape} polygonA
|
|
76
|
+
* @param {Transform2} xfA
|
|
77
|
+
* @param {CircleShape} circleB
|
|
78
|
+
* @param {Transform2} xfB
|
|
79
|
+
*/
|
|
80
|
+
export function collidePolygonAndCircle(manifold: Manifold, polygonA: PolygonShape, xfA: Transform2, circleB: CircleShape, xfB: Transform2): void;
|
|
81
|
+
/**
|
|
82
|
+
* @function collidePolygons
|
|
83
|
+
* @description Builds the manifold for two convex polygons using the
|
|
84
|
+
* separating-axis test to pick a reference face, then clipping the opposing
|
|
85
|
+
* (incident) edge against it. The result is the one- or two-point contact patch
|
|
86
|
+
* that makes boxes rest flat instead of rocking.
|
|
87
|
+
* @param {Manifold} manifold - Output manifold
|
|
88
|
+
* @param {PolygonShape} polyA
|
|
89
|
+
* @param {Transform2} xfA
|
|
90
|
+
* @param {PolygonShape} polyB
|
|
91
|
+
* @param {Transform2} xfB
|
|
92
|
+
*/
|
|
93
|
+
export function collidePolygons(manifold: Manifold, polyA: PolygonShape, xfA: Transform2, polyB: PolygonShape, xfB: Transform2): void;
|
|
94
|
+
/**
|
|
95
|
+
* @function mulTXf
|
|
96
|
+
* @description Composes transforms: returns the transform of `B` expressed in
|
|
97
|
+
* `A`'s frame.
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
100
|
+
export function mulTXf(A: any, B: any): Transform2;
|
|
101
|
+
import { Vec2 } from "./Math2D.js";
|
|
102
|
+
import { Transform2 } from "./Math2D.js";
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class Contact
|
|
3
|
+
* @description A potential or actual touch between two fixtures. The broadphase
|
|
4
|
+
* creates one as soon as two AABBs overlap; `touching` only becomes true once
|
|
5
|
+
* the narrowphase finds real contact points. Contacts persist across steps,
|
|
6
|
+
* which is what lets the solver warm-start from last frame's impulses.
|
|
7
|
+
*/
|
|
8
|
+
export class Contact {
|
|
9
|
+
/**
|
|
10
|
+
* @method create
|
|
11
|
+
* @description Builds a contact for a fixture pair, normalizing the order so
|
|
12
|
+
* mixed polygon/circle pairs always arrive as (polygon, circle): the one
|
|
13
|
+
* ordering the narrowphase implements.
|
|
14
|
+
* @param {Fixture} fixtureA
|
|
15
|
+
* @param {Fixture} fixtureB
|
|
16
|
+
* @returns {Contact}
|
|
17
|
+
*/
|
|
18
|
+
static create(fixtureA: Fixture, fixtureB: Fixture): Contact;
|
|
19
|
+
constructor(fixtureA: any, fixtureB: any);
|
|
20
|
+
fixtureA: any;
|
|
21
|
+
fixtureB: any;
|
|
22
|
+
manifold: Manifold;
|
|
23
|
+
friction: number;
|
|
24
|
+
restitution: any;
|
|
25
|
+
tangentSpeed: number;
|
|
26
|
+
/** @private */
|
|
27
|
+
private touching;
|
|
28
|
+
/** @private */
|
|
29
|
+
private enabled;
|
|
30
|
+
/** @private */
|
|
31
|
+
private filterFlag;
|
|
32
|
+
/** @private */
|
|
33
|
+
private islandFlag;
|
|
34
|
+
/** @private */
|
|
35
|
+
private toiFlag;
|
|
36
|
+
/** @private */
|
|
37
|
+
private toi;
|
|
38
|
+
/** @private */
|
|
39
|
+
private _index;
|
|
40
|
+
/**
|
|
41
|
+
* @method getManifold
|
|
42
|
+
* @description Returns the local-space manifold.
|
|
43
|
+
* @returns {Manifold}
|
|
44
|
+
*/
|
|
45
|
+
getManifold(): Manifold;
|
|
46
|
+
/**
|
|
47
|
+
* @method getWorldManifold
|
|
48
|
+
* @description Returns the contact in world space: the normal (pointing from
|
|
49
|
+
* fixture A's body towards fixture B's), the contact points, and the
|
|
50
|
+
* separation at each point.
|
|
51
|
+
* @param {WorldManifold} [worldManifold] - Optional object to fill
|
|
52
|
+
* @returns {WorldManifold}
|
|
53
|
+
*/
|
|
54
|
+
getWorldManifold(worldManifold?: WorldManifold): WorldManifold;
|
|
55
|
+
/**
|
|
56
|
+
* @method isTouching
|
|
57
|
+
* @description Whether the fixtures are actually in contact this step.
|
|
58
|
+
* @returns {boolean}
|
|
59
|
+
*/
|
|
60
|
+
isTouching(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* @method setEnabled
|
|
63
|
+
* @description Enables or disables the collision response for this contact.
|
|
64
|
+
* Disabling only lasts for the current step (useful from a pre-solve
|
|
65
|
+
* callback to build one-way platforms).
|
|
66
|
+
* @param {boolean} value
|
|
67
|
+
*/
|
|
68
|
+
setEnabled(value: boolean): void;
|
|
69
|
+
/**
|
|
70
|
+
* @method isEnabled
|
|
71
|
+
* @description Whether the collision response is enabled.
|
|
72
|
+
* @returns {boolean}
|
|
73
|
+
*/
|
|
74
|
+
isEnabled(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* @method getFixtureA
|
|
77
|
+
* @description Returns the first fixture.
|
|
78
|
+
* @returns {Fixture}
|
|
79
|
+
*/
|
|
80
|
+
getFixtureA(): Fixture;
|
|
81
|
+
/**
|
|
82
|
+
* @method getFixtureB
|
|
83
|
+
* @description Returns the second fixture.
|
|
84
|
+
* @returns {Fixture}
|
|
85
|
+
*/
|
|
86
|
+
getFixtureB(): Fixture;
|
|
87
|
+
/**
|
|
88
|
+
* @method getFriction
|
|
89
|
+
* @description Returns the mixed friction used by the solver.
|
|
90
|
+
* @returns {number}
|
|
91
|
+
*/
|
|
92
|
+
getFriction(): number;
|
|
93
|
+
/**
|
|
94
|
+
* @method setFriction
|
|
95
|
+
* @description Overrides the mixed friction for this contact.
|
|
96
|
+
* @param {number} friction
|
|
97
|
+
*/
|
|
98
|
+
setFriction(friction: number): void;
|
|
99
|
+
/**
|
|
100
|
+
* @method resetFriction
|
|
101
|
+
* @description Restores the friction mixed from the two fixtures.
|
|
102
|
+
*/
|
|
103
|
+
resetFriction(): void;
|
|
104
|
+
/**
|
|
105
|
+
* @method getRestitution
|
|
106
|
+
* @description Returns the mixed restitution used by the solver.
|
|
107
|
+
* @returns {number}
|
|
108
|
+
*/
|
|
109
|
+
getRestitution(): number;
|
|
110
|
+
/**
|
|
111
|
+
* @method setRestitution
|
|
112
|
+
* @description Overrides the mixed restitution for this contact.
|
|
113
|
+
* @param {number} restitution
|
|
114
|
+
*/
|
|
115
|
+
setRestitution(restitution: number): void;
|
|
116
|
+
/**
|
|
117
|
+
* @method resetRestitution
|
|
118
|
+
* @description Restores the restitution mixed from the two fixtures.
|
|
119
|
+
*/
|
|
120
|
+
resetRestitution(): void;
|
|
121
|
+
/**
|
|
122
|
+
* @method flagForFiltering
|
|
123
|
+
* @description Marks the contact so the next step re-checks whether these two
|
|
124
|
+
* fixtures are still allowed to collide.
|
|
125
|
+
*/
|
|
126
|
+
flagForFiltering(): void;
|
|
127
|
+
/**
|
|
128
|
+
* @method evaluate
|
|
129
|
+
* @description Runs the narrowphase for this fixture pair into `manifold`.
|
|
130
|
+
* @param {Manifold} manifold
|
|
131
|
+
* @param {Transform2} xfA
|
|
132
|
+
* @param {Transform2} xfB
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
private evaluate;
|
|
136
|
+
/**
|
|
137
|
+
* @method update
|
|
138
|
+
* @description Re-runs the narrowphase, carries last step's impulses over to
|
|
139
|
+
* matching contact points (warm starting), and fires begin/end contact
|
|
140
|
+
* events on the world when the touching state flips.
|
|
141
|
+
* @param {World} world - The owning world, used to dispatch events
|
|
142
|
+
*/
|
|
143
|
+
update(world: World): void;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* @class ContactManager
|
|
147
|
+
* @description Owns the world's contact list: creates contacts from broadphase
|
|
148
|
+
* pairs, drops them once the AABBs stop overlapping, and refreshes the ones
|
|
149
|
+
* that remain each step.
|
|
150
|
+
*/
|
|
151
|
+
export class ContactManager {
|
|
152
|
+
constructor(world: any);
|
|
153
|
+
world: any;
|
|
154
|
+
contacts: any[];
|
|
155
|
+
/**
|
|
156
|
+
* @method addPair
|
|
157
|
+
* @description Creates a contact for a new broadphase pair, unless the two
|
|
158
|
+
* fixtures share a body, already have a contact, or the filter rejects them.
|
|
159
|
+
* @param {FixtureProxy} proxyA
|
|
160
|
+
* @param {FixtureProxy} proxyB
|
|
161
|
+
*/
|
|
162
|
+
addPair(proxyA: FixtureProxy, proxyB: FixtureProxy): void;
|
|
163
|
+
/**
|
|
164
|
+
* @method findNewContacts
|
|
165
|
+
* @description Turns this step's broadphase movement into new contacts.
|
|
166
|
+
*/
|
|
167
|
+
findNewContacts(): void;
|
|
168
|
+
/**
|
|
169
|
+
* @method destroy
|
|
170
|
+
* @description Removes a contact, firing end-contact if it was touching.
|
|
171
|
+
* @param {Contact} contact
|
|
172
|
+
*/
|
|
173
|
+
destroy(contact: Contact): void;
|
|
174
|
+
/**
|
|
175
|
+
* @method collide
|
|
176
|
+
* @description Refreshes every contact: drops the ones whose AABBs no longer
|
|
177
|
+
* overlap or whose filters changed, and re-runs the narrowphase on the rest.
|
|
178
|
+
*/
|
|
179
|
+
collide(): void;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* @function shouldCollide
|
|
183
|
+
* @description Applies the collision filter to a fixture pair. A positive
|
|
184
|
+
* shared group index always collides, a negative one never does; otherwise each
|
|
185
|
+
* fixture's category must appear in the other's mask.
|
|
186
|
+
* @param {Fixture} fixtureA
|
|
187
|
+
* @param {Fixture} fixtureB
|
|
188
|
+
* @returns {boolean}
|
|
189
|
+
*/
|
|
190
|
+
export function shouldCollide(fixtureA: Fixture, fixtureB: Fixture): boolean;
|
|
191
|
+
/**
|
|
192
|
+
* @function mixFriction
|
|
193
|
+
* @description Combines two friction coefficients (geometric mean), so a slick
|
|
194
|
+
* body sliding on a rough one lands somewhere in between.
|
|
195
|
+
* @private
|
|
196
|
+
*/
|
|
197
|
+
export function mixFriction(a: any, b: any): number;
|
|
198
|
+
/**
|
|
199
|
+
* @function mixRestitution
|
|
200
|
+
* @description Combines two restitutions: the bouncier surface wins, which is
|
|
201
|
+
* what players expect from a trampoline on concrete.
|
|
202
|
+
* @private
|
|
203
|
+
*/
|
|
204
|
+
export function mixRestitution(a: any, b: any): any;
|
|
205
|
+
import { Manifold } from "./Collision.js";
|
|
206
|
+
import { WorldManifold } from "./Collision.js";
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export default ContactSolver;
|
|
2
|
+
/**
|
|
3
|
+
* @class ContactSolver
|
|
4
|
+
* @description Resolves every contact in an island with sequential impulses:
|
|
5
|
+
* for each contact point it works out the impulse that removes the approaching
|
|
6
|
+
* velocity (plus any bounce), applies it, and repeats over all points for a
|
|
7
|
+
* fixed number of iterations. Impulses are accumulated and clamped so they can
|
|
8
|
+
* only ever push, never pull, and they carry over between steps (warm starting)
|
|
9
|
+
* so stacks settle instead of sinking.
|
|
10
|
+
*
|
|
11
|
+
* Position error left over after the velocity pass is fixed separately, by
|
|
12
|
+
* nudging the bodies apart without injecting energy.
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} def - `{ contacts, positions, velocities, dt, velocityThreshold }`
|
|
15
|
+
*/
|
|
16
|
+
declare class ContactSolver {
|
|
17
|
+
constructor(def: any);
|
|
18
|
+
positions: any;
|
|
19
|
+
velocities: any;
|
|
20
|
+
contacts: any;
|
|
21
|
+
dt: any;
|
|
22
|
+
velocityThreshold: any;
|
|
23
|
+
velocityConstraints: {
|
|
24
|
+
friction: any;
|
|
25
|
+
restitution: any;
|
|
26
|
+
tangentSpeed: any;
|
|
27
|
+
indexA: any;
|
|
28
|
+
indexB: any;
|
|
29
|
+
invMassA: any;
|
|
30
|
+
invMassB: any;
|
|
31
|
+
invIA: any;
|
|
32
|
+
invIB: any;
|
|
33
|
+
contactIndex: number;
|
|
34
|
+
pointCount: any;
|
|
35
|
+
normal: Vec2;
|
|
36
|
+
tangent: Vec2;
|
|
37
|
+
K: {
|
|
38
|
+
k11: number;
|
|
39
|
+
k12: number;
|
|
40
|
+
k22: number;
|
|
41
|
+
};
|
|
42
|
+
normalMass: {
|
|
43
|
+
k11: number;
|
|
44
|
+
k12: number;
|
|
45
|
+
k22: number;
|
|
46
|
+
};
|
|
47
|
+
points: any[];
|
|
48
|
+
}[];
|
|
49
|
+
positionConstraints: {
|
|
50
|
+
indexA: any;
|
|
51
|
+
indexB: any;
|
|
52
|
+
invMassA: any;
|
|
53
|
+
invMassB: any;
|
|
54
|
+
invIA: any;
|
|
55
|
+
invIB: any;
|
|
56
|
+
localCenterA: any;
|
|
57
|
+
localCenterB: any;
|
|
58
|
+
radiusA: any;
|
|
59
|
+
radiusB: any;
|
|
60
|
+
type: any;
|
|
61
|
+
localNormal: any;
|
|
62
|
+
localPoint: any;
|
|
63
|
+
localPoints: any[];
|
|
64
|
+
pointCount: any;
|
|
65
|
+
}[];
|
|
66
|
+
/**
|
|
67
|
+
* @method initializeVelocityConstraints
|
|
68
|
+
* @description Computes the effective mass at every contact point and the
|
|
69
|
+
* bounce target, from the state at the start of the step.
|
|
70
|
+
*/
|
|
71
|
+
initializeVelocityConstraints(): void;
|
|
72
|
+
/**
|
|
73
|
+
* @method warmStart
|
|
74
|
+
* @description Re-applies last step's impulses before solving, which gets the
|
|
75
|
+
* solver most of the way to the answer immediately.
|
|
76
|
+
*/
|
|
77
|
+
warmStart(): void;
|
|
78
|
+
/**
|
|
79
|
+
* @method solveVelocityConstraints
|
|
80
|
+
* @description One relaxation pass over every contact point: friction first,
|
|
81
|
+
* then the normal impulses that stop the bodies interpenetrating.
|
|
82
|
+
*/
|
|
83
|
+
solveVelocityConstraints(): void;
|
|
84
|
+
/**
|
|
85
|
+
* @method _solveBlock
|
|
86
|
+
* @description Two-point block solve. Solving both points of a manifold
|
|
87
|
+
* together (rather than one after the other) is what keeps a box resting on
|
|
88
|
+
* the ground from rocking between its corners. Four candidate solutions are
|
|
89
|
+
* tried in turn: both points pushing, either one alone, or neither.
|
|
90
|
+
* @private
|
|
91
|
+
*/
|
|
92
|
+
private _solveBlock;
|
|
93
|
+
/**
|
|
94
|
+
* @method storeImpulses
|
|
95
|
+
* @description Writes the accumulated impulses back onto the manifold so the
|
|
96
|
+
* next step can warm-start from them.
|
|
97
|
+
*/
|
|
98
|
+
storeImpulses(): void;
|
|
99
|
+
/**
|
|
100
|
+
* @method solvePositionConstraints
|
|
101
|
+
* @description Pushes overlapping bodies apart geometrically. This runs on
|
|
102
|
+
* positions only, no velocity is added, so separating a deep overlap can't
|
|
103
|
+
* fling bodies across the level.
|
|
104
|
+
* @returns {boolean} - True once every overlap is within tolerance
|
|
105
|
+
*/
|
|
106
|
+
solvePositionConstraints(): boolean;
|
|
107
|
+
}
|
|
108
|
+
import { Vec2 } from "./Math2D.js";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class DistanceProxy
|
|
3
|
+
* @description A convex shape reduced to what GJK needs: a point cloud plus a
|
|
4
|
+
* skin radius. Circles collapse to a single point with a large radius; polygons
|
|
5
|
+
* keep their corners and carry the small polygon skin.
|
|
6
|
+
*/
|
|
7
|
+
export class DistanceProxy {
|
|
8
|
+
vertices: any[];
|
|
9
|
+
radius: number;
|
|
10
|
+
/**
|
|
11
|
+
* @method set
|
|
12
|
+
* @description Fills this proxy from a shape.
|
|
13
|
+
* @param {Shape} shape - A CircleShape or PolygonShape
|
|
14
|
+
* @returns {DistanceProxy} - this
|
|
15
|
+
*/
|
|
16
|
+
set(shape: Shape): DistanceProxy;
|
|
17
|
+
/**
|
|
18
|
+
* @method getSupport
|
|
19
|
+
* @description Index of the vertex furthest along a direction.
|
|
20
|
+
* @param {Object} d - Direction in the proxy's local frame
|
|
21
|
+
* @returns {number}
|
|
22
|
+
*/
|
|
23
|
+
getSupport(d: any): number;
|
|
24
|
+
/**
|
|
25
|
+
* @method getMaxExtent
|
|
26
|
+
* @description Distance from the local origin to the furthest vertex, plus
|
|
27
|
+
* the skin. Continuous collision uses it to bound how fast a rotating body's
|
|
28
|
+
* surface can approach another.
|
|
29
|
+
* @returns {number}
|
|
30
|
+
*/
|
|
31
|
+
getMaxExtent(): number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @function distance
|
|
35
|
+
* @description GJK: computes the distance and the closest points between two
|
|
36
|
+
* convex proxies. This is the primitive continuous collision and overlap tests
|
|
37
|
+
* are built on.
|
|
38
|
+
* @param {Object} output - Written as `{ distance, pointA, pointB, iterations }`
|
|
39
|
+
* @param {Object} input - `{ proxyA, proxyB, transformA, transformB, useRadii }`
|
|
40
|
+
* @returns {Object} - The same output object
|
|
41
|
+
*/
|
|
42
|
+
export function distance(output: any, input: any): any;
|
|
43
|
+
/**
|
|
44
|
+
* @function testOverlap
|
|
45
|
+
* @description True when two shapes overlap under their transforms. Sensors use
|
|
46
|
+
* this instead of building a manifold, since they never need contact points.
|
|
47
|
+
* @param {Shape} shapeA
|
|
48
|
+
* @param {Transform2} xfA
|
|
49
|
+
* @param {Shape} shapeB
|
|
50
|
+
* @param {Transform2} xfB
|
|
51
|
+
* @returns {boolean}
|
|
52
|
+
*/
|
|
53
|
+
export function testOverlap(shapeA: Shape, xfA: Transform2, shapeB: Shape, xfB: Transform2): boolean;
|
|
54
|
+
import { Transform2 } from "./Math2D.js";
|