@flighthq/physics3d 0.5.1-next.638.d4dbd4e → 0.5.1-next.650.5d3df0b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/physics3d`. The `@fl
13
13
  This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
14
14
 
15
15
  - [Flight project](https://github.com/flighthq/flight)
16
- - [Source for @flighthq/physics3d@0.5.1-next.638.d4dbd4e](https://github.com/flighthq/flight/tree/d4dbd4e347dc8be10b180c85a766ab50333dcb51/packages/physics3d)
17
- - [License](https://github.com/flighthq/flight/blob/d4dbd4e347dc8be10b180c85a766ab50333dcb51/LICENSE.md)
16
+ - [Source for @flighthq/physics3d@0.5.1-next.650.5d3df0b](https://github.com/flighthq/flight/tree/5d3df0b3bd7071e51898ec6ca5f733b81cb94a54/packages/physics3d)
17
+ - [License](https://github.com/flighthq/flight/blob/5d3df0b3bd7071e51898ec6ca5f733b81cb94a54/LICENSE.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/physics3d",
3
- "version": "0.5.1-next.638.d4dbd4e",
3
+ "version": "0.5.1-next.650.5d3df0b",
4
4
  "author": "Joshua Granick and other contributors",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,12 +38,12 @@
38
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@flighthq/collision": "0.5.1-next.638.d4dbd4e",
42
- "@flighthq/log": "0.5.1-next.638.d4dbd4e",
43
- "@flighthq/math": "0.5.1-next.638.d4dbd4e",
44
- "@flighthq/node": "0.5.1-next.638.d4dbd4e",
45
- "@flighthq/spatial": "0.5.1-next.638.d4dbd4e",
46
- "@flighthq/types": "0.5.1-next.638.d4dbd4e"
41
+ "@flighthq/collision": "0.5.1-next.650.5d3df0b",
42
+ "@flighthq/log": "0.5.1-next.650.5d3df0b",
43
+ "@flighthq/math": "0.5.1-next.650.5d3df0b",
44
+ "@flighthq/node": "0.5.1-next.650.5d3df0b",
45
+ "@flighthq/spatial": "0.5.1-next.650.5d3df0b",
46
+ "@flighthq/types": "0.5.1-next.650.5d3df0b"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@flighthq/geometry": "*",
@@ -2,6 +2,7 @@ import {
2
2
  createCollisionHeightfield3D,
3
3
  createCollisionTriangleMesh3D,
4
4
  registerBuiltInCollisionFaceQueries3D,
5
+ registerBuiltInCollisionPairTests3D,
5
6
  registerBuiltInCollisionSupports3D,
6
7
  } from '@flighthq/collision/contract';
7
8
  import type { CollisionBuiltInShape3D, Physics3DMaterial, Physics3DWorld, RigidBody3D } from '@flighthq/types/contract';
@@ -457,6 +458,52 @@ describe('physics3d stress qualification', () => {
457
458
  for (let i = 0; i < workspace.length; i += 1) expect(retained[i]).toBe(workspace[i]);
458
459
  });
459
460
 
461
+ // Pair test registration persists globally; this test must follow all GJK-path tests.
462
+ it('converges a 12-high walled pile with specialized pair tests', () => {
463
+ registerBuiltInCollisionPairTests3D();
464
+ const world = createPhysics3DWorld();
465
+ world.gravityY = -10;
466
+ addSlab(world, 20, 1, 20, -1);
467
+ for (const [x, z, halfX, halfZ] of [
468
+ [-1.02, 0, 0.5, 3],
469
+ [1.02, 0, 0.5, 3],
470
+ [0, -1.02, 3, 0.5],
471
+ [0, 1.02, 3, 0.5],
472
+ ]) {
473
+ const wall = createRigidBody3D('static');
474
+ wall.x = x;
475
+ wall.z = z;
476
+ wall.y = 10;
477
+ addPhysics3DBody(world, wall);
478
+ addPhysics3DCollider(world, wall, createPhysics3DCollider(boxShape(halfX, 11, halfZ), MATERIAL));
479
+ }
480
+ const pile: RigidBody3D[] = [];
481
+ for (let i = 0; i < 12; i += 1) pile.push(addBox(world, 'dynamic', 0, 0.5 + i, 0));
482
+
483
+ run(world, 900);
484
+
485
+ for (const body of pile) expectFiniteBody(body);
486
+ for (let i = 1; i < pile.length; i += 1) expect(pile[i].y).toBeGreaterThan(pile[i - 1].y);
487
+ expect(pile[0].y).toBeGreaterThan(0.4);
488
+ expect(pile[pile.length - 1].y).toBeGreaterThan(10.2);
489
+ expect(
490
+ pile.every((body) => body.sleeping),
491
+ JSON.stringify(
492
+ pile.map((body) => [
493
+ body.y,
494
+ body.sleeping,
495
+ body.sleepTimer,
496
+ body.velocityX,
497
+ body.velocityY,
498
+ body.velocityZ,
499
+ body.angularVelocityX,
500
+ body.angularVelocityY,
501
+ body.angularVelocityZ,
502
+ ]),
503
+ ),
504
+ ).toBe(true);
505
+ });
506
+
460
507
  it('keeps a spinning asymmetric body finite, with a drift that halves as the timestep does', () => {
461
508
  // The 3D-only failure mode, with no 2D counterpart: a body whose inertia tensor is not isotropic
462
509
  // precesses, and the gyroscopic term that produces it is integrated EXPLICITLY. So the test is not