@forgeax/engine-physics-rapier3d 0.1.27 → 0.1.29
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/__tests__/derived-physics.unit.test.d.ts +2 -0
- package/dist/__tests__/derived-physics.unit.test.d.ts.map +1 -0
- package/dist/index.mjs +1598 -27
- package/dist/index.mjs.map +1 -1
- package/dist/rapier-physics-world-3d.d.ts +98 -4
- package/dist/rapier-physics-world-3d.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/__tests__/derived-physics.unit.test.ts +779 -0
- package/src/__tests__/physics-rapier3d.unit.test.ts +66 -1
- package/src/rapier-physics-world-3d.ts +2013 -50
|
@@ -1222,7 +1222,8 @@ describe('incremental physics ECS reconciliation', () => {
|
|
|
1222
1222
|
ensureSpy.mockClear();
|
|
1223
1223
|
world.removeComponent(entity as never, Collider as never).unwrap();
|
|
1224
1224
|
runPhysicsTicks(world);
|
|
1225
|
-
expect(pw.hasBody(entity)).toBe(
|
|
1225
|
+
expect(pw.hasBody(entity)).toBe(true);
|
|
1226
|
+
expect(rapierBodyFor(pw, entity)?.numColliders()).toBe(0);
|
|
1226
1227
|
expect(removeSpy).toHaveBeenCalledTimes(1);
|
|
1227
1228
|
|
|
1228
1229
|
world
|
|
@@ -1256,6 +1257,70 @@ describe('incremental physics ECS reconciliation', () => {
|
|
|
1256
1257
|
expect(pw.getBodyCount()).toBe(1);
|
|
1257
1258
|
});
|
|
1258
1259
|
|
|
1260
|
+
it('keeps a body-only derived publication intact when its authored collider is added and removed', async () => {
|
|
1261
|
+
const RAPIER = await loadOrSkip();
|
|
1262
|
+
if (!RAPIER) return;
|
|
1263
|
+
const world = prepareWorld();
|
|
1264
|
+
const pw = createRapier3DPhysicsWorld(RAPIER);
|
|
1265
|
+
world.insertResource('PhysicsWorld', pw);
|
|
1266
|
+
const entity = spawnBox(world, { bodyType: RigidBodyTypeValue.dynamic });
|
|
1267
|
+
world.removeComponent(entity as never, Collider as never).unwrap();
|
|
1268
|
+
world.set(entity as never, RigidBody as never, { gravityScale: 0 }).unwrap();
|
|
1269
|
+
registerPhysicsSystems(world);
|
|
1270
|
+
runPhysicsTicks(world);
|
|
1271
|
+
expect(rapierBodyFor(pw, entity)?.numColliders()).toBe(0);
|
|
1272
|
+
pw.admitDerivedShapeCandidate(
|
|
1273
|
+
pw
|
|
1274
|
+
.prepareDerivedShapeCandidate({
|
|
1275
|
+
entity,
|
|
1276
|
+
revision: 1,
|
|
1277
|
+
sourceKey: 'body-only',
|
|
1278
|
+
worldIdentity: world,
|
|
1279
|
+
bodyType: 'dynamic',
|
|
1280
|
+
velocityPolicy: 'preserve',
|
|
1281
|
+
constraints: [],
|
|
1282
|
+
seams: [],
|
|
1283
|
+
massProperties: {
|
|
1284
|
+
mode: 'explicit',
|
|
1285
|
+
mass: 2,
|
|
1286
|
+
centerOfMass: [0, 0, 0],
|
|
1287
|
+
principalInertia: [1, 1, 1],
|
|
1288
|
+
},
|
|
1289
|
+
shapes: [
|
|
1290
|
+
{
|
|
1291
|
+
id: 'voxel',
|
|
1292
|
+
revision: 1,
|
|
1293
|
+
cells: [[0, 0, 0]],
|
|
1294
|
+
origin: [3, 0, 0],
|
|
1295
|
+
voxelSize: [1, 1, 1],
|
|
1296
|
+
},
|
|
1297
|
+
],
|
|
1298
|
+
})
|
|
1299
|
+
.unwrap(),
|
|
1300
|
+
).unwrap();
|
|
1301
|
+
runPhysicsTicks(world);
|
|
1302
|
+
const body = rapierBodyFor(pw, entity);
|
|
1303
|
+
const derivedHandle = body.collider(0).handle;
|
|
1304
|
+
world
|
|
1305
|
+
.addComponent(entity as never, {
|
|
1306
|
+
component: Collider as never,
|
|
1307
|
+
data: { shape: ColliderShapeValue.sphere, radius: 0.5 },
|
|
1308
|
+
})
|
|
1309
|
+
.unwrap();
|
|
1310
|
+
runPhysicsTicks(world);
|
|
1311
|
+
expect(rapierBodyFor(pw, entity)?.handle).toBe(body.handle);
|
|
1312
|
+
expect(body.numColliders()).toBe(2);
|
|
1313
|
+
expect(pw.raw.getCollider(derivedHandle)?.isValid()).toBe(true);
|
|
1314
|
+
expect(pw.getDerivedBodyMass(entity)).toBeCloseTo(2);
|
|
1315
|
+
world.removeComponent(entity as never, Collider as never).unwrap();
|
|
1316
|
+
runPhysicsTicks(world);
|
|
1317
|
+
expect(body.numColliders()).toBe(1);
|
|
1318
|
+
expect(body.collider(0).handle).toBe(derivedHandle);
|
|
1319
|
+
expect(pw.getDerivedPublication(entity)?.revision).toBe(1);
|
|
1320
|
+
expect(pw.getDerivedBodyMass(entity)).toBeCloseTo(2);
|
|
1321
|
+
pw.dispose();
|
|
1322
|
+
});
|
|
1323
|
+
|
|
1259
1324
|
it('switches kinematic pose ownership when CharacterController is added or removed', async () => {
|
|
1260
1325
|
const RAPIER = await loadOrSkip();
|
|
1261
1326
|
if (!RAPIER) return;
|