@onerjs/core 8.53.6 → 8.53.8

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.
@@ -350,17 +350,7 @@ export class HavokPlugin {
350
350
  // Update the region reference and world transform offset
351
351
  pluginData.worldRegion = newRegion;
352
352
  pluginData.worldTransformOffset = this._hknp.HP_Body_GetWorldTransformOffset(pluginData.hpBodyId)[1];
353
- // Garbage-collect the old region if it has no bodies left and it's not the default world
354
- if (currentRegion !== this._worldRegions[0]) {
355
- const bodyCount = this._hknp.HP_World_GetNumBodies(currentRegion.world)[1];
356
- if (bodyCount === 0) {
357
- this._hknp.HP_World_Release(currentRegion.world);
358
- const idx = this._worldRegions.indexOf(currentRegion);
359
- if (idx > 0) {
360
- this._worldRegions.splice(idx, 1);
361
- }
362
- }
363
- }
353
+ this._releaseWorldRegionIfEmpty(currentRegion);
364
354
  }
365
355
  /**
366
356
  * Searches existing world regions for one that contains the given position.
@@ -380,6 +370,28 @@ export class HavokPlugin {
380
370
  }
381
371
  return null;
382
372
  }
373
+ /**
374
+ * Releases a non-default world region when it no longer contains any bodies.
375
+ * @param worldRegion - The world region to release if empty
376
+ */
377
+ _releaseWorldRegionIfEmpty(worldRegion) {
378
+ const regionIndex = this._worldRegions.indexOf(worldRegion);
379
+ if (regionIndex <= 0 || this._hknp.HP_World_GetNumBodies(worldRegion.world)[1] !== 0) {
380
+ return;
381
+ }
382
+ this._hknp.HP_World_Release(worldRegion.world);
383
+ this._worldRegions.splice(regionIndex, 1);
384
+ }
385
+ /**
386
+ * Releases world regions that became candidates for removal while bodies were being removed.
387
+ * This must run after collision and trigger notifications to avoid releasing a world while its native events are being read.
388
+ */
389
+ _releasePendingWorldRegions() {
390
+ for (const worldRegion of this._worldRegionsPendingRelease) {
391
+ this._releaseWorldRegionIfEmpty(worldRegion);
392
+ }
393
+ this._worldRegionsPendingRelease.clear();
394
+ }
383
395
  constructor(_useDeltaForWorldStep = true, hpInjection = HK, parameters = {}) {
384
396
  this._useDeltaForWorldStep = _useDeltaForWorldStep;
385
397
  /**
@@ -409,6 +421,11 @@ export class HavokPlugin {
409
421
  * Additional regions are created as needed for floating origin mode.
410
422
  */
411
423
  this._worldRegions = [];
424
+ /**
425
+ * World regions that may have become empty while removing bodies.
426
+ * They are released after collision and trigger notifications have completed.
427
+ */
428
+ this._worldRegionsPendingRelease = new Set();
412
429
  /**
413
430
  * Stored gravity value to apply to new world regions.
414
431
  */
@@ -611,6 +628,7 @@ export class HavokPlugin {
611
628
  this._notifyCollisions(region.world);
612
629
  this._notifyTriggers(region.world);
613
630
  }
631
+ this._releasePendingWorldRegions();
614
632
  }
615
633
  /**
616
634
  * Returns the version of the physics engine plugin.
@@ -686,12 +704,14 @@ export class HavokPlugin {
686
704
  this._bodyCollisionObservable.delete(instance.hpBodyId[0]);
687
705
  this._hknp.HP_World_RemoveBody(instance.worldRegion.world, instance.hpBodyId);
688
706
  this._bodies.delete(instance.hpBodyId[0]);
707
+ this._worldRegionsPendingRelease.add(instance.worldRegion);
689
708
  }
690
709
  }
691
710
  if (body._pluginData) {
692
711
  this._bodyCollisionObservable.delete(body._pluginData.hpBodyId[0]);
693
712
  this._hknp.HP_World_RemoveBody(body._pluginData.worldRegion.world, body._pluginData.hpBodyId);
694
713
  this._bodies.delete(body._pluginData.hpBodyId[0]);
714
+ this._worldRegionsPendingRelease.add(body._pluginData.worldRegion);
695
715
  }
696
716
  }
697
717
  /**
@@ -804,6 +824,7 @@ export class HavokPlugin {
804
824
  const hkbody = body._pluginDataInstances.pop();
805
825
  this._bodies.delete(hkbody.hpBodyId[0]);
806
826
  this._hknp.HP_World_RemoveBody(hkbody.worldRegion.world, hkbody.hpBodyId);
827
+ this._worldRegionsPendingRelease.add(hkbody.worldRegion);
807
828
  this._hknp.HP_Body_Release(hkbody.hpBodyId);
808
829
  }
809
830
  this._createOrUpdateBodyInstances(body, motionType, matrixData, 0, instancesCount, true);
@@ -1462,6 +1483,7 @@ export class HavokPlugin {
1462
1483
  // Update region reference and cached world transform offset
1463
1484
  pluginData.worldRegion = newRegion;
1464
1485
  pluginData.worldTransformOffset = this._hknp.HP_Body_GetWorldTransformOffset(pluginData.hpBodyId)[1];
1486
+ this._releaseWorldRegionIfEmpty(currentRegion);
1465
1487
  }
1466
1488
  }
1467
1489
  }
@@ -2815,6 +2837,7 @@ export class HavokPlugin {
2815
2837
  }
2816
2838
  }
2817
2839
  this._worldRegions.length = 0;
2840
+ this._worldRegionsPendingRelease.clear();
2818
2841
  this.world = undefined;
2819
2842
  }
2820
2843
  _v3ToBvecRef(v, vec3) {