@newkrok/nape-js 3.6.0 → 3.7.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/dist/index.d.ts CHANGED
@@ -1186,13 +1186,13 @@ declare class Constraint {
1186
1186
  * The impulse applied to `body` by this constraint in the last simulation step,
1187
1187
  * expressed as a {@link Vec3} `(fx, fy, torque)`.
1188
1188
  *
1189
- * @param body - Must be one of the bodies linked to this constraint.
1189
+ * @param _body - Must be one of the bodies linked to this constraint.
1190
1190
  */
1191
1191
  bodyImpulse(_body: Body): Vec3 | null;
1192
1192
  /**
1193
1193
  * Invokes `fn` once for each distinct body linked to this constraint.
1194
1194
  *
1195
- * @param fn - Function to call for each body.
1195
+ * @param _fn - Function to call for each body.
1196
1196
  */
1197
1197
  visitBodies(_fn: (body: Body) => void): void;
1198
1198
  /**
@@ -1214,25 +1214,75 @@ declare class Constraint {
1214
1214
  */
1215
1215
  declare class InteractionFilter {
1216
1216
  static __name__: string[];
1217
+ /**
1218
+ * @param collisionGroup - Collision group bits (default 1).
1219
+ * @param collisionMask - Collision mask bits (default -1, all bits set).
1220
+ * @param sensorGroup - Sensor group bits (default 1).
1221
+ * @param sensorMask - Sensor mask bits (default -1, all bits set).
1222
+ * @param fluidGroup - Fluid group bits (default 1).
1223
+ * @param fluidMask - Fluid mask bits (default -1, all bits set).
1224
+ */
1217
1225
  constructor(collisionGroup?: number, collisionMask?: number, sensorGroup?: number, sensorMask?: number, fluidGroup?: number, fluidMask?: number);
1226
+ /** Bit-mask identifying which collision group(s) this shape belongs to. */
1218
1227
  get collisionGroup(): number;
1219
1228
  set collisionGroup(value: number);
1229
+ /** Bit-mask of collision groups this shape will collide with. */
1220
1230
  get collisionMask(): number;
1221
1231
  set collisionMask(value: number);
1232
+ /** Bit-mask identifying which sensor group(s) this shape belongs to. */
1222
1233
  get sensorGroup(): number;
1223
1234
  set sensorGroup(value: number);
1235
+ /** Bit-mask of sensor groups this shape will sense. */
1224
1236
  get sensorMask(): number;
1225
1237
  set sensorMask(value: number);
1238
+ /** Bit-mask identifying which fluid group(s) this shape belongs to. */
1226
1239
  get fluidGroup(): number;
1227
1240
  set fluidGroup(value: number);
1241
+ /** Bit-mask of fluid groups this shape will interact with as a fluid. */
1228
1242
  get fluidMask(): number;
1229
1243
  set fluidMask(value: number);
1244
+ /** Arbitrary user data attached to this filter. */
1230
1245
  get userData(): Record<string, unknown>;
1246
+ /** Read-only list of shapes currently using this filter. */
1231
1247
  get shapes(): any;
1248
+ /**
1249
+ * Test whether two filters allow collision interaction.
1250
+ * @param filter - The other filter to test against.
1251
+ * @returns `true` if the two filters' group/mask bits permit collision.
1252
+ */
1232
1253
  shouldCollide(filter: InteractionFilter): boolean;
1254
+ /**
1255
+ * Test whether two filters allow sensor interaction.
1256
+ * @param filter - The other filter to test against.
1257
+ * @returns `true` if the two filters' group/mask bits permit sensing.
1258
+ */
1233
1259
  shouldSense(filter: InteractionFilter): boolean;
1260
+ /**
1261
+ * Test whether two filters allow fluid interaction.
1262
+ * @param filter - The other filter to test against.
1263
+ * @returns `true` if the two filters' group/mask bits permit fluid interaction.
1264
+ */
1234
1265
  shouldFlow(filter: InteractionFilter): boolean;
1266
+ /** Create a copy of this filter with the same group/mask values. */
1235
1267
  copy(): InteractionFilter;
1268
+ /** Return a hex-formatted string representation of all group/mask pairs. */
1269
+ toString(): string;
1270
+ }
1271
+
1272
+ /**
1273
+ * Result from a raycast query.
1274
+ *
1275
+ * Provides the contact normal, distance, inside-flag, and shape hit.
1276
+ * Instances are pooled — call `dispose()` when done to return to pool.
1277
+ */
1278
+ declare class RayResult {
1279
+ static __name__: string[];
1280
+ constructor();
1281
+ get normal(): Vec2;
1282
+ get distance(): number;
1283
+ get inner(): boolean;
1284
+ get shape(): Shape;
1285
+ dispose(): void;
1236
1286
  toString(): string;
1237
1287
  }
1238
1288
 
@@ -1278,433 +1328,948 @@ declare class InteractionType {
1278
1328
  }
1279
1329
 
1280
1330
  /**
1281
- * The physics world. Add bodies, shapes, and constraints, then call `step()` each frame to advance the simulation.
1331
+ * Structural interface for all dynamically-generated Nape list classes
1332
+ * (BodyList, ShapeList, CompoundList, etc.).
1333
+ *
1334
+ * These classes are created at runtime by {@link createListClasses} and placed
1335
+ * in the `nape` namespace, so they cannot be imported directly. Use this
1336
+ * interface as the return type for Space / Body query methods.
1282
1337
  */
1283
- declare class Space {
1284
- /**
1285
- * @param gravity - Initial gravity vector (default (0, 0)).
1286
- * @param broadphase - Broadphase algorithm to use.
1287
- */
1288
- constructor(gravity?: Vec2, broadphase?: Broadphase);
1289
- /** Arbitrary user data attached to this Space. */
1338
+ interface TypedListLike<T> extends Iterable<T> {
1339
+ /** Number of elements in the list. */
1340
+ readonly length: number;
1341
+ /** Returns element at the given index. */
1342
+ at(index: number): T;
1343
+ /** Returns true if the list contains `obj`. */
1344
+ has(obj: T): boolean;
1345
+ /** Adds `obj` to the end of the list. Returns true if successful. */
1346
+ push(obj: T): boolean;
1347
+ /** Adds `obj` to the front of the list. Returns true if successful. */
1348
+ unshift(obj: T): boolean;
1349
+ /** Removes and returns the last element. */
1350
+ pop(): T;
1351
+ /** Removes and returns the first element. */
1352
+ shift(): T;
1353
+ /** Adds `obj` (anywhere). Returns true if successful. */
1354
+ add(obj: T): boolean;
1355
+ /** Removes `obj`. Returns true if it was present. */
1356
+ remove(obj: T): boolean;
1357
+ /** Removes all elements. */
1358
+ clear(): void;
1359
+ /** Returns true if the list has no elements. */
1360
+ empty(): boolean;
1361
+ /** Returns an iterator over the elements. */
1362
+ iterator(): Iterable<T>;
1363
+ /** Returns a shallow or deep copy of the list. */
1364
+ copy(deep?: boolean): TypedListLike<T>;
1365
+ /** Merge elements of `xs` into this list. */
1366
+ merge(xs: TypedListLike<T>): void;
1367
+ /** Apply `lambda` to every element. */
1368
+ foreach(lambda: (obj: T) => void): void;
1369
+ /** Returns a filtered copy. */
1370
+ filter(lambda: (obj: T) => boolean): TypedListLike<T>;
1371
+ /** Converts to a plain array. */
1372
+ toArray(): T[];
1373
+ }
1374
+
1375
+ /**
1376
+ * Arbiter type classification.
1377
+ *
1378
+ * - `COLLISION` — collision arbiter
1379
+ * - `SENSOR` — sensor arbiter
1380
+ * - `FLUID` — fluid arbiter
1381
+ *
1382
+ * Converted from nape-compiled.js lines 11653–11725.
1383
+ */
1384
+ declare class ArbiterType {
1385
+ static __name__: string[];
1386
+ constructor();
1387
+ static get COLLISION(): ArbiterType;
1388
+ static get SENSOR(): ArbiterType;
1389
+ static get FLUID(): ArbiterType;
1390
+ toString(): string;
1391
+ }
1392
+
1393
+ /**
1394
+ * Physical material properties applied to shapes.
1395
+ *
1396
+ * Controls elasticity (bounciness), friction coefficients, density, and
1397
+ * rolling friction. Internally wraps a ZPP_Material and is registered as
1398
+ * the public `nape.phys.Material` class in the compiled namespace.
1399
+ *
1400
+ * Converted from nape-compiled.js lines 38254–38573.
1401
+ */
1402
+ declare class Material {
1403
+ static __name__: string[];
1404
+ constructor(elasticity?: number, dynamicFriction?: number, staticFriction?: number, density?: number, rollingFriction?: number);
1405
+ get elasticity(): number;
1406
+ set elasticity(value: number);
1407
+ get dynamicFriction(): number;
1408
+ set dynamicFriction(value: number);
1409
+ get staticFriction(): number;
1410
+ set staticFriction(value: number);
1411
+ get density(): number;
1412
+ set density(value: number);
1413
+ get rollingFriction(): number;
1414
+ set rollingFriction(value: number);
1290
1415
  get userData(): Record<string, unknown>;
1416
+ copy(): Material;
1417
+ toString(): string;
1418
+ static wood(): Material;
1419
+ static steel(): Material;
1420
+ static ice(): Material;
1421
+ static rubber(): Material;
1422
+ static glass(): Material;
1423
+ static sand(): Material;
1424
+ }
1425
+
1426
+ /**
1427
+ * A convex polygon physics shape.
1428
+ */
1429
+ declare class Polygon extends Shape {
1430
+ static __name__: string[];
1431
+ static __super__: any;
1291
1432
  /**
1292
- * World gravity applied to all dynamic bodies each step. Live Vec2.
1293
- * @throws If set to null or a disposed Vec2.
1433
+ * Create a Polygon from a list of Vec2 vertices. Vertices must form a convex polygon
1434
+ * in counter-clockwise order.
1435
+ * @param localVerts - Vertices as `Array<Vec2>`, `Vec2List`, or `GeomPoly`.
1436
+ * @param material - Material to assign (uses default if omitted).
1437
+ * @param filter - InteractionFilter to assign (uses default if omitted).
1294
1438
  */
1295
- get gravity(): Vec2;
1296
- set gravity(value: Vec2);
1297
- /** The broadphase algorithm currently in use (SWEEP_AND_PRUNE or DYNAMIC_AABB_TREE). */
1298
- get broadphase(): Broadphase;
1299
- /** If true, contact points are sorted for determinism. Default: true. */
1300
- get sortContacts(): boolean;
1301
- set sortContacts(value: boolean);
1439
+ constructor(localVerts?: Vec2[] | any, material?: Material, filter?: InteractionFilter);
1302
1440
  /**
1303
- * Global angular drag coefficient applied to all bodies.
1304
- * @throws If set to NaN.
1441
+ * Create an axis-aligned rectangle at the given position.
1442
+ * @param x - Left edge x coordinate.
1443
+ * @param y - Top edge y coordinate.
1444
+ * @param width - Rectangle width.
1445
+ * @param height - Rectangle height.
1446
+ * @param weak - If true, returned Vec2s are marked weak and will be auto-disposed.
1447
+ * @returns Array of four Vec2 corner vertices.
1305
1448
  */
1306
- get worldAngularDrag(): number;
1307
- set worldAngularDrag(value: number);
1449
+ static rect(x: number, y: number, width: number, height: number, weak?: boolean): Vec2[];
1308
1450
  /**
1309
- * Global linear drag coefficient applied to all bodies.
1310
- * @throws If set to NaN.
1451
+ * Create an axis-aligned rectangular polygon centred at the origin.
1452
+ * @param width - Rectangle width.
1453
+ * @param height - Rectangle height (defaults to `width` for a square).
1454
+ * @param weak - If true, returned Vec2s are marked weak and will be auto-disposed.
1455
+ * @returns Array of four Vec2 corner vertices.
1311
1456
  */
1312
- get worldLinearDrag(): number;
1313
- set worldLinearDrag(value: number);
1314
- /** Read-only list of all Compound objects in this space. */
1315
- get compounds(): object;
1316
- /** Read-only list of all Body objects directly in this space. */
1317
- get bodies(): object;
1318
- /** Read-only list of bodies that are awake and actively simulated. */
1319
- get liveBodies(): object;
1320
- /** Read-only list of all Constraint objects in this space. */
1321
- get constraints(): object;
1322
- /** Read-only list of active (awake) constraints. */
1323
- get liveConstraints(): object;
1324
- /** The static world body that acts as an immovable anchor for constraints. */
1325
- get world(): Body;
1326
- /** Read-only list of all active collision/fluid arbiters. */
1327
- get arbiters(): object;
1328
- /** Read-only list of all event listeners registered to this space. */
1329
- get listeners(): object;
1330
- /** Number of `step()` calls made so far. */
1331
- get timeStamp(): number;
1332
- /** Cumulative time simulated (sum of all `deltaTime` values passed to `step()`). */
1333
- get elapsedTime(): number;
1457
+ static box(width: number, height?: number, weak?: boolean): Vec2[];
1334
1458
  /**
1335
- * Advance the simulation by `deltaTime` seconds.
1336
- * `velocityIterations` and `positionIterations` control solver accuracy (default 10 each).
1337
- * @param deltaTime - Time step in seconds; must be strictly positive and not NaN.
1338
- * @param velocityIterations - Number of velocity solver iterations (minimum 1).
1339
- * @param positionIterations - Number of position solver iterations (minimum 1).
1340
- * @throws If `deltaTime` is NaN, non-positive, or any iteration count is less than 1.
1459
+ * Create a regular polygon (or ellipse approximation) centred at the origin.
1460
+ * @param xRadius - Horizontal radius of the circumscribed ellipse.
1461
+ * @param yRadius - Vertical radius of the circumscribed ellipse.
1462
+ * @param edgeCount - Number of sides (must be >= 3).
1463
+ * @param angleOffset - Rotation offset in radians applied to all vertices (default 0).
1464
+ * @param weak - If true, returned Vec2s are marked weak and will be auto-disposed.
1465
+ * @returns Array of `edgeCount` Vec2 vertices.
1341
1466
  */
1342
- step(deltaTime: number, velocityIterations?: number, positionIterations?: number): void;
1467
+ static regular(xRadius: number, yRadius: number, edgeCount: number, angleOffset?: number, weak?: boolean): Vec2[];
1468
+ /** The list of local-space vertices defining this polygon's shape. */
1469
+ get localVerts(): any;
1470
+ /** World-space vertices of this polygon, updated each simulation step. */
1471
+ get worldVerts(): any;
1472
+ /** The list of edges derived from this polygon's vertices. */
1473
+ get edges(): any;
1343
1474
  /**
1344
- * Remove all bodies, constraints, and compounds from this space.
1345
- * @throws If called during a `step()`.
1475
+ * Validate the polygon geometry and return a string describing any issues, or
1476
+ * `"valid"` if the polygon is well-formed.
1477
+ * @returns A validation result string from the underlying ZPP_Polygon.
1346
1478
  */
1347
- clear(): void;
1479
+ validity(): any;
1480
+ }
1481
+
1482
+ /**
1483
+ * An edge of a polygon shape.
1484
+ *
1485
+ * Edges are read-only and managed by the polygon they belong to.
1486
+ * Cannot be instantiated directly — only obtained from Polygon.edges.
1487
+ *
1488
+ * Fully modernized — all getters access ZPP_Edge directly.
1489
+ */
1490
+ declare class Edge {
1491
+ static __name__: string[];
1492
+ constructor();
1493
+ /** Parent polygon. */
1494
+ get polygon(): Polygon;
1495
+ /** Local-space normal vector (immutable Vec2). */
1496
+ get localNormal(): Vec2;
1497
+ /** World-space normal vector (immutable Vec2). Requires polygon in a body. */
1498
+ get worldNormal(): Vec2;
1499
+ /** Edge length. */
1500
+ get length(): number;
1501
+ /** Local-space projection along the edge normal. */
1502
+ get localProjection(): number;
1503
+ /** World-space projection. Requires polygon in a body. */
1504
+ get worldProjection(): number;
1505
+ /** First local vertex of this edge. */
1506
+ get localVertex1(): Vec2;
1507
+ /** Second local vertex of this edge. */
1508
+ get localVertex2(): Vec2;
1509
+ /** First world vertex. Requires polygon in a body. */
1510
+ get worldVertex1(): Vec2;
1511
+ /** Second world vertex. Requires polygon in a body. */
1512
+ get worldVertex2(): Vec2;
1513
+ toString(): string;
1348
1514
  /**
1349
- * Call `lambda` for every body in the space, including those inside compounds.
1350
- * @param lambda - Callback invoked with each Body.
1351
- * @throws If `lambda` is null.
1515
+ * Wrap a ZPP_Vec2 vertex into its public Vec2 outer.
1516
+ * Mirrors the compiled vertex wrapping pattern.
1352
1517
  */
1353
- visitBodies(lambda: (body: Body) => void): void;
1518
+ private _wrapVert;
1519
+ }
1520
+
1521
+ /**
1522
+ * An arbiter representing a physical collision between two solid shapes.
1523
+ *
1524
+ * Provides access to contact points, collision normal, friction coefficients,
1525
+ * elasticity, and impulse data. Properties marked _mutable in pre-handler_ can
1526
+ * only be set within a {@link PreListener} handler.
1527
+ *
1528
+ * Obtain via {@link Arbiter.collisionArbiter} or by casting from a callback's
1529
+ * arbiter list.
1530
+ *
1531
+ * Fully modernized — uses extracted ZPP_ColArbiter directly.
1532
+ */
1533
+ declare class CollisionArbiter extends Arbiter {
1534
+ static __name__: string[];
1535
+ static __super__: typeof Arbiter;
1536
+ constructor();
1354
1537
  /**
1355
- * Call `lambda` for every constraint in the space, including those inside compounds.
1356
- * @param lambda - Callback invoked with each Constraint.
1357
- * @throws If `lambda` is null.
1538
+ * The list of active contact points between the two shapes.
1539
+ * Contains 1 or 2 {@link Contact} objects depending on the collision geometry.
1358
1540
  */
1359
- visitConstraints(lambda: (constraint: Constraint) => void): void;
1541
+ get contacts(): object;
1360
1542
  /**
1361
- * Call `lambda` for every compound in the space (recursively).
1362
- * @param lambda - Callback invoked with each Compound.
1363
- * @throws If `lambda` is null.
1543
+ * Collision normal vector pointing from `shape1` toward `shape2`.
1544
+ * Read-only; available after the arbiter is active.
1364
1545
  */
1365
- visitCompounds(lambda: (compound: Compound) => void): void;
1366
- /**
1367
- * Determine the type of interaction between two shapes (COLLISION, FLUID, SENSOR, or null if they don't interact).
1368
- * @param shape1 - The first shape; must belong to a Body.
1369
- * @param shape2 - The second shape; must belong to a Body.
1370
- * @returns The InteractionType, or null if the shapes would not interact.
1371
- * @throws If either shape is null or not attached to a Body.
1372
- */
1373
- interactionType(shape1: Shape, shape2: Shape): InteractionType | null;
1374
- /**
1375
- * Return all shapes whose geometry contains the given world-space point.
1376
- * @param point - The world-space point to test.
1377
- * @param filter - Optional interaction filter to restrict results.
1378
- * @param output - Optional existing ShapeList to accumulate results into.
1379
- * @returns A ShapeList of matching shapes.
1380
- * @throws If `point` is null or disposed.
1381
- */
1382
- shapesUnderPoint(point: Vec2, filter?: InteractionFilter | null, output?: object | null): object;
1383
- /**
1384
- * Return all bodies that have at least one shape containing the given world-space point.
1385
- * @param point - The world-space point to test.
1386
- * @param filter - Optional interaction filter to restrict results.
1387
- * @param output - Optional existing BodyList to accumulate results into.
1388
- * @returns A BodyList of matching bodies.
1389
- * @throws If `point` is null or disposed.
1390
- */
1391
- bodiesUnderPoint(point: Vec2, filter?: InteractionFilter | null, output?: object | null): object;
1392
- /**
1393
- * Return all shapes that overlap with the given AABB.
1394
- * @param aabb - The axis-aligned bounding box to test against.
1395
- * @param containment - If true, only shapes fully contained within the AABB are returned.
1396
- * @param strict - If true, exact shape geometry is tested; otherwise only AABBs are compared.
1397
- * @param filter - Optional interaction filter to restrict results.
1398
- * @param output - Optional existing ShapeList to accumulate results into.
1399
- * @returns A ShapeList of matching shapes.
1400
- * @throws If `aabb` is null or degenerate (zero width or height).
1401
- */
1402
- shapesInAABB(aabb: AABB, containment?: boolean, strict?: boolean, filter?: InteractionFilter | null, output?: object | null): object;
1403
- /**
1404
- * Return all bodies that have at least one shape overlapping the given AABB.
1405
- * @param aabb - The axis-aligned bounding box to test against.
1406
- * @param containment - If true, only shapes fully contained within the AABB count.
1407
- * @param strict - If true, exact shape geometry is tested; otherwise only AABBs are compared.
1408
- * @param filter - Optional interaction filter to restrict results.
1409
- * @param output - Optional existing BodyList to accumulate results into.
1410
- * @returns A BodyList of matching bodies.
1411
- * @throws If `aabb` is null or degenerate (zero width or height).
1412
- */
1413
- bodiesInAABB(aabb: AABB, containment?: boolean, strict?: boolean, filter?: InteractionFilter | null, output?: object | null): object;
1546
+ get normal(): Vec2;
1547
+ /** Sum of the radii of the two shapes at the collision point. */
1548
+ get radius(): number;
1549
+ /** Reference edge of shape1 (if polygon), or null. */
1550
+ get referenceEdge1(): Edge | null;
1551
+ /** Reference edge of shape2 (if polygon), or null. */
1552
+ get referenceEdge2(): Edge | null;
1414
1553
  /**
1415
- * Return all shapes that overlap with a circle defined by `position` and `radius`.
1416
- * @param position - World-space centre of the query circle.
1417
- * @param radius - Radius of the query circle; must be strictly positive and not NaN.
1418
- * @param containment - If true, only shapes fully contained within the circle are returned.
1419
- * @param filter - Optional interaction filter to restrict results.
1420
- * @param output - Optional existing ShapeList to accumulate results into.
1421
- * @returns A ShapeList of matching shapes.
1422
- * @throws If `position` is null/disposed, or `radius` is NaN or non-positive.
1554
+ * Coefficient of restitution (bounciness).
1555
+ *
1556
+ * Combined from the two shapes' `elasticity` values. Can be overridden
1557
+ * inside a pre-handler. Must be `>= 0`.
1558
+ *
1559
+ * _Mutable in pre-handler only._
1423
1560
  */
1424
- shapesInCircle(position: Vec2, radius: number, containment?: boolean, filter?: InteractionFilter | null, output?: object | null): object;
1561
+ get elasticity(): number;
1562
+ set elasticity(value: number);
1425
1563
  /**
1426
- * Return all bodies that have at least one shape overlapping a query circle.
1427
- * @param position - World-space centre of the query circle.
1428
- * @param radius - Radius of the query circle; must be strictly positive and not NaN.
1429
- * @param containment - If true, only shapes fully contained within the circle count.
1430
- * @param filter - Optional interaction filter to restrict results.
1431
- * @param output - Optional existing BodyList to accumulate results into.
1432
- * @returns A BodyList of matching bodies.
1433
- * @throws If `position` is null/disposed, or `radius` is NaN or non-positive.
1564
+ * Dynamic (kinetic) friction coefficient applied when the contact is sliding.
1565
+ * Combined from the two shapes' material values. _Mutable in pre-handler only._
1434
1566
  */
1435
- bodiesInCircle(position: Vec2, radius: number, containment?: boolean, filter?: InteractionFilter | null, output?: object | null): object;
1567
+ get dynamicFriction(): number;
1568
+ set dynamicFriction(value: number);
1436
1569
  /**
1437
- * Return all shapes in the space that overlap with `shape`.
1438
- * @param shape - The query shape; must be attached to a Body.
1439
- * @param containment - If true, only shapes fully contained within `shape` are returned.
1440
- * @param filter - Optional interaction filter to restrict results.
1441
- * @param output - Optional existing ShapeList to accumulate results into.
1442
- * @returns A ShapeList of overlapping shapes.
1443
- * @throws If `shape` is null, not attached to a Body, or is an invalid polygon.
1570
+ * Static friction coefficient applied when the contact is at rest.
1571
+ * Combined from the two shapes' material values. _Mutable in pre-handler only._
1444
1572
  */
1445
- shapesInShape(shape: Shape, containment?: boolean, filter?: InteractionFilter | null, output?: object | null): object;
1573
+ get staticFriction(): number;
1574
+ set staticFriction(value: number);
1446
1575
  /**
1447
- * Return all bodies in the space that have at least one shape overlapping `shape`.
1448
- * @param shape - The query shape; must be attached to a Body.
1449
- * @param containment - If true, only shapes fully contained within `shape` count.
1450
- * @param filter - Optional interaction filter to restrict results.
1451
- * @param output - Optional existing BodyList to accumulate results into.
1452
- * @returns A BodyList of overlapping bodies.
1453
- * @throws If `shape` is null, not attached to a Body, or is an invalid polygon.
1576
+ * Rolling friction coefficient resists rolling motion.
1577
+ * Combined from the two shapes' material values. _Mutable in pre-handler only._
1454
1578
  */
1455
- bodiesInShape(shape: Shape, containment?: boolean, filter?: InteractionFilter | null, output?: object | null): object;
1579
+ get rollingFriction(): number;
1580
+ set rollingFriction(value: number);
1581
+ /** Whether the first contact point lies on a polygon vertex (poly-circle only). */
1582
+ firstVertex(): boolean;
1583
+ /** Whether the second contact point lies on a polygon vertex (poly-circle only). */
1584
+ secondVertex(): boolean;
1456
1585
  /**
1457
- * Return all shapes in the space that overlap with any shape attached to `body`.
1458
- * Equivalent to calling `shapesInShape` for each of `body`'s shapes and merging results.
1459
- * @param body - The body whose shapes are used as the query region.
1460
- * @param filter - Optional interaction filter to restrict results.
1461
- * @param output - Optional existing ShapeList to accumulate results into.
1462
- * @returns A ShapeList of overlapping shapes.
1463
- * @throws If `body` is null.
1586
+ * Impulse applied in the normal (collision) direction, summed over all contacts.
1587
+ * @param body - One of the two bodies, or `null` for the combined value.
1588
+ * @param freshOnly - Only include new contact points. Default `false`.
1464
1589
  */
1465
- shapesInBody(body: Body, filter?: InteractionFilter | null, output?: object | null): object;
1590
+ normalImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
1466
1591
  /**
1467
- * Return all bodies in the space that overlap with any shape attached to `body`.
1468
- * Equivalent to calling `bodiesInShape` for each of `body`'s shapes and merging results.
1469
- * @param body - The body whose shapes are used as the query region.
1470
- * @param filter - Optional interaction filter to restrict results.
1471
- * @param output - Optional existing BodyList to accumulate results into.
1472
- * @returns A BodyList of overlapping bodies.
1473
- * @throws If `body` is null.
1592
+ * Friction impulse applied in the tangent direction, summed over all contacts.
1593
+ * @param body - One of the two bodies, or `null` for the combined value.
1594
+ * @param freshOnly - Only include new contact points. Default `false`.
1474
1595
  */
1475
- bodiesInBody(body: Body, filter?: InteractionFilter | null, output?: object | null): object;
1596
+ tangentImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
1597
+ /** Total impulse (normal + tangent + rolling) accumulated across all contacts. */
1598
+ totalImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
1476
1599
  /**
1477
- * Sweep `shape` along its current velocity for `deltaTime` seconds and return the first hit.
1478
- * @param shape - The shape to sweep; must belong to a Body.
1479
- * @param deltaTime - Duration of the sweep; must be non-negative.
1480
- * @param liveSweep - If true, other body velocities are considered during the sweep.
1481
- * @param filter - Optional interaction filter to restrict results.
1482
- * @returns The first RayResult hit, or null if nothing was struck.
1483
- * @throws If `shape` is null, not attached to a Body, or `deltaTime` is negative/NaN.
1600
+ * Rolling impulse applied by this collision.
1601
+ * @param body - One of the two bodies, or `null` for the combined value.
1602
+ * @param freshOnly - Only include new contact points. Default `false`.
1484
1603
  */
1485
- convexCast(shape: Shape, deltaTime: number, liveSweep?: boolean, filter?: InteractionFilter | null): object | null;
1604
+ rollingImpulse(body?: Body | null, freshOnly?: boolean): number;
1605
+ }
1606
+
1607
+ /**
1608
+ * An arbiter representing a fluid interaction between a fluid shape and a body.
1609
+ *
1610
+ * Provides access to buoyancy and drag impulses, the overlap area, and the
1611
+ * centre of overlap. Properties marked _mutable in pre-handler_ can only be
1612
+ * set within a {@link PreListener} handler.
1613
+ *
1614
+ * Obtain via {@link Arbiter.fluidArbiter} or by casting from a callback arbiter.
1615
+ *
1616
+ * Fully modernized — uses extracted ZPP_FluidArbiter directly.
1617
+ */
1618
+ declare class FluidArbiter extends Arbiter {
1619
+ static __name__: string[];
1620
+ static __super__: typeof Arbiter;
1621
+ constructor();
1486
1622
  /**
1487
- * Sweep `shape` along its current velocity for `deltaTime` seconds and return all hits.
1488
- * @param shape - The shape to sweep; must belong to a Body.
1489
- * @param deltaTime - Duration of the sweep; must be non-negative.
1490
- * @param liveSweep - If true, other body velocities are considered during the sweep.
1491
- * @param filter - Optional interaction filter to restrict results.
1492
- * @param output - Optional existing RayResultList to accumulate results into.
1493
- * @returns A RayResultList of all hits encountered during the sweep.
1494
- * @throws If `shape` is null, not attached to a Body, or `deltaTime` is negative/NaN.
1623
+ * Centre of the overlap region between the fluid and the body shape.
1624
+ * _Mutable in pre-handler only._
1495
1625
  */
1496
- convexMultiCast(shape: Shape, deltaTime: number, liveSweep?: boolean, filter?: InteractionFilter | null, output?: object | null): object;
1626
+ get position(): Vec2;
1627
+ set position(value: Vec2);
1497
1628
  /**
1498
- * Cast a ray into the space and return the closest hit.
1499
- * @param ray - The ray to cast.
1500
- * @param inner - If true, shapes are tested from the inside as well (useful for concave queries).
1501
- * @param filter - Optional interaction filter to restrict results.
1502
- * @returns The closest RayResult, or null if nothing was hit.
1503
- * @throws If `ray` is null.
1629
+ * Area of the overlap region in pixels². Used to compute buoyancy force.
1630
+ * Must be strictly positive and finite.
1631
+ * _Mutable in pre-handler only._
1504
1632
  */
1505
- rayCast(ray: Ray, inner?: boolean, filter?: InteractionFilter | null): object | null;
1633
+ get overlap(): number;
1634
+ set overlap(value: number);
1506
1635
  /**
1507
- * Cast a ray into the space and return all hits.
1508
- * @param ray - The ray to cast.
1509
- * @param inner - If true, shapes are tested from the inside as well.
1510
- * @param filter - Optional interaction filter to restrict results.
1511
- * @param output - Optional existing RayResultList to accumulate results into.
1512
- * @returns A RayResultList of all shapes the ray intersected.
1513
- * @throws If `ray` is null.
1636
+ * Buoyancy impulse applied in the last step as `(fx, fy, torque)`.
1637
+ * @param body - One of the two bodies, or `null` for the combined value.
1514
1638
  */
1515
- rayMultiCast(ray: Ray, inner?: boolean, filter?: InteractionFilter | null, output?: object | null): object;
1639
+ buoyancyImpulse(body?: Body | null): Vec3;
1516
1640
  /**
1517
- * Returns a brief string summary of this space.
1518
- * @returns A string in the form `Space(bodies=N)`.
1641
+ * Linear and angular drag impulse applied in the last step as `(fx, fy, torque)`.
1642
+ * @param body - One of the two bodies, or `null` for the combined value.
1519
1643
  */
1520
- toString(): string;
1644
+ dragImpulse(body?: Body | null): Vec3;
1645
+ /** Total impulse (buoyancy + drag). */
1646
+ totalImpulse(body?: Body | null, _freshOnly?: boolean): Vec3;
1521
1647
  }
1522
1648
 
1523
1649
  /**
1524
- * Body type enumeration.
1650
+ * Return value for {@link PreListener} handlers — controls whether the interaction
1651
+ * is resolved this step and in future steps.
1525
1652
  *
1526
- * - `STATIC` immovable, infinite mass (walls, floors)
1527
- * - `DYNAMIC` fully simulated (default)
1528
- * - `KINEMATIC` — moves only via velocity, not affected by forces
1653
+ * - `ACCEPT` resolve the interaction (default if handler returns `null`)
1654
+ * - `IGNORE` suppress the interaction permanently until the next `BEGIN`
1655
+ * - `ACCEPT_ONCE` — accept this step only, then revert to the previous flag
1656
+ * - `IGNORE_ONCE` — ignore this step only, then revert to the previous flag
1529
1657
  *
1530
- * Converted from nape-compiled.js lines 24640–24705.
1658
+ * Use `IGNORE`/`ACCEPT` for stateful decisions (e.g., one-way platforms).
1659
+ * Use `*_ONCE` variants for single-step overrides.
1660
+ *
1661
+ * Converted from nape-compiled.js lines 2504–2591.
1531
1662
  */
1532
- declare class BodyType {
1663
+ declare class PreFlag {
1533
1664
  static __name__: string[];
1534
1665
  constructor();
1535
- static get STATIC(): BodyType;
1536
- static get DYNAMIC(): BodyType;
1537
- static get KINEMATIC(): BodyType;
1666
+ /** Accept and resolve the interaction normally. */
1667
+ static get ACCEPT(): PreFlag;
1668
+ /** Suppress the interaction permanently until the next `BEGIN` event. */
1669
+ static get IGNORE(): PreFlag;
1670
+ /** Accept this step only; revert to the previous flag next step. */
1671
+ static get ACCEPT_ONCE(): PreFlag;
1672
+ /** Ignore this step only; revert to the previous flag next step. */
1673
+ static get IGNORE_ONCE(): PreFlag;
1538
1674
  toString(): string;
1539
1675
  }
1540
1676
 
1541
1677
  /**
1542
- * Physical material properties applied to shapes.
1678
+ * Represents an active interaction between two shapes.
1543
1679
  *
1544
- * Controls elasticity (bounciness), friction coefficients, density, and
1545
- * rolling friction. Internally wraps a ZPP_Material and is registered as
1546
- * the public `nape.phys.Material` class in the compiled namespace.
1680
+ * Arbiters are created and pooled internally by the engine — they cannot be
1681
+ * instantiated directly. Access them via:
1682
+ * - `space.arbiters` all active arbiters in the simulation
1683
+ * - `body.arbiters` — arbiters involving a specific body
1684
+ * - `InteractionCallback.arbiters` — arbiters in an interaction callback
1685
+ * - `PreCallback.arbiter` — the arbiter in a pre-handler
1547
1686
  *
1548
- * Converted from nape-compiled.js lines 38254–38573.
1687
+ * Use {@link Arbiter.collisionArbiter} or {@link Arbiter.fluidArbiter} to cast
1688
+ * to a subtype for type-specific properties.
1689
+ *
1690
+ * **Warning:** do not hold references to `Arbiter` objects after the current
1691
+ * simulation step — they are pooled and may be reused.
1692
+ *
1693
+ * Fully modernized — uses extracted ZPP_Arbiter directly.
1549
1694
  */
1550
- declare class Material {
1695
+ declare class Arbiter {
1551
1696
  static __name__: string[];
1552
- constructor(elasticity?: number, dynamicFriction?: number, staticFriction?: number, density?: number, rollingFriction?: number);
1553
- get elasticity(): number;
1554
- set elasticity(value: number);
1555
- get dynamicFriction(): number;
1556
- set dynamicFriction(value: number);
1557
- get staticFriction(): number;
1558
- set staticFriction(value: number);
1559
- get density(): number;
1560
- set density(value: number);
1561
- get rollingFriction(): number;
1562
- set rollingFriction(value: number);
1563
- get userData(): Record<string, unknown>;
1564
- copy(): Material;
1697
+ constructor();
1698
+ /**
1699
+ * Whether both interacting bodies are currently sleeping.
1700
+ * Throws if the arbiter is not active.
1701
+ */
1702
+ get isSleeping(): boolean;
1703
+ /**
1704
+ * The interaction type of this arbiter.
1705
+ * @see {@link ArbiterType}
1706
+ */
1707
+ get type(): ArbiterType;
1708
+ /** Cast to CollisionArbiter if this is a collision, else null. */
1709
+ get collisionArbiter(): CollisionArbiter | null;
1710
+ /** Cast to FluidArbiter if this is a fluid interaction, else null. */
1711
+ get fluidArbiter(): FluidArbiter | null;
1712
+ /** First shape (lower id). */
1713
+ get shape1(): Shape;
1714
+ /** Second shape (higher id). */
1715
+ get shape2(): Shape;
1716
+ /** Body of shape1. */
1717
+ get body1(): Body;
1718
+ /** Body of shape2. */
1719
+ get body2(): Body;
1720
+ /** The pre-handler state of this arbiter. */
1721
+ get state(): PreFlag;
1722
+ /** Whether this is a collision arbiter. */
1723
+ isCollisionArbiter(): boolean;
1724
+ /** Whether this is a fluid arbiter. */
1725
+ isFluidArbiter(): boolean;
1726
+ /** Whether this is a sensor arbiter. */
1727
+ isSensorArbiter(): boolean;
1728
+ /**
1729
+ * Total impulse applied by this arbiter in the last step as `(fx, fy, torque)`.
1730
+ *
1731
+ * Pass a `body` to get the impulse applied specifically to that body.
1732
+ * Pass `freshOnly = true` to include only new contact points (not persistent ones).
1733
+ *
1734
+ * Overridden by {@link CollisionArbiter} and {@link FluidArbiter}.
1735
+ *
1736
+ * @param body - One of the two interacting bodies, or `null` for the combined impulse.
1737
+ * @param _freshOnly - When `true`, only count fresh (new) contacts. Default `false`.
1738
+ */
1739
+ totalImpulse(body?: Body | null, _freshOnly?: boolean): Vec3;
1565
1740
  toString(): string;
1566
- static wood(): Material;
1567
- static steel(): Material;
1568
- static ice(): Material;
1569
- static rubber(): Material;
1570
- static glass(): Material;
1571
- static sand(): Material;
1572
1741
  }
1573
1742
 
1574
1743
  /**
1575
- * Fluid properties for shapes that act as fluid regions.
1744
+ * Enumeration of physics callback event types.
1576
1745
  *
1577
- * Controls density, viscosity, and per-fluid gravity override.
1578
- * Internally wraps a ZPP_FluidProperties and is registered as
1579
- * the public `nape.phys.FluidProperties` class in the compiled namespace.
1746
+ * Use these singletons to specify which phase of an interaction a listener
1747
+ * should respond to:
1580
1748
  *
1581
- * Converted from nape-compiled.js lines 37002–37511.
1749
+ * - `BEGIN` — fired once when two interactors first make contact
1750
+ * - `ONGOING` — fired every simulation step while the interaction persists
1751
+ * - `END` — fired once when two interactors separate
1752
+ * - `WAKE` — fired when a body or constraint wakes from sleep
1753
+ * - `SLEEP` — fired when a body or constraint falls asleep
1754
+ * - `BREAK` — fired when a constraint exceeds its `maxForce`/`maxError` and breaks
1755
+ * - `PRE` — fired before collision resolution; allows per-step accept/ignore decisions
1756
+ *
1757
+ * Valid events per listener type:
1758
+ * - {@link BodyListener}: `WAKE`, `SLEEP`
1759
+ * - {@link ConstraintListener}: `WAKE`, `SLEEP`, `BREAK`
1760
+ * - {@link InteractionListener}: `BEGIN`, `ONGOING`, `END`
1761
+ * - {@link PreListener}: always `PRE` (set internally)
1762
+ *
1763
+ * Converted from nape-compiled.js lines 516–657.
1582
1764
  */
1583
- declare class FluidProperties {
1765
+ declare class CbEvent {
1584
1766
  static __name__: string[];
1585
- constructor(density?: number, viscosity?: number);
1586
- get density(): number;
1587
- set density(value: number);
1588
- get viscosity(): number;
1589
- set viscosity(value: number);
1590
- get gravity(): any;
1591
- set gravity(gravity: any);
1592
- get userData(): Record<string, unknown>;
1593
- get shapes(): any;
1594
- copy(): FluidProperties;
1767
+ constructor();
1768
+ /** Interaction-start event. Fired once when two interactors first make contact. */
1769
+ static get BEGIN(): CbEvent;
1770
+ /** Interaction-continue event. Fired every step while the interaction persists. */
1771
+ static get ONGOING(): CbEvent;
1772
+ /** Interaction-end event. Fired once when two interactors separate. */
1773
+ static get END(): CbEvent;
1774
+ /** Wake event. Fired when a body or constraint wakes from sleep. */
1775
+ static get WAKE(): CbEvent;
1776
+ /** Sleep event. Fired when a body or constraint falls asleep. */
1777
+ static get SLEEP(): CbEvent;
1778
+ /** Break event. Fired when a constraint exceeds its `maxForce` or `maxError` limit. */
1779
+ static get BREAK(): CbEvent;
1780
+ /** Pre-interaction event. Fired before collision resolution; handler can accept or ignore. */
1781
+ static get PRE(): CbEvent;
1595
1782
  toString(): string;
1596
1783
  }
1597
1784
 
1598
1785
  /**
1599
- * Mass mode for a body.
1786
+ * Listener type classification.
1600
1787
  *
1601
- * - `DEFAULT` use computed mass from shapes
1602
- * - `FIXED` use a fixed mass value
1788
+ * - `BODY` body event listener
1789
+ * - `CONSTRAINT` constraint event listener
1790
+ * - `INTERACTION` — interaction event listener
1791
+ * - `PRE` — pre-interaction listener
1603
1792
  *
1604
- * Converted from nape-compiled.js lines 2696627013.
1793
+ * Converted from nape-compiled.js lines 25542646.
1605
1794
  */
1606
- declare class MassMode {
1795
+ declare class ListenerType {
1607
1796
  static __name__: string[];
1608
1797
  constructor();
1609
- static get DEFAULT(): MassMode;
1610
- static get FIXED(): MassMode;
1798
+ static get BODY(): ListenerType;
1799
+ static get CONSTRAINT(): ListenerType;
1800
+ static get INTERACTION(): ListenerType;
1801
+ static get PRE(): ListenerType;
1611
1802
  toString(): string;
1612
1803
  }
1613
1804
 
1614
1805
  /**
1615
- * Inertia mode for a body.
1806
+ * Listener Base class for all physics event listeners.
1616
1807
  *
1617
- * - `DEFAULT` use computed inertia from shapes
1618
- * - `FIXED` — use a fixed inertia value
1808
+ * Provides common properties (type, event, precedence, space) and
1809
+ * toString() for all listener subclasses.
1619
1810
  *
1620
- * Converted from nape-compiled.js lines 2634326390.
1811
+ * Fully modernized from nape-compiled.js lines 231433.
1621
1812
  */
1622
- declare class InertiaMode {
1623
- static __name__: string[];
1624
- constructor();
1625
- static get DEFAULT(): InertiaMode;
1626
- static get FIXED(): InertiaMode;
1627
- toString(): string;
1628
- }
1629
1813
 
1630
1814
  /**
1631
- * Gravity mass mode for a body.
1815
+ * Base class for all physics event listeners.
1632
1816
  *
1633
- * - `DEFAULT` — use computed mass for gravity
1634
- * - `FIXED` — use a fixed gravity mass value
1635
- * - `SCALED` — scale the computed gravity mass
1817
+ * Cannot be instantiated directly — use one of the concrete subclasses:
1818
+ * {@link BodyListener}, {@link ConstraintListener}, {@link InteractionListener},
1819
+ * or {@link PreListener}.
1636
1820
  *
1637
- * Converted from nape-compiled.js lines 26272–26342.
1821
+ * Provides common properties (`type`, `event`, `precedence`, `space`) shared
1822
+ * by all listener types.
1823
+ *
1824
+ * Fully modernized from nape-compiled.js lines 231–433.
1638
1825
  */
1639
- declare class GravMassMode {
1826
+ declare class Listener {
1640
1827
  static __name__: string[];
1641
1828
  constructor();
1642
- static get DEFAULT(): GravMassMode;
1643
- static get FIXED(): GravMassMode;
1644
- static get SCALED(): GravMassMode;
1829
+ /** The type of this listener (BODY, CONSTRAINT, INTERACTION, or PRE). */
1830
+ get type(): ListenerType;
1831
+ /**
1832
+ * The event this listener responds to.
1833
+ *
1834
+ * Valid values depend on the concrete listener type — see {@link CbEvent}.
1835
+ * Changing this while the listener is assigned to a space re-registers it.
1836
+ */
1837
+ get event(): CbEvent;
1838
+ set event(event: CbEvent);
1839
+ /**
1840
+ * Execution priority of this listener relative to other listeners for the
1841
+ * same event. Higher values execute first.
1842
+ *
1843
+ * @defaultValue `0`
1844
+ */
1845
+ get precedence(): number;
1846
+ set precedence(precedence: number);
1847
+ /**
1848
+ * The space this listener is currently registered in, or `null` if not registered.
1849
+ *
1850
+ * Assign to register/unregister the listener in a space:
1851
+ * ```ts
1852
+ * listener.space = mySpace; // register
1853
+ * listener.space = null; // unregister
1854
+ * ```
1855
+ */
1856
+ get space(): Space | null;
1857
+ set space(space: Space | null);
1645
1858
  toString(): string;
1646
1859
  }
1647
1860
 
1648
1861
  /**
1649
- * A rigid body in the physics simulation. Add shapes to give it geometry, then add it to a `Space` to participate in simulation.
1862
+ * Concrete type aliases for all dynamically-generated Nape list classes.
1863
+ *
1864
+ * These aliases use {@link TypedListLike} to give IDE-visible types to the
1865
+ * return values of Space and Body query methods, without requiring the
1866
+ * dynamic list classes to be statically importable.
1650
1867
  */
1651
- declare class Body extends Interactor {
1652
- static __name__: string[];
1653
- static __super__: typeof Interactor;
1654
- /** If true, this body is included in debug rendering. */
1655
- debugDraw: boolean;
1868
+
1869
+ type BodyList = TypedListLike<Body>;
1870
+ type CompoundList = TypedListLike<Compound>;
1871
+ type ShapeList = TypedListLike<Shape>;
1872
+ type ConstraintList = TypedListLike<Constraint>;
1873
+ type ArbiterList = TypedListLike<Arbiter>;
1874
+ type ListenerList = TypedListLike<Listener>;
1875
+ type RayResultList = TypedListLike<RayResult>;
1876
+ type ConvexResultList = TypedListLike<ConvexResult>;
1877
+
1878
+ /**
1879
+ * The physics world. Add bodies, shapes, and constraints, then call `step()` each frame to advance the simulation.
1880
+ */
1881
+ declare class Space {
1656
1882
  /**
1657
- * @param type - Body type (DYNAMIC by default).
1658
- * @param position - Initial world-space position (defaults to origin).
1883
+ * @param gravity - Initial gravity vector (default (0, 0)).
1884
+ * @param broadphase - Broadphase algorithm to use.
1659
1885
  */
1660
- constructor(type?: BodyType, position?: Vec2);
1661
- /** The body type: DYNAMIC, STATIC, or KINEMATIC. Cannot be changed mid-step. */
1662
- get type(): BodyType;
1663
- set type(value: BodyType);
1664
- /** Return true if this body is static. */
1665
- isStatic(): boolean;
1666
- /** Return true if this body is dynamic. */
1667
- isDynamic(): boolean;
1668
- /** Return true if this body is kinematic. */
1669
- isKinematic(): boolean;
1670
- /** World-space position of the body's origin. Live Vec2 — mutating it moves the body. */
1671
- get position(): Vec2;
1672
- set position(value: Vec2);
1886
+ constructor(gravity?: Vec2, broadphase?: Broadphase);
1887
+ /** Arbitrary user data attached to this Space. */
1888
+ get userData(): Record<string, unknown>;
1673
1889
  /**
1674
- * Rotation of the body in radians.
1675
- * @throws If set on a static body that is already in a space.
1890
+ * World gravity applied to all dynamic bodies each step. Live Vec2.
1891
+ * @throws If set to null or a disposed Vec2.
1676
1892
  */
1677
- get rotation(): number;
1678
- set rotation(value: number);
1679
- /** Linear velocity in world space (units/s). Live Vec2. Static bodies cannot have velocity. */
1680
- get velocity(): Vec2;
1681
- set velocity(value: Vec2);
1682
- /** Angular velocity in radians per second. */
1683
- get angularVel(): number;
1684
- set angularVel(value: number);
1685
- /** Desired velocity for kinematic bodies; the engine tries to match this each step. */
1686
- get kinematicVel(): Vec2;
1687
- set kinematicVel(value: Vec2);
1688
- /** Desired angular velocity for kinematic bodies. */
1689
- get kinAngVel(): number;
1690
- set kinAngVel(value: number);
1691
- /** Surface velocity used in friction calculations. */
1692
- get surfaceVel(): Vec2;
1693
- set surfaceVel(value: Vec2);
1694
- /** Accumulated force applied to this body for the current step (cleared after each step). */
1695
- get force(): Vec2;
1696
- set force(value: Vec2);
1697
- /** Accumulated torque applied to this body for the current step (only for DYNAMIC bodies). */
1698
- get torque(): number;
1699
- set torque(value: number);
1893
+ get gravity(): Vec2;
1894
+ set gravity(value: Vec2);
1895
+ /** The broadphase algorithm currently in use (SWEEP_AND_PRUNE or DYNAMIC_AABB_TREE). */
1896
+ get broadphase(): Broadphase;
1897
+ /** If true, contact points are sorted for determinism. Default: true. */
1898
+ get sortContacts(): boolean;
1899
+ set sortContacts(value: boolean);
1700
1900
  /**
1701
- * Mass in kg. Must be finite and > 0. Setting switches massMode to FIXED.
1702
- * @throws If the body is the world body, or if no shapes are present in DEFAULT mass mode.
1901
+ * Global angular drag coefficient applied to all bodies.
1902
+ * @throws If set to NaN.
1703
1903
  */
1704
- get mass(): number;
1705
- set mass(value: number);
1904
+ get worldAngularDrag(): number;
1905
+ set worldAngularDrag(value: number);
1706
1906
  /**
1707
- * Moment of inertia. Must be finite and > 0. Setting switches inertiaMode to FIXED.
1907
+ * Global linear drag coefficient applied to all bodies.
1908
+ * @throws If set to NaN.
1909
+ */
1910
+ get worldLinearDrag(): number;
1911
+ set worldLinearDrag(value: number);
1912
+ /** Read-only list of all Compound objects in this space. */
1913
+ get compounds(): CompoundList;
1914
+ /** Read-only list of all Body objects directly in this space. */
1915
+ get bodies(): BodyList;
1916
+ /** Read-only list of bodies that are awake and actively simulated. */
1917
+ get liveBodies(): BodyList;
1918
+ /** Read-only list of all Constraint objects in this space. */
1919
+ get constraints(): ConstraintList;
1920
+ /** Read-only list of active (awake) constraints. */
1921
+ get liveConstraints(): ConstraintList;
1922
+ /** The static world body that acts as an immovable anchor for constraints. */
1923
+ get world(): Body;
1924
+ /** Read-only list of all active collision/fluid arbiters. */
1925
+ get arbiters(): ArbiterList;
1926
+ /** Read-only list of all event listeners registered to this space. */
1927
+ get listeners(): ListenerList;
1928
+ /** Number of `step()` calls made so far. */
1929
+ get timeStamp(): number;
1930
+ /** Cumulative time simulated (sum of all `deltaTime` values passed to `step()`). */
1931
+ get elapsedTime(): number;
1932
+ /**
1933
+ * Advance the simulation by `deltaTime` seconds.
1934
+ * `velocityIterations` and `positionIterations` control solver accuracy (default 10 each).
1935
+ * @param deltaTime - Time step in seconds; must be strictly positive and not NaN.
1936
+ * @param velocityIterations - Number of velocity solver iterations (minimum 1).
1937
+ * @param positionIterations - Number of position solver iterations (minimum 1).
1938
+ * @throws If `deltaTime` is NaN, non-positive, or any iteration count is less than 1.
1939
+ */
1940
+ step(deltaTime: number, velocityIterations?: number, positionIterations?: number): void;
1941
+ /**
1942
+ * Remove all bodies, constraints, and compounds from this space.
1943
+ * @throws If called during a `step()`.
1944
+ */
1945
+ clear(): void;
1946
+ /**
1947
+ * Call `lambda` for every body in the space, including those inside compounds.
1948
+ * @param lambda - Callback invoked with each Body.
1949
+ * @throws If `lambda` is null.
1950
+ */
1951
+ visitBodies(lambda: (body: Body) => void): void;
1952
+ /**
1953
+ * Call `lambda` for every constraint in the space, including those inside compounds.
1954
+ * @param lambda - Callback invoked with each Constraint.
1955
+ * @throws If `lambda` is null.
1956
+ */
1957
+ visitConstraints(lambda: (constraint: Constraint) => void): void;
1958
+ /**
1959
+ * Call `lambda` for every compound in the space (recursively).
1960
+ * @param lambda - Callback invoked with each Compound.
1961
+ * @throws If `lambda` is null.
1962
+ */
1963
+ visitCompounds(lambda: (compound: Compound) => void): void;
1964
+ /**
1965
+ * Determine the type of interaction between two shapes (COLLISION, FLUID, SENSOR, or null if they don't interact).
1966
+ * @param shape1 - The first shape; must belong to a Body.
1967
+ * @param shape2 - The second shape; must belong to a Body.
1968
+ * @returns The InteractionType, or null if the shapes would not interact.
1969
+ * @throws If either shape is null or not attached to a Body.
1970
+ */
1971
+ interactionType(shape1: Shape, shape2: Shape): InteractionType | null;
1972
+ /**
1973
+ * Return all shapes whose geometry contains the given world-space point.
1974
+ * @param point - The world-space point to test.
1975
+ * @param filter - Optional interaction filter to restrict results.
1976
+ * @param output - Optional existing ShapeList to accumulate results into.
1977
+ * @returns A ShapeList of matching shapes.
1978
+ * @throws If `point` is null or disposed.
1979
+ */
1980
+ shapesUnderPoint(point: Vec2, filter?: InteractionFilter | null, output?: ShapeList | null): ShapeList;
1981
+ /**
1982
+ * Return all bodies that have at least one shape containing the given world-space point.
1983
+ * @param point - The world-space point to test.
1984
+ * @param filter - Optional interaction filter to restrict results.
1985
+ * @param output - Optional existing BodyList to accumulate results into.
1986
+ * @returns A BodyList of matching bodies.
1987
+ * @throws If `point` is null or disposed.
1988
+ */
1989
+ bodiesUnderPoint(point: Vec2, filter?: InteractionFilter | null, output?: BodyList | null): BodyList;
1990
+ /**
1991
+ * Return all shapes that overlap with the given AABB.
1992
+ * @param aabb - The axis-aligned bounding box to test against.
1993
+ * @param containment - If true, only shapes fully contained within the AABB are returned.
1994
+ * @param strict - If true, exact shape geometry is tested; otherwise only AABBs are compared.
1995
+ * @param filter - Optional interaction filter to restrict results.
1996
+ * @param output - Optional existing ShapeList to accumulate results into.
1997
+ * @returns A ShapeList of matching shapes.
1998
+ * @throws If `aabb` is null or degenerate (zero width or height).
1999
+ */
2000
+ shapesInAABB(aabb: AABB, containment?: boolean, strict?: boolean, filter?: InteractionFilter | null, output?: ShapeList | null): ShapeList;
2001
+ /**
2002
+ * Return all bodies that have at least one shape overlapping the given AABB.
2003
+ * @param aabb - The axis-aligned bounding box to test against.
2004
+ * @param containment - If true, only shapes fully contained within the AABB count.
2005
+ * @param strict - If true, exact shape geometry is tested; otherwise only AABBs are compared.
2006
+ * @param filter - Optional interaction filter to restrict results.
2007
+ * @param output - Optional existing BodyList to accumulate results into.
2008
+ * @returns A BodyList of matching bodies.
2009
+ * @throws If `aabb` is null or degenerate (zero width or height).
2010
+ */
2011
+ bodiesInAABB(aabb: AABB, containment?: boolean, strict?: boolean, filter?: InteractionFilter | null, output?: BodyList | null): BodyList;
2012
+ /**
2013
+ * Return all shapes that overlap with a circle defined by `position` and `radius`.
2014
+ * @param position - World-space centre of the query circle.
2015
+ * @param radius - Radius of the query circle; must be strictly positive and not NaN.
2016
+ * @param containment - If true, only shapes fully contained within the circle are returned.
2017
+ * @param filter - Optional interaction filter to restrict results.
2018
+ * @param output - Optional existing ShapeList to accumulate results into.
2019
+ * @returns A ShapeList of matching shapes.
2020
+ * @throws If `position` is null/disposed, or `radius` is NaN or non-positive.
2021
+ */
2022
+ shapesInCircle(position: Vec2, radius: number, containment?: boolean, filter?: InteractionFilter | null, output?: ShapeList | null): ShapeList;
2023
+ /**
2024
+ * Return all bodies that have at least one shape overlapping a query circle.
2025
+ * @param position - World-space centre of the query circle.
2026
+ * @param radius - Radius of the query circle; must be strictly positive and not NaN.
2027
+ * @param containment - If true, only shapes fully contained within the circle count.
2028
+ * @param filter - Optional interaction filter to restrict results.
2029
+ * @param output - Optional existing BodyList to accumulate results into.
2030
+ * @returns A BodyList of matching bodies.
2031
+ * @throws If `position` is null/disposed, or `radius` is NaN or non-positive.
2032
+ */
2033
+ bodiesInCircle(position: Vec2, radius: number, containment?: boolean, filter?: InteractionFilter | null, output?: BodyList | null): BodyList;
2034
+ /**
2035
+ * Return all shapes in the space that overlap with `shape`.
2036
+ * @param shape - The query shape; must be attached to a Body.
2037
+ * @param containment - If true, only shapes fully contained within `shape` are returned.
2038
+ * @param filter - Optional interaction filter to restrict results.
2039
+ * @param output - Optional existing ShapeList to accumulate results into.
2040
+ * @returns A ShapeList of overlapping shapes.
2041
+ * @throws If `shape` is null, not attached to a Body, or is an invalid polygon.
2042
+ */
2043
+ shapesInShape(shape: Shape, containment?: boolean, filter?: InteractionFilter | null, output?: ShapeList | null): ShapeList;
2044
+ /**
2045
+ * Return all bodies in the space that have at least one shape overlapping `shape`.
2046
+ * @param shape - The query shape; must be attached to a Body.
2047
+ * @param containment - If true, only shapes fully contained within `shape` count.
2048
+ * @param filter - Optional interaction filter to restrict results.
2049
+ * @param output - Optional existing BodyList to accumulate results into.
2050
+ * @returns A BodyList of overlapping bodies.
2051
+ * @throws If `shape` is null, not attached to a Body, or is an invalid polygon.
2052
+ */
2053
+ bodiesInShape(shape: Shape, containment?: boolean, filter?: InteractionFilter | null, output?: BodyList | null): BodyList;
2054
+ /**
2055
+ * Return all shapes in the space that overlap with any shape attached to `body`.
2056
+ * Equivalent to calling `shapesInShape` for each of `body`'s shapes and merging results.
2057
+ * @param body - The body whose shapes are used as the query region.
2058
+ * @param filter - Optional interaction filter to restrict results.
2059
+ * @param output - Optional existing ShapeList to accumulate results into.
2060
+ * @returns A ShapeList of overlapping shapes.
2061
+ * @throws If `body` is null.
2062
+ */
2063
+ shapesInBody(body: Body, filter?: InteractionFilter | null, output?: ShapeList | null): ShapeList;
2064
+ /**
2065
+ * Return all bodies in the space that overlap with any shape attached to `body`.
2066
+ * Equivalent to calling `bodiesInShape` for each of `body`'s shapes and merging results.
2067
+ * @param body - The body whose shapes are used as the query region.
2068
+ * @param filter - Optional interaction filter to restrict results.
2069
+ * @param output - Optional existing BodyList to accumulate results into.
2070
+ * @returns A BodyList of overlapping bodies.
2071
+ * @throws If `body` is null.
2072
+ */
2073
+ bodiesInBody(body: Body, filter?: InteractionFilter | null, output?: BodyList | null): BodyList;
2074
+ /**
2075
+ * Sweep `shape` along its current velocity for `deltaTime` seconds and return the first hit.
2076
+ * @param shape - The shape to sweep; must belong to a Body.
2077
+ * @param deltaTime - Duration of the sweep; must be non-negative.
2078
+ * @param liveSweep - If true, other body velocities are considered during the sweep.
2079
+ * @param filter - Optional interaction filter to restrict results.
2080
+ * @returns The first RayResult hit, or null if nothing was struck.
2081
+ * @throws If `shape` is null, not attached to a Body, or `deltaTime` is negative/NaN.
2082
+ */
2083
+ convexCast(shape: Shape, deltaTime: number, liveSweep?: boolean, filter?: InteractionFilter | null): ConvexResult | null;
2084
+ /**
2085
+ * Sweep `shape` along its current velocity for `deltaTime` seconds and return all hits.
2086
+ * @param shape - The shape to sweep; must belong to a Body.
2087
+ * @param deltaTime - Duration of the sweep; must be non-negative.
2088
+ * @param liveSweep - If true, other body velocities are considered during the sweep.
2089
+ * @param filter - Optional interaction filter to restrict results.
2090
+ * @param output - Optional existing RayResultList to accumulate results into.
2091
+ * @returns A RayResultList of all hits encountered during the sweep.
2092
+ * @throws If `shape` is null, not attached to a Body, or `deltaTime` is negative/NaN.
2093
+ */
2094
+ convexMultiCast(shape: Shape, deltaTime: number, liveSweep?: boolean, filter?: InteractionFilter | null, output?: ConvexResultList | null): ConvexResultList;
2095
+ /**
2096
+ * Cast a ray into the space and return the closest hit.
2097
+ * @param ray - The ray to cast.
2098
+ * @param inner - If true, shapes are tested from the inside as well (useful for concave queries).
2099
+ * @param filter - Optional interaction filter to restrict results.
2100
+ * @returns The closest RayResult, or null if nothing was hit.
2101
+ * @throws If `ray` is null.
2102
+ */
2103
+ rayCast(ray: Ray, inner?: boolean, filter?: InteractionFilter | null): RayResult | null;
2104
+ /**
2105
+ * Cast a ray into the space and return all hits.
2106
+ * @param ray - The ray to cast.
2107
+ * @param inner - If true, shapes are tested from the inside as well.
2108
+ * @param filter - Optional interaction filter to restrict results.
2109
+ * @param output - Optional existing RayResultList to accumulate results into.
2110
+ * @returns A RayResultList of all shapes the ray intersected.
2111
+ * @throws If `ray` is null.
2112
+ */
2113
+ rayMultiCast(ray: Ray, inner?: boolean, filter?: InteractionFilter | null, output?: RayResultList | null): RayResultList;
2114
+ /**
2115
+ * Returns a brief string summary of this space.
2116
+ * @returns A string in the form `Space(bodies=N)`.
2117
+ */
2118
+ toString(): string;
2119
+ }
2120
+
2121
+ /**
2122
+ * Body type enumeration.
2123
+ *
2124
+ * - `STATIC` — immovable, infinite mass (walls, floors)
2125
+ * - `DYNAMIC` — fully simulated (default)
2126
+ * - `KINEMATIC` — moves only via velocity, not affected by forces
2127
+ *
2128
+ * Converted from nape-compiled.js lines 24640–24705.
2129
+ */
2130
+ declare class BodyType {
2131
+ static __name__: string[];
2132
+ constructor();
2133
+ static get STATIC(): BodyType;
2134
+ static get DYNAMIC(): BodyType;
2135
+ static get KINEMATIC(): BodyType;
2136
+ toString(): string;
2137
+ }
2138
+
2139
+ /**
2140
+ * Fluid properties for shapes that act as fluid regions.
2141
+ *
2142
+ * Controls density, viscosity, and per-fluid gravity override.
2143
+ * Internally wraps a ZPP_FluidProperties and is registered as
2144
+ * the public `nape.phys.FluidProperties` class in the compiled namespace.
2145
+ *
2146
+ * Converted from nape-compiled.js lines 37002–37511.
2147
+ */
2148
+ declare class FluidProperties {
2149
+ static __name__: string[];
2150
+ constructor(density?: number, viscosity?: number);
2151
+ get density(): number;
2152
+ set density(value: number);
2153
+ get viscosity(): number;
2154
+ set viscosity(value: number);
2155
+ get gravity(): any;
2156
+ set gravity(gravity: any);
2157
+ get userData(): Record<string, unknown>;
2158
+ get shapes(): any;
2159
+ copy(): FluidProperties;
2160
+ toString(): string;
2161
+ }
2162
+
2163
+ /**
2164
+ * Mass mode for a body.
2165
+ *
2166
+ * - `DEFAULT` — use computed mass from shapes
2167
+ * - `FIXED` — use a fixed mass value
2168
+ *
2169
+ * Converted from nape-compiled.js lines 26966–27013.
2170
+ */
2171
+ declare class MassMode {
2172
+ static __name__: string[];
2173
+ constructor();
2174
+ static get DEFAULT(): MassMode;
2175
+ static get FIXED(): MassMode;
2176
+ toString(): string;
2177
+ }
2178
+
2179
+ /**
2180
+ * Inertia mode for a body.
2181
+ *
2182
+ * - `DEFAULT` — use computed inertia from shapes
2183
+ * - `FIXED` — use a fixed inertia value
2184
+ *
2185
+ * Converted from nape-compiled.js lines 26343–26390.
2186
+ */
2187
+ declare class InertiaMode {
2188
+ static __name__: string[];
2189
+ constructor();
2190
+ static get DEFAULT(): InertiaMode;
2191
+ static get FIXED(): InertiaMode;
2192
+ toString(): string;
2193
+ }
2194
+
2195
+ /**
2196
+ * Gravity mass mode for a body.
2197
+ *
2198
+ * - `DEFAULT` — use computed mass for gravity
2199
+ * - `FIXED` — use a fixed gravity mass value
2200
+ * - `SCALED` — scale the computed gravity mass
2201
+ *
2202
+ * Converted from nape-compiled.js lines 26272–26342.
2203
+ */
2204
+ declare class GravMassMode {
2205
+ static __name__: string[];
2206
+ constructor();
2207
+ static get DEFAULT(): GravMassMode;
2208
+ static get FIXED(): GravMassMode;
2209
+ static get SCALED(): GravMassMode;
2210
+ toString(): string;
2211
+ }
2212
+
2213
+ /**
2214
+ * A rigid body in the physics simulation. Add shapes to give it geometry, then add it to a `Space` to participate in simulation.
2215
+ */
2216
+ declare class Body extends Interactor {
2217
+ static __name__: string[];
2218
+ static __super__: typeof Interactor;
2219
+ /** If true, this body is included in debug rendering. */
2220
+ debugDraw: boolean;
2221
+ /**
2222
+ * @param type - Body type (DYNAMIC by default).
2223
+ * @param position - Initial world-space position (defaults to origin).
2224
+ */
2225
+ constructor(type?: BodyType, position?: Vec2);
2226
+ /** The body type: DYNAMIC, STATIC, or KINEMATIC. Cannot be changed mid-step. */
2227
+ get type(): BodyType;
2228
+ set type(value: BodyType);
2229
+ /** Return true if this body is static. */
2230
+ isStatic(): boolean;
2231
+ /** Return true if this body is dynamic. */
2232
+ isDynamic(): boolean;
2233
+ /** Return true if this body is kinematic. */
2234
+ isKinematic(): boolean;
2235
+ /** World-space position of the body's origin. Live Vec2 — mutating it moves the body. */
2236
+ get position(): Vec2;
2237
+ set position(value: Vec2);
2238
+ /**
2239
+ * Rotation of the body in radians.
2240
+ * @throws If set on a static body that is already in a space.
2241
+ */
2242
+ get rotation(): number;
2243
+ set rotation(value: number);
2244
+ /** Linear velocity in world space (units/s). Live Vec2. Static bodies cannot have velocity. */
2245
+ get velocity(): Vec2;
2246
+ set velocity(value: Vec2);
2247
+ /** Angular velocity in radians per second. */
2248
+ get angularVel(): number;
2249
+ set angularVel(value: number);
2250
+ /** Desired velocity for kinematic bodies; the engine tries to match this each step. */
2251
+ get kinematicVel(): Vec2;
2252
+ set kinematicVel(value: Vec2);
2253
+ /** Desired angular velocity for kinematic bodies. */
2254
+ get kinAngVel(): number;
2255
+ set kinAngVel(value: number);
2256
+ /** Surface velocity used in friction calculations. */
2257
+ get surfaceVel(): Vec2;
2258
+ set surfaceVel(value: Vec2);
2259
+ /** Accumulated force applied to this body for the current step (cleared after each step). */
2260
+ get force(): Vec2;
2261
+ set force(value: Vec2);
2262
+ /** Accumulated torque applied to this body for the current step (only for DYNAMIC bodies). */
2263
+ get torque(): number;
2264
+ set torque(value: number);
2265
+ /**
2266
+ * Mass in kg. Must be finite and > 0. Setting switches massMode to FIXED.
2267
+ * @throws If the body is the world body, or if no shapes are present in DEFAULT mass mode.
2268
+ */
2269
+ get mass(): number;
2270
+ set mass(value: number);
2271
+ /**
2272
+ * Moment of inertia. Must be finite and > 0. Setting switches inertiaMode to FIXED.
1708
2273
  * @throws If the body is the world body, or if no shapes are present in DEFAULT inertia mode.
1709
2274
  */
1710
2275
  get inertia(): number;
@@ -1882,677 +2447,325 @@ declare class Body extends Interactor {
1882
2447
  * @returns `this` for chaining.
1883
2448
  * @throws If `centre` is null or `angle` is NaN.
1884
2449
  */
1885
- rotate(centre: Vec2, angle: number): Body;
1886
- /**
1887
- * Set the same `Material` on every shape attached to this body.
1888
- * @param material - The material to apply.
1889
- * @returns `this` for chaining.
1890
- */
1891
- setShapeMaterials(material: Material): Body;
1892
- /**
1893
- * Set the same `InteractionFilter` on every shape attached to this body.
1894
- * @param filter - The interaction filter to apply.
1895
- * @returns `this` for chaining.
1896
- */
1897
- setShapeFilters(filter: InteractionFilter): Body;
1898
- /**
1899
- * Set the same `FluidProperties` on every shape attached to this body.
1900
- * @param fluidProperties - The fluid properties to apply.
1901
- * @returns `this` for chaining.
1902
- */
1903
- setShapeFluidProperties(fluidProperties: FluidProperties): Body;
1904
- /**
1905
- * Test whether a world-space point lies inside any shape attached to this body.
1906
- * @param point - The point to test in world space.
1907
- * @returns True if the point is inside at least one shape.
1908
- */
1909
- contains(point: Vec2): boolean;
1910
- /**
1911
- * Return the set of bodies connected to this body via constraints.
1912
- * @param depth - Maximum traversal depth (-1 means unlimited).
1913
- * @param output - Optional existing list to accumulate results into.
1914
- * @returns A BodyList of connected bodies.
1915
- */
1916
- connectedBodies(depth?: number, output?: object | null): object;
1917
- /**
1918
- * Return the set of bodies currently interacting with this body via arbiters.
1919
- * @param type - Filter by interaction type (COLLISION, FLUID, SENSOR), or null for all.
1920
- * @param _depth - Unused; reserved for future use.
1921
- * @param output - Optional existing list to accumulate results into.
1922
- * @returns A BodyList of interacting bodies.
1923
- */
1924
- interactingBodies(type?: InteractionType | null, _depth?: number, output?: object | null): object;
1925
- /**
1926
- * Sum of normal (penetration-resolving) impulses received from collision arbiters this step.
1927
- * @param body - If provided, only arbiters shared with `body` are summed.
1928
- * @param freshOnly - If true, only newly created arbiters are considered.
1929
- * @returns A Vec3 where x/y are the linear component and z is the angular component.
1930
- */
1931
- normalImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
1932
- /**
1933
- * Sum of tangent (friction) impulses received from collision arbiters this step.
1934
- * @param body - If provided, only arbiters shared with `body` are summed.
1935
- * @param freshOnly - If true, only newly created arbiters are considered.
1936
- * @returns A Vec3 where x/y are the linear component and z is the angular component.
1937
- */
1938
- tangentImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
1939
- /**
1940
- * Sum of total contact impulses (normal + tangent) from collision arbiters this step.
1941
- * @param body - If provided, only arbiters shared with `body` are summed.
1942
- * @param freshOnly - If true, only newly created arbiters are considered.
1943
- * @returns A Vec3 where x/y are the linear component and z is the angular component.
1944
- */
1945
- totalContactsImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
1946
- /**
1947
- * Sum of rolling (angular friction) impulses from collision arbiters this step.
1948
- * @param body - If provided, only arbiters shared with `body` are summed.
1949
- * @param freshOnly - If true, only newly created arbiters are considered.
1950
- * @returns The total rolling impulse scalar.
1951
- */
1952
- rollingImpulse(body?: Body | null, freshOnly?: boolean): number;
1953
- /**
1954
- * Sum of buoyancy impulses received from fluid arbiters this step.
1955
- * @param body - If provided, only arbiters shared with `body` are summed.
1956
- * @returns A Vec3 where x/y are the linear component and z is the angular component.
1957
- */
1958
- buoyancyImpulse(body?: Body | null): Vec3;
1959
- /**
1960
- * Sum of fluid drag impulses received from fluid arbiters this step.
1961
- * @param body - If provided, only arbiters shared with `body` are summed.
1962
- * @returns A Vec3 where x/y are the linear component and z is the angular component.
1963
- */
1964
- dragImpulse(body?: Body | null): Vec3;
1965
- /**
1966
- * Sum of total fluid impulses (buoyancy + drag) from fluid arbiters this step.
1967
- * @param body - If provided, only arbiters shared with `body` are summed.
1968
- * @returns A Vec3 where x/y are the linear component and z is the angular component.
1969
- */
1970
- totalFluidImpulse(body?: Body | null): Vec3;
1971
- /**
1972
- * Sum of impulses applied to this body by all attached constraints this step.
1973
- * @returns A Vec3 where x/y are the linear component and z is the angular component.
1974
- */
1975
- constraintsImpulse(): Vec3;
1976
- /**
1977
- * Sum of all impulses (contacts + constraints) applied to this body this step, excluding sensor arbiters.
1978
- * @param body - If provided, only arbiters shared with `body` are summed.
1979
- * @param freshOnly - If true, only newly created contact arbiters are considered.
1980
- * @returns A Vec3 where x/y are the linear component and z is the angular component.
1981
- */
1982
- totalImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
1983
- /**
1984
- * Compute a heuristic crush factor indicating how strongly this body is being compressed from multiple directions.
1985
- * A value near zero means balanced forces; larger values indicate compression.
1986
- * @returns The crush factor (dimensionless).
1987
- * @throws If the body is not in a Space.
1988
- */
1989
- crushFactor(): number;
1990
- private _getArbiters;
1991
- private _getConstraints;
1992
- private _arbiterImpulseQuery;
1993
- }
1994
-
1995
- /**
1996
- * Shape type classification.
1997
- *
1998
- * - `CIRCLE` — circle shape
1999
- * - `POLYGON` — polygon shape
2000
- *
2001
- * Converted from nape-compiled.js lines 30435–30482.
2002
- */
2003
- declare class ShapeType {
2004
- static __name__: string[];
2005
- constructor();
2006
- static get CIRCLE(): ShapeType;
2007
- static get POLYGON(): ShapeType;
2008
- toString(): string;
2009
- }
2010
-
2011
- /**
2012
- * Base class for physics shapes (Circle, Polygon). Never instantiated directly — use
2013
- * `new Circle(...)` or `Polygon.box(...)` etc.
2014
- */
2015
- declare class Shape extends Interactor {
2016
- /** The shape type: CIRCLE or POLYGON. */
2017
- get type(): ShapeType;
2018
- /** Returns true if this is a Circle shape. */
2019
- isCircle(): boolean;
2020
- /** Returns true if this is a Polygon shape. */
2021
- isPolygon(): boolean;
2022
- /**
2023
- * The Body this shape belongs to. Setting moves the shape between bodies.
2024
- */
2025
- get body(): Body;
2026
- set body(value: Body | null);
2027
- /** Cast to Circle, or null if this is not a circle. */
2028
- get castCircle(): Shape | null;
2029
- /** Cast to Polygon, or null if this is not a polygon. */
2030
- get castPolygon(): Shape | null;
2031
- /** World-space centre of mass of this shape (read-only, lazy-computed). */
2032
- get worldCOM(): Vec2;
2033
- /**
2034
- * Local-space centre of mass. Can be set to override the default shape centroid.
2035
- */
2036
- get localCOM(): Vec2;
2037
- set localCOM(value: Vec2);
2038
- /** Cross-sectional area of this shape. */
2039
- get area(): number;
2040
- /** Contribution to moment of inertia (about local centroid, unit density). */
2041
- get inertia(): number;
2042
- /** Angular drag coefficient for this shape. */
2043
- get angDrag(): number;
2044
- /** The Material assigned to this shape (controls friction, elasticity, density). */
2045
- get material(): Material;
2046
- set material(value: Material);
2047
- /** The InteractionFilter controlling which shapes interact with this one. */
2048
- get filter(): InteractionFilter;
2049
- set filter(value: InteractionFilter);
2050
- /** Fluid simulation properties for this shape. Auto-created on first access. */
2051
- get fluidProperties(): FluidProperties;
2052
- set fluidProperties(value: FluidProperties);
2053
- /** Set of callback types registered on this shape for event dispatch. */
2054
- get cbTypes(): CbTypeSet;
2055
- /** If true, this shape participates in fluid interaction. */
2056
- get fluidEnabled(): boolean;
2057
- set fluidEnabled(value: boolean);
2058
- /** If true, this shape acts as a sensor (no physical response, only callbacks). */
2059
- get sensorEnabled(): boolean;
2060
- set sensorEnabled(value: boolean);
2061
- /** World-space AABB of this shape (updated each step). */
2062
- get bounds(): AABB;
2063
- /**
2064
- * Translate the shape's local vertices by the given vector (in-place).
2065
- * @param translation - The displacement vector to apply.
2066
- * @returns `this` for chaining.
2067
- */
2068
- translate(translation: Vec2): Shape;
2450
+ rotate(centre: Vec2, angle: number): Body;
2069
2451
  /**
2070
- * Scale the shape's local geometry. Circles require uniform scaling.
2071
- * @param scaleX - Horizontal scale factor (must be non-zero).
2072
- * @param scaleY - Vertical scale factor (must be non-zero).
2452
+ * Set the same `Material` on every shape attached to this body.
2453
+ * @param material - The material to apply.
2073
2454
  * @returns `this` for chaining.
2074
2455
  */
2075
- scale(scaleX: number, scaleY: number): Shape;
2456
+ setShapeMaterials(material: Material): Body;
2076
2457
  /**
2077
- * Rotate the shape's local vertices by `angle` radians.
2078
- * @param angle - Rotation in radians.
2458
+ * Set the same `InteractionFilter` on every shape attached to this body.
2459
+ * @param filter - The interaction filter to apply.
2079
2460
  * @returns `this` for chaining.
2080
2461
  */
2081
- rotate(angle: number): Shape;
2462
+ setShapeFilters(filter: InteractionFilter): Body;
2082
2463
  /**
2083
- * Apply a Mat23 affine transform to the shape's local geometry.
2084
- * @param matrix - The transformation matrix (must be non-singular; Circles require equiorthogonal).
2464
+ * Set the same `FluidProperties` on every shape attached to this body.
2465
+ * @param fluidProperties - The fluid properties to apply.
2085
2466
  * @returns `this` for chaining.
2086
2467
  */
2087
- transform(matrix: {
2088
- _inner: NapeInner;
2089
- }): Shape;
2468
+ setShapeFluidProperties(fluidProperties: FluidProperties): Body;
2090
2469
  /**
2091
- * Return true if the given world-space point lies inside this shape.
2092
- * Requires the shape to be attached to a Body.
2093
- * @param point - The world-space point to test.
2094
- * @returns True if the point is inside this shape.
2470
+ * Test whether a world-space point lies inside any shape attached to this body.
2471
+ * @param point - The point to test in world space.
2472
+ * @returns True if the point is inside at least one shape.
2095
2473
  */
2096
2474
  contains(point: Vec2): boolean;
2097
2475
  /**
2098
- * Create a deep copy of this shape with the same type, geometry, material, and filter.
2099
- * @returns A new Shape instance independent of this one.
2100
- */
2101
- copy(): Shape;
2102
- toString(): string;
2103
- /** Setup worldCOM lazy Vec2 wrapper */
2104
- private _setupWorldCOM;
2105
- }
2106
- /** Lightweight typed interface for the callback type set on a shape. */
2107
- interface CbTypeSet {
2108
- readonly _inner: NapeInner;
2109
- add(cbType: {
2110
- _inner: NapeInner;
2111
- }): void;
2112
- remove(cbType: {
2113
- _inner: NapeInner;
2114
- }): void;
2115
- has(cbType: {
2116
- _inner: NapeInner;
2117
- }): boolean;
2118
- clear(): void;
2119
- readonly length: number;
2120
- }
2121
-
2122
- /**
2123
- * Result from a convex-cast query.
2124
- *
2125
- * Provides the contact normal, position, time-of-impact, and shape hit.
2126
- * Instances are pooled — call `dispose()` when done to return to pool.
2127
- */
2128
- declare class ConvexResult {
2129
- static __name__: string[];
2130
- constructor();
2131
- get normal(): Vec2;
2132
- get position(): Vec2;
2133
- get toi(): number;
2134
- get shape(): Shape;
2135
- dispose(): void;
2136
- toString(): string;
2137
- }
2138
-
2139
- /**
2140
- * Result from a raycast query.
2141
- *
2142
- * Provides the contact normal, distance, inside-flag, and shape hit.
2143
- * Instances are pooled — call `dispose()` when done to return to pool.
2144
- */
2145
- declare class RayResult {
2146
- static __name__: string[];
2147
- constructor();
2148
- get normal(): Vec2;
2149
- get distance(): number;
2150
- get inner(): boolean;
2151
- get shape(): Shape;
2152
- dispose(): void;
2153
- toString(): string;
2154
- }
2155
-
2156
- /**
2157
- * Static utility class for geometric queries between shapes and bodies.
2158
- *
2159
- * Fully modernized — calls ZPP_Geom, ZPP_SweepDistance, and ZPP_Collide directly.
2160
- */
2161
- declare class Geom {
2162
- static __name__: string[];
2163
- /**
2164
- * Calculate minimum distance between two bodies and return closest points.
2476
+ * Return the set of bodies connected to this body via constraints.
2477
+ * @param depth - Maximum traversal depth (-1 means unlimited).
2478
+ * @param output - Optional existing list to accumulate results into.
2479
+ * @returns A BodyList of connected bodies.
2165
2480
  */
2166
- static distanceBody(body1: Body, body2: Body, out1: Vec2, out2: Vec2): number;
2481
+ connectedBodies(depth?: number, output?: BodyList | null): BodyList;
2167
2482
  /**
2168
- * Calculate minimum distance between two shapes and return closest points.
2483
+ * Return the set of bodies currently interacting with this body via arbiters.
2484
+ * @param type - Filter by interaction type (COLLISION, FLUID, SENSOR), or null for all.
2485
+ * @param _depth - Unused; reserved for future use.
2486
+ * @param output - Optional existing list to accumulate results into.
2487
+ * @returns A BodyList of interacting bodies.
2169
2488
  */
2170
- static distance(shape1: Shape, shape2: Shape, out1: Vec2, out2: Vec2): number;
2489
+ interactingBodies(type?: InteractionType | null, _depth?: number, output?: BodyList | null): BodyList;
2171
2490
  /**
2172
- * Test if two bodies intersect (any of their shapes overlap).
2491
+ * Sum of normal (penetration-resolving) impulses received from collision arbiters this step.
2492
+ * @param body - If provided, only arbiters shared with `body` are summed.
2493
+ * @param freshOnly - If true, only newly created arbiters are considered.
2494
+ * @returns A Vec3 where x/y are the linear component and z is the angular component.
2173
2495
  */
2174
- static intersectsBody(body1: Body, body2: Body): boolean;
2496
+ normalImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
2175
2497
  /**
2176
- * Test if two shapes intersect.
2498
+ * Sum of tangent (friction) impulses received from collision arbiters this step.
2499
+ * @param body - If provided, only arbiters shared with `body` are summed.
2500
+ * @param freshOnly - If true, only newly created arbiters are considered.
2501
+ * @returns A Vec3 where x/y are the linear component and z is the angular component.
2177
2502
  */
2178
- static intersects(shape1: Shape, shape2: Shape): boolean;
2503
+ tangentImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
2179
2504
  /**
2180
- * Test if shape1 fully contains shape2.
2505
+ * Sum of total contact impulses (normal + tangent) from collision arbiters this step.
2506
+ * @param body - If provided, only arbiters shared with `body` are summed.
2507
+ * @param freshOnly - If true, only newly created arbiters are considered.
2508
+ * @returns A Vec3 where x/y are the linear component and z is the angular component.
2181
2509
  */
2182
- static contains(shape1: Shape, shape2: Shape): boolean;
2183
- }
2184
-
2185
- /**
2186
- * A circular physics shape. The simplest and most performant collision shape.
2187
- */
2188
- declare class Circle extends Shape {
2189
- static __name__: string[];
2190
- static __super__: any;
2510
+ totalContactsImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
2191
2511
  /**
2192
- * Create a circle with the given radius and optional local centre-of-mass offset.
2193
- * @param radius - Circle radius (must be > 0).
2194
- * @param localCOM - Local centre offset (defaults to origin).
2195
- * @param material - Material to assign (uses default if omitted).
2196
- * @param filter - InteractionFilter to assign (uses default if omitted).
2512
+ * Sum of rolling (angular friction) impulses from collision arbiters this step.
2513
+ * @param body - If provided, only arbiters shared with `body` are summed.
2514
+ * @param freshOnly - If true, only newly created arbiters are considered.
2515
+ * @returns The total rolling impulse scalar.
2197
2516
  */
2198
- constructor(radius?: number, localCOM?: Vec2, material?: Material, filter?: InteractionFilter);
2199
- /** The circle's radius. Must be > 0. */
2200
- get radius(): number;
2201
- set radius(value: number);
2202
- }
2203
-
2204
- /**
2205
- * A convex polygon physics shape.
2206
- */
2207
- declare class Polygon extends Shape {
2208
- static __name__: string[];
2209
- static __super__: any;
2517
+ rollingImpulse(body?: Body | null, freshOnly?: boolean): number;
2210
2518
  /**
2211
- * Create a Polygon from a list of Vec2 vertices. Vertices must form a convex polygon
2212
- * in counter-clockwise order.
2213
- * @param localVerts - Vertices as `Array<Vec2>`, `Vec2List`, or `GeomPoly`.
2214
- * @param material - Material to assign (uses default if omitted).
2215
- * @param filter - InteractionFilter to assign (uses default if omitted).
2519
+ * Sum of buoyancy impulses received from fluid arbiters this step.
2520
+ * @param body - If provided, only arbiters shared with `body` are summed.
2521
+ * @returns A Vec3 where x/y are the linear component and z is the angular component.
2216
2522
  */
2217
- constructor(localVerts?: Vec2[] | any, material?: Material, filter?: InteractionFilter);
2523
+ buoyancyImpulse(body?: Body | null): Vec3;
2218
2524
  /**
2219
- * Create an axis-aligned rectangle at the given position.
2220
- * @param x - Left edge x coordinate.
2221
- * @param y - Top edge y coordinate.
2222
- * @param width - Rectangle width.
2223
- * @param height - Rectangle height.
2224
- * @param weak - If true, returned Vec2s are marked weak and will be auto-disposed.
2225
- * @returns Array of four Vec2 corner vertices.
2525
+ * Sum of fluid drag impulses received from fluid arbiters this step.
2526
+ * @param body - If provided, only arbiters shared with `body` are summed.
2527
+ * @returns A Vec3 where x/y are the linear component and z is the angular component.
2226
2528
  */
2227
- static rect(x: number, y: number, width: number, height: number, weak?: boolean): Vec2[];
2529
+ dragImpulse(body?: Body | null): Vec3;
2228
2530
  /**
2229
- * Create an axis-aligned rectangular polygon centred at the origin.
2230
- * @param width - Rectangle width.
2231
- * @param height - Rectangle height (defaults to `width` for a square).
2232
- * @param weak - If true, returned Vec2s are marked weak and will be auto-disposed.
2233
- * @returns Array of four Vec2 corner vertices.
2531
+ * Sum of total fluid impulses (buoyancy + drag) from fluid arbiters this step.
2532
+ * @param body - If provided, only arbiters shared with `body` are summed.
2533
+ * @returns A Vec3 where x/y are the linear component and z is the angular component.
2234
2534
  */
2235
- static box(width: number, height?: number, weak?: boolean): Vec2[];
2535
+ totalFluidImpulse(body?: Body | null): Vec3;
2236
2536
  /**
2237
- * Create a regular polygon (or ellipse approximation) centred at the origin.
2238
- * @param xRadius - Horizontal radius of the circumscribed ellipse.
2239
- * @param yRadius - Vertical radius of the circumscribed ellipse.
2240
- * @param edgeCount - Number of sides (must be >= 3).
2241
- * @param angleOffset - Rotation offset in radians applied to all vertices (default 0).
2242
- * @param weak - If true, returned Vec2s are marked weak and will be auto-disposed.
2243
- * @returns Array of `edgeCount` Vec2 vertices.
2537
+ * Sum of impulses applied to this body by all attached constraints this step.
2538
+ * @returns A Vec3 where x/y are the linear component and z is the angular component.
2244
2539
  */
2245
- static regular(xRadius: number, yRadius: number, edgeCount: number, angleOffset?: number, weak?: boolean): Vec2[];
2246
- /** The list of local-space vertices defining this polygon's shape. */
2247
- get localVerts(): any;
2248
- /** World-space vertices of this polygon, updated each simulation step. */
2249
- get worldVerts(): any;
2250
- /** The list of edges derived from this polygon's vertices. */
2251
- get edges(): any;
2540
+ constraintsImpulse(): Vec3;
2252
2541
  /**
2253
- * Validate the polygon geometry and return a string describing any issues, or
2254
- * `"valid"` if the polygon is well-formed.
2255
- * @returns A validation result string from the underlying ZPP_Polygon.
2542
+ * Sum of all impulses (contacts + constraints) applied to this body this step, excluding sensor arbiters.
2543
+ * @param body - If provided, only arbiters shared with `body` are summed.
2544
+ * @param freshOnly - If true, only newly created contact arbiters are considered.
2545
+ * @returns A Vec3 where x/y are the linear component and z is the angular component.
2256
2546
  */
2257
- validity(): any;
2258
- }
2259
-
2260
- /**
2261
- * An edge of a polygon shape.
2262
- *
2263
- * Edges are read-only and managed by the polygon they belong to.
2264
- * Cannot be instantiated directly — only obtained from Polygon.edges.
2265
- *
2266
- * Fully modernized — all getters access ZPP_Edge directly.
2267
- */
2268
- declare class Edge {
2269
- static __name__: string[];
2270
- constructor();
2271
- /** Parent polygon. */
2272
- get polygon(): Polygon;
2273
- /** Local-space normal vector (immutable Vec2). */
2274
- get localNormal(): Vec2;
2275
- /** World-space normal vector (immutable Vec2). Requires polygon in a body. */
2276
- get worldNormal(): Vec2;
2277
- /** Edge length. */
2278
- get length(): number;
2279
- /** Local-space projection along the edge normal. */
2280
- get localProjection(): number;
2281
- /** World-space projection. Requires polygon in a body. */
2282
- get worldProjection(): number;
2283
- /** First local vertex of this edge. */
2284
- get localVertex1(): Vec2;
2285
- /** Second local vertex of this edge. */
2286
- get localVertex2(): Vec2;
2287
- /** First world vertex. Requires polygon in a body. */
2288
- get worldVertex1(): Vec2;
2289
- /** Second world vertex. Requires polygon in a body. */
2290
- get worldVertex2(): Vec2;
2291
- toString(): string;
2547
+ totalImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
2292
2548
  /**
2293
- * Wrap a ZPP_Vec2 vertex into its public Vec2 outer.
2294
- * Mirrors the compiled vertex wrapping pattern.
2549
+ * Compute a heuristic crush factor indicating how strongly this body is being compressed from multiple directions.
2550
+ * A value near zero means balanced forces; larger values indicate compression.
2551
+ * @returns The crush factor (dimensionless).
2552
+ * @throws If the body is not in a Space.
2295
2553
  */
2296
- private _wrapVert;
2297
- }
2298
-
2299
- /**
2300
- * Result of polygon shape validation.
2301
- *
2302
- * - `VALID` — shape is valid
2303
- * - `DEGENERATE` — shape is degenerate (e.g., zero area)
2304
- * - `CONCAVE` — shape is concave (must be convex)
2305
- * - `SELF_INTERSECTING` — shape edges self-intersect
2306
- *
2307
- * Converted from nape-compiled.js lines 30760–30856.
2308
- */
2309
- declare class ValidationResult {
2310
- static __name__: string[];
2311
- constructor();
2312
- static get VALID(): ValidationResult;
2313
- static get DEGENERATE(): ValidationResult;
2314
- static get CONCAVE(): ValidationResult;
2315
- static get SELF_INTERSECTING(): ValidationResult;
2316
- toString(): string;
2554
+ crushFactor(): number;
2555
+ private _getArbiters;
2556
+ private _getConstraints;
2557
+ private _arbiterImpulseQuery;
2317
2558
  }
2318
2559
 
2319
2560
  /**
2320
- * Arbiter type classification.
2561
+ * Shape type classification.
2321
2562
  *
2322
- * - `COLLISION` collision arbiter
2323
- * - `SENSOR` sensor arbiter
2324
- * - `FLUID` — fluid arbiter
2563
+ * - `CIRCLE` circle shape
2564
+ * - `POLYGON` polygon shape
2325
2565
  *
2326
- * Converted from nape-compiled.js lines 1165311725.
2566
+ * Converted from nape-compiled.js lines 3043530482.
2327
2567
  */
2328
- declare class ArbiterType {
2568
+ declare class ShapeType {
2329
2569
  static __name__: string[];
2330
2570
  constructor();
2331
- static get COLLISION(): ArbiterType;
2332
- static get SENSOR(): ArbiterType;
2333
- static get FLUID(): ArbiterType;
2571
+ static get CIRCLE(): ShapeType;
2572
+ static get POLYGON(): ShapeType;
2334
2573
  toString(): string;
2335
2574
  }
2336
2575
 
2337
2576
  /**
2338
- * An arbiter representing a physical collision between two solid shapes.
2339
- *
2340
- * Provides access to contact points, collision normal, friction coefficients,
2341
- * elasticity, and impulse data. Properties marked _mutable in pre-handler_ can
2342
- * only be set within a {@link PreListener} handler.
2343
- *
2344
- * Obtain via {@link Arbiter.collisionArbiter} or by casting from a callback's
2345
- * arbiter list.
2346
- *
2347
- * Fully modernized — uses extracted ZPP_ColArbiter directly.
2577
+ * Base class for physics shapes (Circle, Polygon). Never instantiated directly — use
2578
+ * `new Circle(...)` or `Polygon.box(...)` etc.
2348
2579
  */
2349
- declare class CollisionArbiter extends Arbiter {
2350
- static __name__: string[];
2351
- static __super__: typeof Arbiter;
2352
- constructor();
2353
- /**
2354
- * The list of active contact points between the two shapes.
2355
- * Contains 1 or 2 {@link Contact} objects depending on the collision geometry.
2356
- */
2357
- get contacts(): object;
2580
+ declare class Shape extends Interactor {
2581
+ /** The shape type: CIRCLE or POLYGON. */
2582
+ get type(): ShapeType;
2583
+ /** Returns true if this is a Circle shape. */
2584
+ isCircle(): boolean;
2585
+ /** Returns true if this is a Polygon shape. */
2586
+ isPolygon(): boolean;
2358
2587
  /**
2359
- * Collision normal vector pointing from `shape1` toward `shape2`.
2360
- * Read-only; available after the arbiter is active.
2588
+ * The Body this shape belongs to. Setting moves the shape between bodies.
2361
2589
  */
2362
- get normal(): Vec2;
2363
- /** Sum of the radii of the two shapes at the collision point. */
2364
- get radius(): number;
2365
- /** Reference edge of shape1 (if polygon), or null. */
2366
- get referenceEdge1(): Edge | null;
2367
- /** Reference edge of shape2 (if polygon), or null. */
2368
- get referenceEdge2(): Edge | null;
2590
+ get body(): Body;
2591
+ set body(value: Body | null);
2592
+ /** Cast to Circle, or null if this is not a circle. */
2593
+ get castCircle(): Shape | null;
2594
+ /** Cast to Polygon, or null if this is not a polygon. */
2595
+ get castPolygon(): Shape | null;
2596
+ /** World-space centre of mass of this shape (read-only, lazy-computed). */
2597
+ get worldCOM(): Vec2;
2369
2598
  /**
2370
- * Coefficient of restitution (bounciness).
2371
- *
2372
- * Combined from the two shapes' `elasticity` values. Can be overridden
2373
- * inside a pre-handler. Must be `>= 0`.
2374
- *
2375
- * _Mutable in pre-handler only._
2599
+ * Local-space centre of mass. Can be set to override the default shape centroid.
2376
2600
  */
2377
- get elasticity(): number;
2378
- set elasticity(value: number);
2601
+ get localCOM(): Vec2;
2602
+ set localCOM(value: Vec2);
2603
+ /** Cross-sectional area of this shape. */
2604
+ get area(): number;
2605
+ /** Contribution to moment of inertia (about local centroid, unit density). */
2606
+ get inertia(): number;
2607
+ /** Angular drag coefficient for this shape. */
2608
+ get angDrag(): number;
2609
+ /** The Material assigned to this shape (controls friction, elasticity, density). */
2610
+ get material(): Material;
2611
+ set material(value: Material);
2612
+ /** The InteractionFilter controlling which shapes interact with this one. */
2613
+ get filter(): InteractionFilter;
2614
+ set filter(value: InteractionFilter);
2615
+ /** Fluid simulation properties for this shape. Auto-created on first access. */
2616
+ get fluidProperties(): FluidProperties;
2617
+ set fluidProperties(value: FluidProperties);
2618
+ /** Set of callback types registered on this shape for event dispatch. */
2619
+ get cbTypes(): CbTypeSet;
2620
+ /** If true, this shape participates in fluid interaction. */
2621
+ get fluidEnabled(): boolean;
2622
+ set fluidEnabled(value: boolean);
2623
+ /** If true, this shape acts as a sensor (no physical response, only callbacks). */
2624
+ get sensorEnabled(): boolean;
2625
+ set sensorEnabled(value: boolean);
2626
+ /** World-space AABB of this shape (updated each step). */
2627
+ get bounds(): AABB;
2379
2628
  /**
2380
- * Dynamic (kinetic) friction coefficient applied when the contact is sliding.
2381
- * Combined from the two shapes' material values. _Mutable in pre-handler only._
2629
+ * Translate the shape's local vertices by the given vector (in-place).
2630
+ * @param translation - The displacement vector to apply.
2631
+ * @returns `this` for chaining.
2382
2632
  */
2383
- get dynamicFriction(): number;
2384
- set dynamicFriction(value: number);
2633
+ translate(translation: Vec2): Shape;
2385
2634
  /**
2386
- * Static friction coefficient applied when the contact is at rest.
2387
- * Combined from the two shapes' material values. _Mutable in pre-handler only._
2635
+ * Scale the shape's local geometry. Circles require uniform scaling.
2636
+ * @param scaleX - Horizontal scale factor (must be non-zero).
2637
+ * @param scaleY - Vertical scale factor (must be non-zero).
2638
+ * @returns `this` for chaining.
2388
2639
  */
2389
- get staticFriction(): number;
2390
- set staticFriction(value: number);
2640
+ scale(scaleX: number, scaleY: number): Shape;
2391
2641
  /**
2392
- * Rolling friction coefficient resists rolling motion.
2393
- * Combined from the two shapes' material values. _Mutable in pre-handler only._
2642
+ * Rotate the shape's local vertices by `angle` radians.
2643
+ * @param angle - Rotation in radians.
2644
+ * @returns `this` for chaining.
2394
2645
  */
2395
- get rollingFriction(): number;
2396
- set rollingFriction(value: number);
2397
- /** Whether the first contact point lies on a polygon vertex (poly-circle only). */
2398
- firstVertex(): boolean;
2399
- /** Whether the second contact point lies on a polygon vertex (poly-circle only). */
2400
- secondVertex(): boolean;
2646
+ rotate(angle: number): Shape;
2401
2647
  /**
2402
- * Impulse applied in the normal (collision) direction, summed over all contacts.
2403
- * @param body - One of the two bodies, or `null` for the combined value.
2404
- * @param freshOnly - Only include new contact points. Default `false`.
2648
+ * Apply a Mat23 affine transform to the shape's local geometry.
2649
+ * @param matrix - The transformation matrix (must be non-singular; Circles require equiorthogonal).
2650
+ * @returns `this` for chaining.
2405
2651
  */
2406
- normalImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
2652
+ transform(matrix: {
2653
+ _inner: NapeInner;
2654
+ }): Shape;
2407
2655
  /**
2408
- * Friction impulse applied in the tangent direction, summed over all contacts.
2409
- * @param body - One of the two bodies, or `null` for the combined value.
2410
- * @param freshOnly - Only include new contact points. Default `false`.
2656
+ * Return true if the given world-space point lies inside this shape.
2657
+ * Requires the shape to be attached to a Body.
2658
+ * @param point - The world-space point to test.
2659
+ * @returns True if the point is inside this shape.
2411
2660
  */
2412
- tangentImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
2413
- /** Total impulse (normal + tangent + rolling) accumulated across all contacts. */
2414
- totalImpulse(body?: Body | null, freshOnly?: boolean): Vec3;
2661
+ contains(point: Vec2): boolean;
2415
2662
  /**
2416
- * Rolling impulse applied by this collision.
2417
- * @param body - One of the two bodies, or `null` for the combined value.
2418
- * @param freshOnly - Only include new contact points. Default `false`.
2663
+ * Create a deep copy of this shape with the same type, geometry, material, and filter.
2664
+ * @returns A new Shape instance independent of this one.
2419
2665
  */
2420
- rollingImpulse(body?: Body | null, freshOnly?: boolean): number;
2666
+ copy(): Shape;
2667
+ toString(): string;
2668
+ /** Setup worldCOM lazy Vec2 wrapper */
2669
+ private _setupWorldCOM;
2670
+ }
2671
+ /** Lightweight typed interface for the callback type set on a shape. */
2672
+ interface CbTypeSet {
2673
+ readonly _inner: NapeInner;
2674
+ add(cbType: {
2675
+ _inner: NapeInner;
2676
+ }): void;
2677
+ remove(cbType: {
2678
+ _inner: NapeInner;
2679
+ }): void;
2680
+ has(cbType: {
2681
+ _inner: NapeInner;
2682
+ }): boolean;
2683
+ clear(): void;
2684
+ readonly length: number;
2421
2685
  }
2422
2686
 
2423
2687
  /**
2424
- * An arbiter representing a fluid interaction between a fluid shape and a body.
2425
- *
2426
- * Provides access to buoyancy and drag impulses, the overlap area, and the
2427
- * centre of overlap. Properties marked _mutable in pre-handler_ can only be
2428
- * set within a {@link PreListener} handler.
2429
- *
2430
- * Obtain via {@link Arbiter.fluidArbiter} or by casting from a callback arbiter.
2688
+ * Result from a convex-cast query.
2431
2689
  *
2432
- * Fully modernized uses extracted ZPP_FluidArbiter directly.
2690
+ * Provides the contact normal, position, time-of-impact, and shape hit.
2691
+ * Instances are pooled — call `dispose()` when done to return to pool.
2433
2692
  */
2434
- declare class FluidArbiter extends Arbiter {
2693
+ declare class ConvexResult {
2435
2694
  static __name__: string[];
2436
- static __super__: typeof Arbiter;
2437
2695
  constructor();
2696
+ get normal(): Vec2;
2697
+ get position(): Vec2;
2698
+ get toi(): number;
2699
+ get shape(): Shape;
2700
+ dispose(): void;
2701
+ toString(): string;
2702
+ }
2703
+
2704
+ /**
2705
+ * Static utility class for geometric queries between shapes and bodies.
2706
+ *
2707
+ * Fully modernized — calls ZPP_Geom, ZPP_SweepDistance, and ZPP_Collide directly.
2708
+ */
2709
+ declare class Geom {
2710
+ static __name__: string[];
2438
2711
  /**
2439
- * Centre of the overlap region between the fluid and the body shape.
2440
- * _Mutable in pre-handler only._
2712
+ * Calculate minimum distance between two bodies and return closest points.
2441
2713
  */
2442
- get position(): Vec2;
2443
- set position(value: Vec2);
2714
+ static distanceBody(body1: Body, body2: Body, out1: Vec2, out2: Vec2): number;
2444
2715
  /**
2445
- * Area of the overlap region in pixels². Used to compute buoyancy force.
2446
- * Must be strictly positive and finite.
2447
- * _Mutable in pre-handler only._
2716
+ * Calculate minimum distance between two shapes and return closest points.
2448
2717
  */
2449
- get overlap(): number;
2450
- set overlap(value: number);
2718
+ static distance(shape1: Shape, shape2: Shape, out1: Vec2, out2: Vec2): number;
2451
2719
  /**
2452
- * Buoyancy impulse applied in the last step as `(fx, fy, torque)`.
2453
- * @param body - One of the two bodies, or `null` for the combined value.
2720
+ * Test if two bodies intersect (any of their shapes overlap).
2454
2721
  */
2455
- buoyancyImpulse(body?: Body | null): Vec3;
2722
+ static intersectsBody(body1: Body, body2: Body): boolean;
2456
2723
  /**
2457
- * Linear and angular drag impulse applied in the last step as `(fx, fy, torque)`.
2458
- * @param body - One of the two bodies, or `null` for the combined value.
2724
+ * Test if two shapes intersect.
2459
2725
  */
2460
- dragImpulse(body?: Body | null): Vec3;
2461
- /** Total impulse (buoyancy + drag). */
2462
- totalImpulse(body?: Body | null, _freshOnly?: boolean): Vec3;
2726
+ static intersects(shape1: Shape, shape2: Shape): boolean;
2727
+ /**
2728
+ * Test if shape1 fully contains shape2.
2729
+ */
2730
+ static contains(shape1: Shape, shape2: Shape): boolean;
2463
2731
  }
2464
2732
 
2465
2733
  /**
2466
- * Return value for {@link PreListener} handlers controls whether the interaction
2467
- * is resolved this step and in future steps.
2468
- *
2469
- * - `ACCEPT` — resolve the interaction (default if handler returns `null`)
2470
- * - `IGNORE` — suppress the interaction permanently until the next `BEGIN`
2471
- * - `ACCEPT_ONCE` — accept this step only, then revert to the previous flag
2472
- * - `IGNORE_ONCE` — ignore this step only, then revert to the previous flag
2473
- *
2474
- * Use `IGNORE`/`ACCEPT` for stateful decisions (e.g., one-way platforms).
2475
- * Use `*_ONCE` variants for single-step overrides.
2476
- *
2477
- * Converted from nape-compiled.js lines 2504–2591.
2734
+ * A circular physics shape. The simplest and most performant collision shape.
2478
2735
  */
2479
- declare class PreFlag {
2736
+ declare class Circle extends Shape {
2480
2737
  static __name__: string[];
2481
- constructor();
2482
- /** Accept and resolve the interaction normally. */
2483
- static get ACCEPT(): PreFlag;
2484
- /** Suppress the interaction permanently until the next `BEGIN` event. */
2485
- static get IGNORE(): PreFlag;
2486
- /** Accept this step only; revert to the previous flag next step. */
2487
- static get ACCEPT_ONCE(): PreFlag;
2488
- /** Ignore this step only; revert to the previous flag next step. */
2489
- static get IGNORE_ONCE(): PreFlag;
2490
- toString(): string;
2738
+ static __super__: any;
2739
+ /**
2740
+ * Create a circle with the given radius and optional local centre-of-mass offset.
2741
+ * @param radius - Circle radius (must be > 0).
2742
+ * @param localCOM - Local centre offset (defaults to origin).
2743
+ * @param material - Material to assign (uses default if omitted).
2744
+ * @param filter - InteractionFilter to assign (uses default if omitted).
2745
+ */
2746
+ constructor(radius?: number, localCOM?: Vec2, material?: Material, filter?: InteractionFilter);
2747
+ /** The circle's radius. Must be > 0. */
2748
+ get radius(): number;
2749
+ set radius(value: number);
2491
2750
  }
2492
2751
 
2493
2752
  /**
2494
- * Represents an active interaction between two shapes.
2495
- *
2496
- * Arbiters are created and pooled internally by the engine — they cannot be
2497
- * instantiated directly. Access them via:
2498
- * - `space.arbiters` — all active arbiters in the simulation
2499
- * - `body.arbiters` — arbiters involving a specific body
2500
- * - `InteractionCallback.arbiters` — arbiters in an interaction callback
2501
- * - `PreCallback.arbiter` — the arbiter in a pre-handler
2502
- *
2503
- * Use {@link Arbiter.collisionArbiter} or {@link Arbiter.fluidArbiter} to cast
2504
- * to a subtype for type-specific properties.
2753
+ * Result of polygon shape validation.
2505
2754
  *
2506
- * **Warning:** do not hold references to `Arbiter` objects after the current
2507
- * simulation step they are pooled and may be reused.
2755
+ * - `VALID` shape is valid
2756
+ * - `DEGENERATE` shape is degenerate (e.g., zero area)
2757
+ * - `CONCAVE` — shape is concave (must be convex)
2758
+ * - `SELF_INTERSECTING` — shape edges self-intersect
2508
2759
  *
2509
- * Fully modernized uses extracted ZPP_Arbiter directly.
2760
+ * Converted from nape-compiled.js lines 30760–30856.
2510
2761
  */
2511
- declare class Arbiter {
2762
+ declare class ValidationResult {
2512
2763
  static __name__: string[];
2513
2764
  constructor();
2514
- /**
2515
- * Whether both interacting bodies are currently sleeping.
2516
- * Throws if the arbiter is not active.
2517
- */
2518
- get isSleeping(): boolean;
2519
- /**
2520
- * The interaction type of this arbiter.
2521
- * @see {@link ArbiterType}
2522
- */
2523
- get type(): ArbiterType;
2524
- /** Cast to CollisionArbiter if this is a collision, else null. */
2525
- get collisionArbiter(): CollisionArbiter | null;
2526
- /** Cast to FluidArbiter if this is a fluid interaction, else null. */
2527
- get fluidArbiter(): FluidArbiter | null;
2528
- /** First shape (lower id). */
2529
- get shape1(): Shape;
2530
- /** Second shape (higher id). */
2531
- get shape2(): Shape;
2532
- /** Body of shape1. */
2533
- get body1(): Body;
2534
- /** Body of shape2. */
2535
- get body2(): Body;
2536
- /** The pre-handler state of this arbiter. */
2537
- get state(): PreFlag;
2538
- /** Whether this is a collision arbiter. */
2539
- isCollisionArbiter(): boolean;
2540
- /** Whether this is a fluid arbiter. */
2541
- isFluidArbiter(): boolean;
2542
- /** Whether this is a sensor arbiter. */
2543
- isSensorArbiter(): boolean;
2544
- /**
2545
- * Total impulse applied by this arbiter in the last step as `(fx, fy, torque)`.
2546
- *
2547
- * Pass a `body` to get the impulse applied specifically to that body.
2548
- * Pass `freshOnly = true` to include only new contact points (not persistent ones).
2549
- *
2550
- * Overridden by {@link CollisionArbiter} and {@link FluidArbiter}.
2551
- *
2552
- * @param body - One of the two interacting bodies, or `null` for the combined impulse.
2553
- * @param freshOnly - When `true`, only count fresh (new) contacts. Default `false`.
2554
- */
2555
- totalImpulse(body?: Body | null, _freshOnly?: boolean): Vec3;
2765
+ static get VALID(): ValidationResult;
2766
+ static get DEGENERATE(): ValidationResult;
2767
+ static get CONCAVE(): ValidationResult;
2768
+ static get SELF_INTERSECTING(): ValidationResult;
2556
2769
  toString(): string;
2557
2770
  }
2558
2771
 
@@ -2604,48 +2817,6 @@ declare class Contact {
2604
2817
  toString(): string;
2605
2818
  }
2606
2819
 
2607
- /**
2608
- * Enumeration of physics callback event types.
2609
- *
2610
- * Use these singletons to specify which phase of an interaction a listener
2611
- * should respond to:
2612
- *
2613
- * - `BEGIN` — fired once when two interactors first make contact
2614
- * - `ONGOING` — fired every simulation step while the interaction persists
2615
- * - `END` — fired once when two interactors separate
2616
- * - `WAKE` — fired when a body or constraint wakes from sleep
2617
- * - `SLEEP` — fired when a body or constraint falls asleep
2618
- * - `BREAK` — fired when a constraint exceeds its `maxForce`/`maxError` and breaks
2619
- * - `PRE` — fired before collision resolution; allows per-step accept/ignore decisions
2620
- *
2621
- * Valid events per listener type:
2622
- * - {@link BodyListener}: `WAKE`, `SLEEP`
2623
- * - {@link ConstraintListener}: `WAKE`, `SLEEP`, `BREAK`
2624
- * - {@link InteractionListener}: `BEGIN`, `ONGOING`, `END`
2625
- * - {@link PreListener}: always `PRE` (set internally)
2626
- *
2627
- * Converted from nape-compiled.js lines 516–657.
2628
- */
2629
- declare class CbEvent {
2630
- static __name__: string[];
2631
- constructor();
2632
- /** Interaction-start event. Fired once when two interactors first make contact. */
2633
- static get BEGIN(): CbEvent;
2634
- /** Interaction-continue event. Fired every step while the interaction persists. */
2635
- static get ONGOING(): CbEvent;
2636
- /** Interaction-end event. Fired once when two interactors separate. */
2637
- static get END(): CbEvent;
2638
- /** Wake event. Fired when a body or constraint wakes from sleep. */
2639
- static get WAKE(): CbEvent;
2640
- /** Sleep event. Fired when a body or constraint falls asleep. */
2641
- static get SLEEP(): CbEvent;
2642
- /** Break event. Fired when a constraint exceeds its `maxForce` or `maxError` limit. */
2643
- static get BREAK(): CbEvent;
2644
- /** Pre-interaction event. Fired before collision resolution; handler can accept or ignore. */
2645
- static get PRE(): CbEvent;
2646
- toString(): string;
2647
- }
2648
-
2649
2820
  /**
2650
2821
  * Composite callback option type — combines include and exclude {@link CbType} lists
2651
2822
  * to express complex listener filter conditions.
@@ -2778,82 +2949,6 @@ declare class CbType {
2778
2949
  toString(): string;
2779
2950
  }
2780
2951
 
2781
- /**
2782
- * Listener type classification.
2783
- *
2784
- * - `BODY` — body event listener
2785
- * - `CONSTRAINT` — constraint event listener
2786
- * - `INTERACTION` — interaction event listener
2787
- * - `PRE` — pre-interaction listener
2788
- *
2789
- * Converted from nape-compiled.js lines 2554–2646.
2790
- */
2791
- declare class ListenerType {
2792
- static __name__: string[];
2793
- constructor();
2794
- static get BODY(): ListenerType;
2795
- static get CONSTRAINT(): ListenerType;
2796
- static get INTERACTION(): ListenerType;
2797
- static get PRE(): ListenerType;
2798
- toString(): string;
2799
- }
2800
-
2801
- /**
2802
- * Listener — Base class for all physics event listeners.
2803
- *
2804
- * Provides common properties (type, event, precedence, space) and
2805
- * toString() for all listener subclasses.
2806
- *
2807
- * Fully modernized from nape-compiled.js lines 231–433.
2808
- */
2809
-
2810
- /**
2811
- * Base class for all physics event listeners.
2812
- *
2813
- * Cannot be instantiated directly — use one of the concrete subclasses:
2814
- * {@link BodyListener}, {@link ConstraintListener}, {@link InteractionListener},
2815
- * or {@link PreListener}.
2816
- *
2817
- * Provides common properties (`type`, `event`, `precedence`, `space`) shared
2818
- * by all listener types.
2819
- *
2820
- * Fully modernized from nape-compiled.js lines 231–433.
2821
- */
2822
- declare class Listener {
2823
- static __name__: string[];
2824
- constructor();
2825
- /** The type of this listener (BODY, CONSTRAINT, INTERACTION, or PRE). */
2826
- get type(): ListenerType;
2827
- /**
2828
- * The event this listener responds to.
2829
- *
2830
- * Valid values depend on the concrete listener type — see {@link CbEvent}.
2831
- * Changing this while the listener is assigned to a space re-registers it.
2832
- */
2833
- get event(): CbEvent;
2834
- set event(event: CbEvent);
2835
- /**
2836
- * Execution priority of this listener relative to other listeners for the
2837
- * same event. Higher values execute first.
2838
- *
2839
- * @defaultValue `0`
2840
- */
2841
- get precedence(): number;
2842
- set precedence(precedence: number);
2843
- /**
2844
- * The space this listener is currently registered in, or `null` if not registered.
2845
- *
2846
- * Assign to register/unregister the listener in a space:
2847
- * ```ts
2848
- * listener.space = mySpace; // register
2849
- * listener.space = null; // unregister
2850
- * ```
2851
- */
2852
- get space(): Space | null;
2853
- set space(space: Space | null);
2854
- toString(): string;
2855
- }
2856
-
2857
2952
  /**
2858
2953
  * Base class for all physics engine callback objects.
2859
2954
  *
@@ -3627,6 +3722,194 @@ declare class PulleyJoint extends Constraint {
3627
3722
  visitBodies(lambda: (body: Body) => void): void;
3628
3723
  }
3629
3724
 
3725
+ /**
3726
+ * ZPP_Constraint — Internal base class for all constraints / joints.
3727
+ *
3728
+ * Manages activation/deactivation, callback types, space integration,
3729
+ * and provides stubs for solver methods overridden by joint subclasses.
3730
+ *
3731
+ * Converted from nape-compiled.js lines 21424–21827.
3732
+ */
3733
+ declare class ZPP_Constraint {
3734
+ static __name__: string[];
3735
+ /**
3736
+ * Namespace references, set by the compiled module after import.
3737
+ * _nape = the `nape` public namespace (for CbTypeIterator in copyto)
3738
+ * _zpp = the `zpp_nape` internal namespace (for ZNPList_*, ZPP_CbSet, etc.)
3739
+ */
3740
+ static _nape: any;
3741
+ static _zpp: any;
3742
+ outer: any;
3743
+ id: number;
3744
+ userData: any;
3745
+ compound: any;
3746
+ space: any;
3747
+ active: boolean;
3748
+ stiff: boolean;
3749
+ frequency: number;
3750
+ damping: number;
3751
+ maxForce: number;
3752
+ maxError: number;
3753
+ breakUnderForce: boolean;
3754
+ breakUnderError: boolean;
3755
+ removeOnBreak: boolean;
3756
+ component: any;
3757
+ ignore: boolean;
3758
+ __velocity: boolean;
3759
+ cbTypes: any;
3760
+ cbSet: any;
3761
+ wrap_cbTypes: any;
3762
+ pre_dt: number;
3763
+ __class__: any;
3764
+ constructor();
3765
+ /**
3766
+ * Initialise base constraint fields.
3767
+ * Extracted into a separate method because compiled joint subclasses
3768
+ * call `ZPP_Constraint.call(this)` — ES classes can't be invoked that
3769
+ * way, so the compiled wrapper delegates to this method instead.
3770
+ */
3771
+ _initBase(): void;
3772
+ clear(): void;
3773
+ activeBodies(): void;
3774
+ inactiveBodies(): void;
3775
+ clearcache(): void;
3776
+ validate(): void;
3777
+ wake_connected(): void;
3778
+ forest(): void;
3779
+ broken(): void;
3780
+ warmStart(): void;
3781
+ draw(_g: any): void;
3782
+ pair_exists(_id: any, _di: any): boolean;
3783
+ preStep(_dt: number): boolean;
3784
+ applyImpulseVel(): boolean;
3785
+ applyImpulsePos(): boolean;
3786
+ copy(_dict?: any, _todo?: any): any;
3787
+ immutable_midstep(name: string): void;
3788
+ setupcbTypes(): void;
3789
+ immutable_cbTypes(): void;
3790
+ wrap_cbTypes_subber(pcb: any): void;
3791
+ wrap_cbTypes_adder(cb: any): boolean;
3792
+ insert_cbtype(cb: any): void;
3793
+ alloc_cbSet(): void;
3794
+ dealloc_cbSet(): void;
3795
+ activate(): void;
3796
+ deactivate(): void;
3797
+ addedToSpace(): void;
3798
+ removedFromSpace(): void;
3799
+ activeInSpace(): void;
3800
+ inactiveOrOutSpace(): void;
3801
+ wake(): void;
3802
+ copyto(ret: any): void;
3803
+ static _findRoot(comp: any): any;
3804
+ static _unionComponents(a: any, b: any): void;
3805
+ }
3806
+
3807
+ /**
3808
+ * ZPP_UserBody — pairs a body with a reference count for user constraints.
3809
+ *
3810
+ * Converted from nape-compiled.js lines 28038–28054.
3811
+ */
3812
+ declare class ZPP_UserBody {
3813
+ static __name__: string[];
3814
+ cnt: number;
3815
+ body: any;
3816
+ constructor(cnt: number, body: any);
3817
+ }
3818
+
3819
+ /**
3820
+ * ZPP_UserConstraint — Internal N-DOF user-defined constraint with Cholesky decomposition.
3821
+ *
3822
+ * A generic constraint where the user supplies callbacks for effective mass,
3823
+ * velocity/position errors, impulse application, and clamping. The solver
3824
+ * factorises the effective-mass matrix via Cholesky (solve/transform) and
3825
+ * drives the constraint each step through warmStart / applyImpulseVel /
3826
+ * applyImpulsePos.
3827
+ *
3828
+ * Converted from nape-compiled.js lines 27368–28037.
3829
+ */
3830
+
3831
+ declare class ZPP_UserConstraint extends ZPP_Constraint {
3832
+ static __name__: string[];
3833
+ static __super__: typeof ZPP_Constraint;
3834
+ outer_zn: any;
3835
+ bodies: ZPP_UserBody[];
3836
+ dim: number;
3837
+ jAcc: number[];
3838
+ bias: number[];
3839
+ stepped: boolean;
3840
+ L: number[];
3841
+ y: number[];
3842
+ soft: number;
3843
+ gamma: number;
3844
+ velonly: boolean;
3845
+ jMax: number;
3846
+ Keff: number[];
3847
+ vec3: any;
3848
+ J: number[];
3849
+ jOld: number[];
3850
+ __class__: any;
3851
+ constructor(dim: number, velonly: boolean);
3852
+ bindVec2_invalidate(_: any): void;
3853
+ addBody(b: any): void;
3854
+ remBody(b: any): boolean;
3855
+ bodyImpulse(b: any): any;
3856
+ activeBodies(): void;
3857
+ inactiveBodies(): void;
3858
+ copy(_dict: any, _todo: any): any;
3859
+ validate(): void;
3860
+ wake_connected(): void;
3861
+ forest(): void;
3862
+ pair_exists(id: number, di: number): boolean;
3863
+ broken(): void;
3864
+ clearcache(): void;
3865
+ lsq(v: number[]): number;
3866
+ _clamp(v: number[], max: number): void;
3867
+ solve(m: number[]): number[];
3868
+ transform(L: number[], x: number[]): void;
3869
+ preStep(dt: number): boolean;
3870
+ warmStart(): void;
3871
+ applyImpulseVel(): boolean;
3872
+ applyImpulsePos(): boolean;
3873
+ draw(g: any): void;
3874
+ }
3875
+
3876
+ /**
3877
+ * Base class for user-defined N-DOF constraints.
3878
+ *
3879
+ * Fully modernized — uses ZPP_UserConstraint directly (extracted to TypeScript).
3880
+ * Subclass and override the abstract callback methods to define custom constraints.
3881
+ */
3882
+ declare abstract class UserConstraint extends Constraint {
3883
+ zpp_inner: ZPP_UserConstraint;
3884
+ constructor(dimensions: number, velocityOnly?: boolean);
3885
+ __bindVec2(): Vec2;
3886
+ /** Create a copy of this constraint. Must be overridden. */
3887
+ __copy(): UserConstraint;
3888
+ /** Called when the constraint breaks. Optional override. */
3889
+ __broken(): void;
3890
+ /** Called to validate the constraint. Optional override. */
3891
+ __validate(): void;
3892
+ /** Draw debug visualization. Optional override. */
3893
+ __draw(_debug: any): void;
3894
+ /** Prepare the constraint for solving. Optional override. */
3895
+ __prepare(): void;
3896
+ /** Compute positional error. Must be overridden for non-velocity-only constraints. */
3897
+ __position(_err: number[]): void;
3898
+ /** Compute velocity error. Must be overridden. */
3899
+ __velocity(_err: number[]): void;
3900
+ /** Compute effective mass matrix (upper triangle). Must be overridden. */
3901
+ __eff_mass(_eff: number[]): void;
3902
+ /** Clamp accumulated impulse. Optional override. */
3903
+ __clamp(_jAcc: number[]): void;
3904
+ /** Apply impulse to a body. Must be overridden. */
3905
+ __impulse(_imp: number[], _body: Body, _out: any): void;
3906
+ impulse(): MatMN;
3907
+ bodyImpulse(body: Body): Vec3;
3908
+ visitBodies(lambda: (body: Body) => void): void;
3909
+ __invalidate(): void;
3910
+ __registerBody(oldBody: Body | null, newBody: Body | null): Body | null;
3911
+ }
3912
+
3630
3913
  declare const VERSION: string;
3631
3914
 
3632
- export { AABB, AngleJoint, Arbiter, ArbiterType, Body, BodyCallback, BodyListener, BodyType, Broadphase, Callback, CbEvent, CbType, Circle, CollisionArbiter, Compound, Constraint, ConstraintCallback, ConstraintListener, Contact, ConvexResult, DistanceJoint, Edge, FluidArbiter, FluidProperties, Geom, GeomPoly, GravMassMode, InertiaMode, InteractionCallback, InteractionFilter, InteractionGroup, InteractionListener, InteractionType, Interactor, LineJoint, Listener, ListenerType, MarchingSquares, MassMode, Mat23, MatMN, Material, MotorJoint, NapeList, OptionType, PivotJoint, Polygon, PreCallback, PreFlag, PreListener, PulleyJoint, Ray, RayResult, Shape, ShapeType, Space, VERSION, ValidationResult, Vec2, Vec3, WeldJoint, Winding };
3915
+ export { AABB, AngleJoint, Arbiter, type ArbiterList, ArbiterType, Body, BodyCallback, type BodyList, BodyListener, BodyType, Broadphase, Callback, CbEvent, CbType, type CbTypeSet, Circle, CollisionArbiter, Compound, type CompoundList, Constraint, ConstraintCallback, type ConstraintList, ConstraintListener, Contact, ConvexResult, type ConvexResultList, DistanceJoint, Edge, FluidArbiter, FluidProperties, Geom, GeomPoly, GravMassMode, InertiaMode, InteractionCallback, InteractionFilter, InteractionGroup, InteractionListener, InteractionType, Interactor, LineJoint, Listener, type ListenerList, ListenerType, MarchingSquares, MassMode, Mat23, MatMN, Material, MotorJoint, NapeList, OptionType, PivotJoint, Polygon, PreCallback, PreFlag, PreListener, PulleyJoint, Ray, RayResult, type RayResultList, Shape, type ShapeList, ShapeType, Space, type TypedListLike, UserConstraint, VERSION, ValidationResult, Vec2, Vec3, WeldJoint, Winding };