@flighthq/physics2d 0.3.0-edge.1458.0c01b63
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/dist/colliderTransform.d.ts +10 -0
- package/dist/colliderTransform.d.ts.map +1 -0
- package/dist/colliderTransform.js +137 -0
- package/dist/colliderTransform.js.map +1 -0
- package/dist/contract.d.ts +9 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +9 -0
- package/dist/contract.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/islands.d.ts +38 -0
- package/dist/islands.d.ts.map +1 -0
- package/dist/islands.js +159 -0
- package/dist/islands.js.map +1 -0
- package/dist/jointRegistry.d.ts +6 -0
- package/dist/jointRegistry.d.ts.map +1 -0
- package/dist/jointRegistry.js +78 -0
- package/dist/jointRegistry.js.map +1 -0
- package/dist/joints.d.ts +39 -0
- package/dist/joints.d.ts.map +1 -0
- package/dist/joints.js +561 -0
- package/dist/joints.js.map +1 -0
- package/dist/massProperties.d.ts +4 -0
- package/dist/massProperties.d.ts.map +1 -0
- package/dist/massProperties.js +146 -0
- package/dist/massProperties.js.map +1 -0
- package/dist/solver.d.ts +7 -0
- package/dist/solver.d.ts.map +1 -0
- package/dist/solver.js +129 -0
- package/dist/solver.js.map +1 -0
- package/dist/step.d.ts +3 -0
- package/dist/step.d.ts.map +1 -0
- package/dist/step.js +414 -0
- package/dist/step.js.map +1 -0
- package/dist/world.d.ts +10 -0
- package/dist/world.d.ts.map +1 -0
- package/dist/world.js +133 -0
- package/dist/world.js.map +1 -0
- package/package.json +49 -0
- package/src/colliderTransform.test.ts +115 -0
- package/src/islands.test.ts +262 -0
- package/src/jointRegistry.test.ts +205 -0
- package/src/joints.test.ts +951 -0
- package/src/massProperties.test.ts +169 -0
- package/src/solver.test.ts +186 -0
- package/src/step.test.ts +745 -0
- package/src/world.test.ts +142 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CollisionShape, Physics2DCollider, RigidBody2D } from '@flighthq/types/contract';
|
|
2
|
+
export declare function createPhysics2DColliderWorldShape(local: Readonly<CollisionShape>): CollisionShape;
|
|
3
|
+
export declare function updatePhysics2DColliderWorldShape(collider: Physics2DCollider, body: Readonly<RigidBody2D>): void;
|
|
4
|
+
export declare function writePhysics2DColliderBounds(collider: Readonly<Physics2DCollider>, out: {
|
|
5
|
+
minX: number;
|
|
6
|
+
minY: number;
|
|
7
|
+
maxX: number;
|
|
8
|
+
maxY: number;
|
|
9
|
+
}): void;
|
|
10
|
+
//# sourceMappingURL=colliderTransform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colliderTransform.d.ts","sourceRoot":"","sources":["../src/colliderTransform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAK/F,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,cAAc,CAYjG;AAWD,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CA8ChH;AAMD,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EACrC,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9D,IAAI,CA2DN"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// Allocates the world-space shape a collider needs for `local`, choosing the kind the transform can
|
|
2
|
+
// actually express. Every field is filled at creation so the shape is never read half-initialised, and
|
|
3
|
+
// polygon storage is sized once here so the per-step transform can write in place.
|
|
4
|
+
export function createPhysics2DColliderWorldShape(local) {
|
|
5
|
+
switch (local.kind) {
|
|
6
|
+
case 'circle':
|
|
7
|
+
return { kind: 'circle', x: local.x, y: local.y, radius: local.radius };
|
|
8
|
+
case 'aabb':
|
|
9
|
+
case 'obb':
|
|
10
|
+
return { kind: 'obb', x: 0, y: 0, halfW: 0, halfH: 0, rotation: 0 };
|
|
11
|
+
case 'polygon':
|
|
12
|
+
return { kind: 'polygon', points: local.points.slice() };
|
|
13
|
+
default:
|
|
14
|
+
return { kind: 'point', x: 0, y: 0 };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// Rewrites `collider.world` from its local shape and the body's current transform. Called once per
|
|
18
|
+
// collider per step, before the narrow phase — never per contact test, because a body with four
|
|
19
|
+
// colliders against a hundred broadphase candidates would otherwise transform the same shape a hundred
|
|
20
|
+
// times to produce the same answer.
|
|
21
|
+
//
|
|
22
|
+
// The world shape is preallocated at collider creation and mutated in place, so a step allocates
|
|
23
|
+
// nothing. Polygon points are the only variable-length part, and the world array is sized once from the
|
|
24
|
+
// local one; a caller that reshapes a collider must rebuild it through `createPhysics2DCollider` rather
|
|
25
|
+
// than mutating `local.points` in place.
|
|
26
|
+
export function updatePhysics2DColliderWorldShape(collider, body) {
|
|
27
|
+
const local = collider.local;
|
|
28
|
+
const world = collider.world;
|
|
29
|
+
const cos = Math.cos(body.angle);
|
|
30
|
+
const sin = Math.sin(body.angle);
|
|
31
|
+
if (local.kind === 'circle' && world.kind === 'circle') {
|
|
32
|
+
world.x = body.x + local.x * cos - local.y * sin;
|
|
33
|
+
world.y = body.y + local.x * sin + local.y * cos;
|
|
34
|
+
world.radius = local.radius;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// An axis-aligned box promotes to an oriented box in world space: rotate it and it is no longer
|
|
38
|
+
// axis-aligned, and silently keeping the `aabb` kind would grow the box to its bounding extent the
|
|
39
|
+
// first time the body turned.
|
|
40
|
+
if (local.kind === 'aabb' && world.kind === 'obb') {
|
|
41
|
+
const centerX = (local.minX + local.maxX) / 2;
|
|
42
|
+
const centerY = (local.minY + local.maxY) / 2;
|
|
43
|
+
world.x = body.x + centerX * cos - centerY * sin;
|
|
44
|
+
world.y = body.y + centerX * sin + centerY * cos;
|
|
45
|
+
world.halfW = (local.maxX - local.minX) / 2;
|
|
46
|
+
world.halfH = (local.maxY - local.minY) / 2;
|
|
47
|
+
world.rotation = body.angle;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (local.kind === 'obb' && world.kind === 'obb') {
|
|
51
|
+
world.x = body.x + local.x * cos - local.y * sin;
|
|
52
|
+
world.y = body.y + local.x * sin + local.y * cos;
|
|
53
|
+
world.halfW = local.halfW;
|
|
54
|
+
world.halfH = local.halfH;
|
|
55
|
+
world.rotation = body.angle + local.rotation;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (local.kind === 'polygon' && world.kind === 'polygon') {
|
|
59
|
+
const source = local.points;
|
|
60
|
+
const target = world.points;
|
|
61
|
+
for (let i = 0; i < source.length; i += 2) {
|
|
62
|
+
const x = source[i];
|
|
63
|
+
const y = source[i + 1];
|
|
64
|
+
target[i] = body.x + x * cos - y * sin;
|
|
65
|
+
target[i + 1] = body.y + x * sin + y * cos;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Writes `collider.world`'s axis-aligned bounds into `out` — the broadphase's view of the collider.
|
|
70
|
+
// Bounds are computed from the WORLD shape rather than by transforming local bounds, because rotating
|
|
71
|
+
// an extent and rotating a shape's bounds are different boxes: the second is the bound of the first and
|
|
72
|
+
// grows without limit as the body spins.
|
|
73
|
+
export function writePhysics2DColliderBounds(collider, out) {
|
|
74
|
+
const shape = collider.world;
|
|
75
|
+
switch (shape.kind) {
|
|
76
|
+
case 'circle':
|
|
77
|
+
out.minX = shape.x - shape.radius;
|
|
78
|
+
out.minY = shape.y - shape.radius;
|
|
79
|
+
out.maxX = shape.x + shape.radius;
|
|
80
|
+
out.maxY = shape.y + shape.radius;
|
|
81
|
+
return;
|
|
82
|
+
case 'aabb':
|
|
83
|
+
out.minX = shape.minX;
|
|
84
|
+
out.minY = shape.minY;
|
|
85
|
+
out.maxX = shape.maxX;
|
|
86
|
+
out.maxY = shape.maxY;
|
|
87
|
+
return;
|
|
88
|
+
case 'obb': {
|
|
89
|
+
const cos = Math.abs(Math.cos(shape.rotation));
|
|
90
|
+
const sin = Math.abs(Math.sin(shape.rotation));
|
|
91
|
+
const extentX = shape.halfW * cos + shape.halfH * sin;
|
|
92
|
+
const extentY = shape.halfW * sin + shape.halfH * cos;
|
|
93
|
+
out.minX = shape.x - extentX;
|
|
94
|
+
out.minY = shape.y - extentY;
|
|
95
|
+
out.maxX = shape.x + extentX;
|
|
96
|
+
out.maxY = shape.y + extentY;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
case 'polygon': {
|
|
100
|
+
const points = shape.points;
|
|
101
|
+
if (points.length < 2) {
|
|
102
|
+
out.minX = 0;
|
|
103
|
+
out.minY = 0;
|
|
104
|
+
out.maxX = 0;
|
|
105
|
+
out.maxY = 0;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
let minX = points[0];
|
|
109
|
+
let minY = points[1];
|
|
110
|
+
let maxX = minX;
|
|
111
|
+
let maxY = minY;
|
|
112
|
+
for (let i = 2; i < points.length; i += 2) {
|
|
113
|
+
const x = points[i];
|
|
114
|
+
const y = points[i + 1];
|
|
115
|
+
if (x < minX)
|
|
116
|
+
minX = x;
|
|
117
|
+
else if (x > maxX)
|
|
118
|
+
maxX = x;
|
|
119
|
+
if (y < minY)
|
|
120
|
+
minY = y;
|
|
121
|
+
else if (y > maxY)
|
|
122
|
+
maxY = y;
|
|
123
|
+
}
|
|
124
|
+
out.minX = minX;
|
|
125
|
+
out.minY = minY;
|
|
126
|
+
out.maxX = maxX;
|
|
127
|
+
out.maxY = maxY;
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
default:
|
|
131
|
+
out.minX = 0;
|
|
132
|
+
out.minY = 0;
|
|
133
|
+
out.maxX = 0;
|
|
134
|
+
out.maxY = 0;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=colliderTransform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colliderTransform.js","sourceRoot":"","sources":["../src/colliderTransform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './colliderTransform';
|
|
2
|
+
export * from './islands';
|
|
3
|
+
export * from './jointRegistry';
|
|
4
|
+
export * from './joints';
|
|
5
|
+
export * from './massProperties';
|
|
6
|
+
export * from './solver';
|
|
7
|
+
export * from './step';
|
|
8
|
+
export * from './world';
|
|
9
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
|
package/dist/contract.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './colliderTransform';
|
|
2
|
+
export * from './islands';
|
|
3
|
+
export * from './jointRegistry';
|
|
4
|
+
export * from './joints';
|
|
5
|
+
export * from './massProperties';
|
|
6
|
+
export * from './solver';
|
|
7
|
+
export * from './step';
|
|
8
|
+
export * from './world';
|
|
9
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { createPhysics2DColliderWorldShape, updatePhysics2DColliderWorldShape, writePhysics2DColliderBounds, } from './colliderTransform';
|
|
2
|
+
export { isRigidBody2DPairAwake, updatePhysics2DSleep, wakePhysics2DBody } from './islands';
|
|
3
|
+
export { Physics2DDistanceJointKind, Physics2DMouseJointKind, Physics2DRevoluteJointKind, Physics2DRopeJointKind, Physics2DWeldJointKind, physics2DDistanceJointSolver, physics2DMouseJointSolver, physics2DRevoluteJointSolver, physics2DRopeJointSolver, physics2DWeldJointSolver, } from './joints';
|
|
4
|
+
export { addPhysics2DJoint, getPhysics2DJointSolver, registerPhysics2DJointSolver, removePhysics2DJoint, } from './jointRegistry';
|
|
5
|
+
export { computePhysics2DColliderMassData, updateRigidBody2DMassData } from './massProperties';
|
|
6
|
+
export { applyPhysics2DImpulse, relativeNormalVelocity, solvePhysics2DContacts, solvePhysics2DContactsOnce, warmStartPhysics2DContacts, } from './solver';
|
|
7
|
+
export { stepPhysics2D } from './step';
|
|
8
|
+
export { addPhysics2DBody, findPhysics2DBody, createPhysics2DCollider, createPhysics2DSolverConfig, createPhysics2DWorld, createRigidBody2D, isPhysics2DPairOrdered, removePhysics2DBody, } from './world';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,iCAAiC,EACjC,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC5F,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,4BAA4B,EAC5B,yBAAyB,EACzB,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { createPhysics2DColliderWorldShape, updatePhysics2DColliderWorldShape, writePhysics2DColliderBounds, } from './colliderTransform';
|
|
2
|
+
export { isRigidBody2DPairAwake, updatePhysics2DSleep, wakePhysics2DBody } from './islands';
|
|
3
|
+
export { Physics2DDistanceJointKind, Physics2DMouseJointKind, Physics2DRevoluteJointKind, Physics2DRopeJointKind, Physics2DWeldJointKind, physics2DDistanceJointSolver, physics2DMouseJointSolver, physics2DRevoluteJointSolver, physics2DRopeJointSolver, physics2DWeldJointSolver, } from './joints';
|
|
4
|
+
export { addPhysics2DJoint, getPhysics2DJointSolver, registerPhysics2DJointSolver, removePhysics2DJoint, } from './jointRegistry';
|
|
5
|
+
export { computePhysics2DColliderMassData, updateRigidBody2DMassData } from './massProperties';
|
|
6
|
+
export { applyPhysics2DImpulse, relativeNormalVelocity, solvePhysics2DContacts, solvePhysics2DContactsOnce, warmStartPhysics2DContacts, } from './solver';
|
|
7
|
+
export { stepPhysics2D } from './step';
|
|
8
|
+
export { addPhysics2DBody, findPhysics2DBody, createPhysics2DCollider, createPhysics2DSolverConfig, createPhysics2DWorld, createRigidBody2D, isPhysics2DPairOrdered, removePhysics2DBody, } from './world';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,iCAAiC,EACjC,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC5F,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,4BAA4B,EAC5B,yBAAyB,EACzB,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Physics2DWorld, RigidBody2D } from '@flighthq/types/contract';
|
|
2
|
+
/** Whether a constraint between these two bodies still has anything to solve.
|
|
3
|
+
*
|
|
4
|
+
* A constraint is live only while at least one of its ends can still move this step. Two sleeping
|
|
5
|
+
* bodies, a sleeper against static scenery, or two static bodies all resolve to nothing: every impulse
|
|
6
|
+
* the solver could compute would be applied to a body that is not being integrated.
|
|
7
|
+
*
|
|
8
|
+
* Skipping is not merely an optimisation, and this is the reason sleep needs a solver-side test at all
|
|
9
|
+
* rather than only an integrator-side one. A resting contact usually carries penetration beyond the
|
|
10
|
+
* slop, so its positional bias is non-zero; solved, it hands the sleeping pair a velocity, which the
|
|
11
|
+
* end-of-step stillness test then reads as motion and wakes them again. A stack would twitch itself
|
|
12
|
+
* awake every step and never rest. */
|
|
13
|
+
export declare function isRigidBody2DPairAwake(a: Readonly<RigidBody2D>, b: Readonly<RigidBody2D>): boolean;
|
|
14
|
+
/** Advances every body's sleep state for one step, and returns whether any body is awake.
|
|
15
|
+
*
|
|
16
|
+
* Sleep is decided per ISLAND, not per body. Two dynamic bodies are in the same island when a contact
|
|
17
|
+
* or a joint connects them, transitively — so a stack, a chain of links, and a pile all settle or wake
|
|
18
|
+
* as one unit. Deciding per body instead produces the visible failure this exists to prevent: a crate
|
|
19
|
+
* that has stopped moving falls asleep while the crate it rests on is still sliding out from under it,
|
|
20
|
+
* and the sleeper hangs in the air until something happens to wake it.
|
|
21
|
+
*
|
|
22
|
+
* Static bodies are excluded entirely. They never move, so they are neither awake nor asleep, and
|
|
23
|
+
* crucially they do NOT join islands: every dynamic body resting on the same ground would otherwise be
|
|
24
|
+
* transitively connected into one world-sized island that can only sleep when the last object in the
|
|
25
|
+
* level stops moving.
|
|
26
|
+
*
|
|
27
|
+
* An island sleeps only once EVERY member has been continuously below both thresholds for
|
|
28
|
+
* `timeToSleep`. Any member exceeding a threshold resets its own timer, and because the island's timer
|
|
29
|
+
* is the minimum across its members, one moving body keeps the whole island awake. */
|
|
30
|
+
export declare function updatePhysics2DSleep(world: Physics2DWorld, dt: number): void;
|
|
31
|
+
/** Wakes `body` and clears its stillness timer, so it is simulated again from this step.
|
|
32
|
+
*
|
|
33
|
+
* The caller wakes a body; the island reduction then keeps its neighbours awake too, because a woken
|
|
34
|
+
* body's zeroed timer becomes the minimum for its island on the next step. Waking is what any external
|
|
35
|
+
* change to a sleeping body must do — applying a force, teleporting it, or removing what it rested on —
|
|
36
|
+
* since a sleeping body is skipped by integration and would otherwise ignore the change entirely. */
|
|
37
|
+
export declare function wakePhysics2DBody(body: RigidBody2D): void;
|
|
38
|
+
//# sourceMappingURL=islands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"islands.d.ts","sourceRoot":"","sources":["../src/islands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAI5E;;;;;;;;;;uCAUuC;AACvC,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,OAAO,CAElG;AAED;;;;;;;;;;;;;;;uFAeuF;AACvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAgE5E;AAED;;;;;sGAKsG;AACtG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAGzD"}
|
package/dist/islands.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { findPhysics2DBody } from './world';
|
|
2
|
+
/** Whether a constraint between these two bodies still has anything to solve.
|
|
3
|
+
*
|
|
4
|
+
* A constraint is live only while at least one of its ends can still move this step. Two sleeping
|
|
5
|
+
* bodies, a sleeper against static scenery, or two static bodies all resolve to nothing: every impulse
|
|
6
|
+
* the solver could compute would be applied to a body that is not being integrated.
|
|
7
|
+
*
|
|
8
|
+
* Skipping is not merely an optimisation, and this is the reason sleep needs a solver-side test at all
|
|
9
|
+
* rather than only an integrator-side one. A resting contact usually carries penetration beyond the
|
|
10
|
+
* slop, so its positional bias is non-zero; solved, it hands the sleeping pair a velocity, which the
|
|
11
|
+
* end-of-step stillness test then reads as motion and wakes them again. A stack would twitch itself
|
|
12
|
+
* awake every step and never rest. */
|
|
13
|
+
export function isRigidBody2DPairAwake(a, b) {
|
|
14
|
+
return _isBodyLive(a) || _isBodyLive(b);
|
|
15
|
+
}
|
|
16
|
+
/** Advances every body's sleep state for one step, and returns whether any body is awake.
|
|
17
|
+
*
|
|
18
|
+
* Sleep is decided per ISLAND, not per body. Two dynamic bodies are in the same island when a contact
|
|
19
|
+
* or a joint connects them, transitively — so a stack, a chain of links, and a pile all settle or wake
|
|
20
|
+
* as one unit. Deciding per body instead produces the visible failure this exists to prevent: a crate
|
|
21
|
+
* that has stopped moving falls asleep while the crate it rests on is still sliding out from under it,
|
|
22
|
+
* and the sleeper hangs in the air until something happens to wake it.
|
|
23
|
+
*
|
|
24
|
+
* Static bodies are excluded entirely. They never move, so they are neither awake nor asleep, and
|
|
25
|
+
* crucially they do NOT join islands: every dynamic body resting on the same ground would otherwise be
|
|
26
|
+
* transitively connected into one world-sized island that can only sleep when the last object in the
|
|
27
|
+
* level stops moving.
|
|
28
|
+
*
|
|
29
|
+
* An island sleeps only once EVERY member has been continuously below both thresholds for
|
|
30
|
+
* `timeToSleep`. Any member exceeding a threshold resets its own timer, and because the island's timer
|
|
31
|
+
* is the minimum across its members, one moving body keeps the whole island awake. */
|
|
32
|
+
export function updatePhysics2DSleep(world, dt) {
|
|
33
|
+
const config = world.config;
|
|
34
|
+
const bodies = world.bodies;
|
|
35
|
+
if (!config.allowSleeping) {
|
|
36
|
+
// The mechanism is off, so nothing may be left asleep from when it was on — a body that stayed
|
|
37
|
+
// asleep here would never be integrated again and would look frozen for the rest of the session.
|
|
38
|
+
for (const body of bodies) {
|
|
39
|
+
body.sleeping = false;
|
|
40
|
+
body.sleepTimer = 0;
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Per-body stillness first: each body's own timer, independent of who it is touching.
|
|
45
|
+
for (const body of bodies) {
|
|
46
|
+
if (body.type === 'static')
|
|
47
|
+
continue;
|
|
48
|
+
if (_isBodyStill(body, config.sleepLinearThreshold, config.sleepAngularThreshold)) {
|
|
49
|
+
body.sleepTimer += dt;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
body.sleepTimer = 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Then the island reduction. `_islandRootOf` is union-find over the contact and joint graph, so the
|
|
56
|
+
// root is a stable representative for the connected component.
|
|
57
|
+
const parents = new Map();
|
|
58
|
+
for (const contact of world.contacts) {
|
|
59
|
+
if (contact.sensor)
|
|
60
|
+
continue; // A sensor reports overlap and resolves nothing, so it couples no motion.
|
|
61
|
+
_unionDynamicPair(world, parents, contact.bodyA, contact.bodyB);
|
|
62
|
+
}
|
|
63
|
+
for (const joint of world.joints) {
|
|
64
|
+
_unionDynamicPair(world, parents, joint.bodyA, joint.bodyB);
|
|
65
|
+
}
|
|
66
|
+
// The island's timer is the MINIMUM across its members: the least-settled body decides.
|
|
67
|
+
const islandTimers = new Map();
|
|
68
|
+
for (const body of bodies) {
|
|
69
|
+
if (body.type === 'static')
|
|
70
|
+
continue;
|
|
71
|
+
const root = _islandRootOf(parents, body.index);
|
|
72
|
+
const current = islandTimers.get(root);
|
|
73
|
+
islandTimers.set(root, current === undefined ? body.sleepTimer : Math.min(current, body.sleepTimer));
|
|
74
|
+
}
|
|
75
|
+
for (const body of bodies) {
|
|
76
|
+
if (body.type === 'static')
|
|
77
|
+
continue;
|
|
78
|
+
const islandTimer = islandTimers.get(_islandRootOf(parents, body.index)) ?? body.sleepTimer;
|
|
79
|
+
const shouldSleep = islandTimer >= config.timeToSleep;
|
|
80
|
+
if (!shouldSleep && body.sleeping) {
|
|
81
|
+
// Waking clears the timer so a woken island must earn its rest again from zero rather than
|
|
82
|
+
// falling straight back asleep on the next step.
|
|
83
|
+
body.sleepTimer = 0;
|
|
84
|
+
}
|
|
85
|
+
body.sleeping = shouldSleep;
|
|
86
|
+
if (shouldSleep) {
|
|
87
|
+
// Zeroed rather than merely small. A sleeping body is not integrated, so any residual velocity is
|
|
88
|
+
// motion that will be silently resumed the moment it wakes — a crate that settled ten steps ago
|
|
89
|
+
// would twitch on waking. Zeroing also makes the stillness test trivially true next step, so a
|
|
90
|
+
// body cannot oscillate across the threshold while asleep.
|
|
91
|
+
body.velocityX = 0;
|
|
92
|
+
body.velocityY = 0;
|
|
93
|
+
body.angularVelocity = 0;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Wakes `body` and clears its stillness timer, so it is simulated again from this step.
|
|
98
|
+
*
|
|
99
|
+
* The caller wakes a body; the island reduction then keeps its neighbours awake too, because a woken
|
|
100
|
+
* body's zeroed timer becomes the minimum for its island on the next step. Waking is what any external
|
|
101
|
+
* change to a sleeping body must do — applying a force, teleporting it, or removing what it rested on —
|
|
102
|
+
* since a sleeping body is skipped by integration and would otherwise ignore the change entirely. */
|
|
103
|
+
export function wakePhysics2DBody(body) {
|
|
104
|
+
body.sleeping = false;
|
|
105
|
+
body.sleepTimer = 0;
|
|
106
|
+
}
|
|
107
|
+
// A body the solver can still move: dynamic or kinematic, and awake. Static bodies are never live —
|
|
108
|
+
// their inverse mass is zero, so an impulse against them changes nothing regardless of sleep state.
|
|
109
|
+
function _isBodyLive(body) {
|
|
110
|
+
return body.type !== 'static' && !body.sleeping;
|
|
111
|
+
}
|
|
112
|
+
function _isBodyStill(body, linearThreshold, angularThreshold) {
|
|
113
|
+
// A body someone has applied force or torque to is not at rest, whatever its velocity currently reads.
|
|
114
|
+
// Velocity alone would miss it: force is applied during the step, so a sleeper skips the integration
|
|
115
|
+
// that would have turned it into motion, and the force is cleared at the end of the step — the push
|
|
116
|
+
// would be silently swallowed and the body would stay asleep under continuous load.
|
|
117
|
+
if (body.forceX !== 0 || body.forceY !== 0 || body.torque !== 0)
|
|
118
|
+
return false;
|
|
119
|
+
const speedSquared = body.velocityX * body.velocityX + body.velocityY * body.velocityY;
|
|
120
|
+
if (speedSquared > linearThreshold * linearThreshold)
|
|
121
|
+
return false;
|
|
122
|
+
return Math.abs(body.angularVelocity) <= angularThreshold;
|
|
123
|
+
}
|
|
124
|
+
// Joins two bodies into one island, but only when BOTH are dynamic. A static body is not a member of
|
|
125
|
+
// any island, so it cannot act as a bridge — otherwise the ground would merge every stack in the level
|
|
126
|
+
// into a single island that sleeps only when nothing anywhere is moving.
|
|
127
|
+
function _unionDynamicPair(world, parents, a, b) {
|
|
128
|
+
const first = findPhysics2DBody(world, a);
|
|
129
|
+
const second = findPhysics2DBody(world, b);
|
|
130
|
+
if (first === null || second === null)
|
|
131
|
+
return;
|
|
132
|
+
if (first.type === 'static' || second.type === 'static')
|
|
133
|
+
return;
|
|
134
|
+
const rootA = _islandRootOf(parents, a);
|
|
135
|
+
const rootB = _islandRootOf(parents, b);
|
|
136
|
+
if (rootA !== rootB)
|
|
137
|
+
parents.set(rootA, rootB);
|
|
138
|
+
}
|
|
139
|
+
// Union-find with path compression. An index with no entry is its own root, so a body touching nothing
|
|
140
|
+
// is an island of one without needing to be inserted first.
|
|
141
|
+
function _islandRootOf(parents, index) {
|
|
142
|
+
let root = index;
|
|
143
|
+
for (;;) {
|
|
144
|
+
const parent = parents.get(root);
|
|
145
|
+
if (parent === undefined || parent === root)
|
|
146
|
+
break;
|
|
147
|
+
root = parent;
|
|
148
|
+
}
|
|
149
|
+
let walk = index;
|
|
150
|
+
for (;;) {
|
|
151
|
+
const parent = parents.get(walk);
|
|
152
|
+
if (parent === undefined || parent === walk)
|
|
153
|
+
break;
|
|
154
|
+
parents.set(walk, root);
|
|
155
|
+
walk = parent;
|
|
156
|
+
}
|
|
157
|
+
return root;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=islands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"islands.js","sourceRoot":"","sources":["../src/islands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Physics2DJoint, Physics2DJointKind, Physics2DJointSolver, Physics2DWorld } from '@flighthq/types/contract';
|
|
2
|
+
export declare function addPhysics2DJoint(world: Physics2DWorld, joint: Physics2DJoint): Physics2DJoint;
|
|
3
|
+
export declare function getPhysics2DJointSolver(world: Readonly<Physics2DWorld>, kind: Physics2DJointKind): Physics2DJointSolver | null;
|
|
4
|
+
export declare function registerPhysics2DJointSolver(world: Physics2DWorld, kind: Physics2DJointKind, solver: Physics2DJointSolver): void;
|
|
5
|
+
export declare function removePhysics2DJoint(world: Physics2DWorld, joint: Readonly<Physics2DJoint>): boolean;
|
|
6
|
+
//# sourceMappingURL=jointRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jointRegistry.d.ts","sourceRoot":"","sources":["../src/jointRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAalC,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,GAAG,cAAc,CAY9F;AAyBD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,IAAI,EAAE,kBAAkB,GACvB,oBAAoB,GAAG,IAAI,CAE7B;AASD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,oBAAoB,GAC3B,IAAI,CASN;AAGD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,OAAO,CAKpG"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { findPhysics2DBody, isPhysics2DPairOrdered } from './world';
|
|
2
|
+
// Adds `joint` to `world` under the same canonical body ordering contacts use, swapping its two ends when
|
|
3
|
+
// the caller supplied them the other way round.
|
|
4
|
+
//
|
|
5
|
+
// A joint is a constraint in the SAME sequential solve list as a contact, so it inherits the same
|
|
6
|
+
// obligation: each impulse lands on the velocities the previous one left, and an ordering that varied
|
|
7
|
+
// with construction history would make the result vary with it. Contacts get this from the broadphase
|
|
8
|
+
// pair sort; joints have no broadphase, so it is enforced here, at the one place a joint enters the
|
|
9
|
+
// world. The anchors and lever arms swap with the bodies — a joint whose ends were exchanged without its
|
|
10
|
+
// anchors would attach to the wrong points and hold the pair in a pose nobody asked for.
|
|
11
|
+
export function addPhysics2DJoint(world, joint) {
|
|
12
|
+
// The kind decides how to reverse itself, because the registry cannot know which of a joint's fields
|
|
13
|
+
// carry a direction — see _canonicalizePhysics2DJointEnds.
|
|
14
|
+
// Only canonicalize when the kind can be consulted. A joint whose solver is not registered yet is
|
|
15
|
+
// explicitly supported (a scene deserialized ahead of the code that solves it), and swapping it now
|
|
16
|
+
// would exchange the bodies and anchors while its kind-specific direction fields stayed as authored --
|
|
17
|
+
// the generic half of a swap with the kind's half missing, which no later registration would repair.
|
|
18
|
+
// An unregistered joint constrains nothing, so its ordering does not matter until a solver exists;
|
|
19
|
+
// registerPhysics2DJointSolver canonicalizes what is already in the world at that point.
|
|
20
|
+
if (getPhysics2DJointSolver(world, joint.kind) !== null)
|
|
21
|
+
_canonicalizePhysics2DJointEnds(world, joint);
|
|
22
|
+
world.joints.push(joint);
|
|
23
|
+
return joint;
|
|
24
|
+
}
|
|
25
|
+
// Exchanges `joint`'s ends when the pair is out of canonical order and the kind consents. The kind is
|
|
26
|
+
// asked only when a swap is actually pending, since swapEnds both vetoes and transforms: calling it
|
|
27
|
+
// otherwise would apply a reversal to ends that never moved.
|
|
28
|
+
function _canonicalizePhysics2DJointEnds(world, joint) {
|
|
29
|
+
const first = findPhysics2DBody(world, joint.bodyA);
|
|
30
|
+
const second = findPhysics2DBody(world, joint.bodyB);
|
|
31
|
+
if (first === null || second === null || isPhysics2DPairOrdered(first, second))
|
|
32
|
+
return;
|
|
33
|
+
const solver = getPhysics2DJointSolver(world, joint.kind);
|
|
34
|
+
if (!(solver?.swapEnds?.(joint) ?? true))
|
|
35
|
+
return;
|
|
36
|
+
const bodyA = joint.bodyA;
|
|
37
|
+
joint.bodyA = joint.bodyB;
|
|
38
|
+
joint.bodyB = bodyA;
|
|
39
|
+
const anchorX = joint.localAnchorAX;
|
|
40
|
+
const anchorY = joint.localAnchorAY;
|
|
41
|
+
joint.localAnchorAX = joint.localAnchorBX;
|
|
42
|
+
joint.localAnchorAY = joint.localAnchorBY;
|
|
43
|
+
joint.localAnchorBX = anchorX;
|
|
44
|
+
joint.localAnchorBY = anchorY;
|
|
45
|
+
}
|
|
46
|
+
// The solver registered for `kind`, or null when none is. A missing solver is an expected condition, not
|
|
47
|
+
// an error: a scene deserialized with a joint kind the running build does not know about should import
|
|
48
|
+
// and simply not constrain, rather than refuse to load.
|
|
49
|
+
export function getPhysics2DJointSolver(world, kind) {
|
|
50
|
+
return world.jointSolvers.get(kind) ?? null;
|
|
51
|
+
}
|
|
52
|
+
// Registers `solver` for `kind` on this world. Last write wins, so a caller may replace a built-in with
|
|
53
|
+
// its own — collisions are avoided by the vendor-prefix convention (bare names reserved for built-ins),
|
|
54
|
+
// not by a guard that would make overriding impossible.
|
|
55
|
+
//
|
|
56
|
+
// Registration is per-world and explicit rather than a module-level table populated on import, so a
|
|
57
|
+
// bundle that never registers a joint never links one: nine solvers are nine chunks of constraint math,
|
|
58
|
+
// and a game using none of them should pay for none of them.
|
|
59
|
+
export function registerPhysics2DJointSolver(world, kind, solver) {
|
|
60
|
+
world.jointSolvers.set(kind, solver);
|
|
61
|
+
// Joints of this kind may already be in the world: addPhysics2DJoint deliberately leaves an
|
|
62
|
+
// unknown-kind joint in its authored order, because canonicalizing it without the kind's consent
|
|
63
|
+
// would half-swap it. This is where that deferred work happens, so the outcome no longer depends on
|
|
64
|
+
// whether the scene or the solver arrived first.
|
|
65
|
+
for (const joint of world.joints) {
|
|
66
|
+
if (joint.kind === kind)
|
|
67
|
+
_canonicalizePhysics2DJointEnds(world, joint);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Removes `joint` from `world`. Returns false when the world does not hold it.
|
|
71
|
+
export function removePhysics2DJoint(world, joint) {
|
|
72
|
+
const at = world.joints.indexOf(joint);
|
|
73
|
+
if (at < 0)
|
|
74
|
+
return false;
|
|
75
|
+
world.joints.splice(at, 1);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=jointRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jointRegistry.js","sourceRoot":"","sources":["../src/jointRegistry.ts"],"names":[],"mappings":"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"}
|
package/dist/joints.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Physics2DJoint, Physics2DWorld } from '@flighthq/types/contract';
|
|
2
|
+
export declare const Physics2DDistanceJointKind = "Distance";
|
|
3
|
+
export declare const Physics2DMouseJointKind = "Mouse";
|
|
4
|
+
export declare const Physics2DRevoluteJointKind = "Revolute";
|
|
5
|
+
export declare const Physics2DRopeJointKind = "Rope";
|
|
6
|
+
export declare const Physics2DWeldJointKind = "Weld";
|
|
7
|
+
export declare const physics2DDistanceJointSolver: {
|
|
8
|
+
warmStart(world: Physics2DWorld, joint: Physics2DJoint): void;
|
|
9
|
+
clearAccumulatedImpulses(joint: Physics2DJoint): void;
|
|
10
|
+
prepare(world: Physics2DWorld, joint: Physics2DJoint, dt: number): void;
|
|
11
|
+
solve(world: Physics2DWorld, joint: Physics2DJoint): void;
|
|
12
|
+
};
|
|
13
|
+
export declare const physics2DMouseJointSolver: {
|
|
14
|
+
swapEnds(): boolean;
|
|
15
|
+
clearAccumulatedImpulses(joint: Physics2DJoint): void;
|
|
16
|
+
prepare(world: Physics2DWorld, joint: Physics2DJoint, dt: number): void;
|
|
17
|
+
solve(world: Physics2DWorld, joint: Physics2DJoint): void;
|
|
18
|
+
};
|
|
19
|
+
export declare const physics2DRevoluteJointSolver: {
|
|
20
|
+
warmStart(world: Physics2DWorld, joint: Physics2DJoint): void;
|
|
21
|
+
clearAccumulatedImpulses(joint: Physics2DJoint): void;
|
|
22
|
+
swapEnds(joint: Physics2DJoint): boolean;
|
|
23
|
+
prepare(world: Physics2DWorld, joint: Physics2DJoint, dt: number): void;
|
|
24
|
+
solve(world: Physics2DWorld, joint: Physics2DJoint): void;
|
|
25
|
+
};
|
|
26
|
+
export declare const physics2DRopeJointSolver: {
|
|
27
|
+
warmStart(world: Physics2DWorld, joint: Physics2DJoint): void;
|
|
28
|
+
clearAccumulatedImpulses(joint: Physics2DJoint): void;
|
|
29
|
+
prepare(world: Physics2DWorld, joint: Physics2DJoint, dt: number): void;
|
|
30
|
+
solve(world: Physics2DWorld, joint: Physics2DJoint): void;
|
|
31
|
+
};
|
|
32
|
+
export declare const physics2DWeldJointSolver: {
|
|
33
|
+
warmStart(world: Physics2DWorld, joint: Physics2DJoint): void;
|
|
34
|
+
clearAccumulatedImpulses(joint: Physics2DJoint): void;
|
|
35
|
+
swapEnds(joint: Physics2DJoint): boolean;
|
|
36
|
+
prepare(world: Physics2DWorld, joint: Physics2DJoint, dt: number): void;
|
|
37
|
+
solve(world: Physics2DWorld, joint: Physics2DJoint): void;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=joints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"joints.d.ts","sourceRoot":"","sources":["../src/joints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EAKd,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAMlC,eAAO,MAAM,0BAA0B,aAAa,CAAC;AACrD,eAAO,MAAM,uBAAuB,UAAU,CAAC;AAC/C,eAAO,MAAM,0BAA0B,aAAa,CAAC;AACrD,eAAO,MAAM,sBAAsB,SAAS,CAAC;AAC7C,eAAO,MAAM,sBAAsB,SAAS,CAAC;AAQ7C,eAAO,MAAM,4BAA4B;qBACtB,cAAc,SAAS,cAAc,GAAG,IAAI;oCAkB7B,cAAc,GAAG,IAAI;mBAItC,cAAc,SAAS,cAAc,MAAM,MAAM,GAAG,IAAI;iBA6C1D,cAAc,SAAS,cAAc,GAAG,IAAI;CAa1D,CAAC;AAOF,eAAO,MAAM,yBAAyB;gBAMxB,OAAO;oCAMa,cAAc,GAAG,IAAI;mBAKtC,cAAc,SAAS,cAAc,MAAM,MAAM,GAAG,IAAI;iBA4B1D,cAAc,SAAS,cAAc,GAAG,IAAI;CAqC1D,CAAC;AAOF,eAAO,MAAM,4BAA4B;qBACtB,cAAc,SAAS,cAAc,GAAG,IAAI;oCAiC7B,cAAc,GAAG,IAAI;oBAarC,cAAc,GAAG,OAAO;mBAezB,cAAc,SAAS,cAAc,MAAM,MAAM,GAAG,IAAI;iBAyB1D,cAAc,SAAS,cAAc,GAAG,IAAI;CAqE1D,CAAC;AAMF,eAAO,MAAM,wBAAwB;qBAClB,cAAc,SAAS,cAAc,GAAG,IAAI;oCAkB7B,cAAc,GAAG,IAAI;mBAItC,cAAc,SAAS,cAAc,MAAM,MAAM,GAAG,IAAI;iBA0B1D,cAAc,SAAS,cAAc,GAAG,IAAI;CAe1D,CAAC;AAWF,eAAO,MAAM,wBAAwB;qBAClB,cAAc,SAAS,cAAc,GAAG,IAAI;oCAS7B,cAAc,GAAG,IAAI;oBAMrC,cAAc,GAAG,OAAO;mBAMzB,cAAc,SAAS,cAAc,MAAM,MAAM,GAAG,IAAI;iBAkB1D,cAAc,SAAS,cAAc,GAAG,IAAI;CAe1D,CAAC"}
|