cubeforge 0.5.0 → 0.5.2
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/advanced.js +1 -1
- package/dist/{chunk-OT6I5RYW.js → chunk-UMHYQ4EP.js} +101 -31
- package/dist/index.d.ts +4 -0
- package/dist/index.js +449 -349
- package/package.json +1 -1
package/dist/advanced.js
CHANGED
|
@@ -5261,6 +5261,31 @@ var PhysicsSystem = class {
|
|
|
5261
5261
|
bvhCache = /* @__PURE__ */ new Map();
|
|
5262
5262
|
// Physics hooks for filtering and modifying contacts
|
|
5263
5263
|
hooks = {};
|
|
5264
|
+
// ── Scratch containers — reused every frame to avoid GC pressure ──────────
|
|
5265
|
+
//
|
|
5266
|
+
// Previously these were allocated fresh inside update() every substep,
|
|
5267
|
+
// producing ~20 Map/Set allocations per frame. Now they live as instance
|
|
5268
|
+
// fields and are cleared at the start of each use. Never escape the class.
|
|
5269
|
+
//
|
|
5270
|
+
// The _current*Pairs fields are double-buffered with their active*Pairs
|
|
5271
|
+
// counterparts: at the end of each substep, the filled "current" is swapped
|
|
5272
|
+
// with "active", and next substep clears the new "current" (which was the
|
|
5273
|
+
// previous "active"). Same enter/stay/exit event semantics, zero allocation.
|
|
5274
|
+
_staticDelta = /* @__PURE__ */ new Map();
|
|
5275
|
+
_preStepPos = /* @__PURE__ */ new Map();
|
|
5276
|
+
_spatialGrid = /* @__PURE__ */ new Map();
|
|
5277
|
+
_jointExcludedPairs = /* @__PURE__ */ new Set();
|
|
5278
|
+
_solverBodies = /* @__PURE__ */ new Map();
|
|
5279
|
+
_triggerNormals = /* @__PURE__ */ new Map();
|
|
5280
|
+
_circleNormals = /* @__PURE__ */ new Map();
|
|
5281
|
+
/** Shared scratch for per-body "checked" neighbor dedup; cleared per iteration. */
|
|
5282
|
+
_checkedScratch = /* @__PURE__ */ new Set();
|
|
5283
|
+
_currentCollisionPairs = /* @__PURE__ */ new Map();
|
|
5284
|
+
_currentTriggerPairs = /* @__PURE__ */ new Map();
|
|
5285
|
+
_currentCirclePairs = /* @__PURE__ */ new Map();
|
|
5286
|
+
_currentCompoundPairs = /* @__PURE__ */ new Map();
|
|
5287
|
+
_currentCapsulePairs = /* @__PURE__ */ new Map();
|
|
5288
|
+
_currentPolygonPairs = /* @__PURE__ */ new Map();
|
|
5264
5289
|
/** Set physics hooks for contact filtering and modification. */
|
|
5265
5290
|
setHooks(hooks) {
|
|
5266
5291
|
this.hooks = hooks;
|
|
@@ -5421,7 +5446,8 @@ var PhysicsSystem = class {
|
|
|
5421
5446
|
}
|
|
5422
5447
|
const nonDynamic = [...staticBox, ...kinematicBox];
|
|
5423
5448
|
this.pruneDeadPairs(world);
|
|
5424
|
-
const staticDelta =
|
|
5449
|
+
const staticDelta = this._staticDelta;
|
|
5450
|
+
staticDelta.clear();
|
|
5425
5451
|
for (const sid of nonDynamic) {
|
|
5426
5452
|
const st = world.getComponent(sid, "Transform");
|
|
5427
5453
|
const prev = this.staticPrevPos.get(sid);
|
|
@@ -5551,12 +5577,14 @@ var PhysicsSystem = class {
|
|
|
5551
5577
|
}
|
|
5552
5578
|
if (rb.dropThrough > 0) rb.dropThrough--;
|
|
5553
5579
|
}
|
|
5554
|
-
const preStepPos =
|
|
5580
|
+
const preStepPos = this._preStepPos;
|
|
5581
|
+
preStepPos.clear();
|
|
5555
5582
|
for (const id of dynamicBox) {
|
|
5556
5583
|
const t = world.getComponent(id, "Transform");
|
|
5557
5584
|
preStepPos.set(id, { x: t.x, y: t.y });
|
|
5558
5585
|
}
|
|
5559
|
-
const spatialGrid =
|
|
5586
|
+
const spatialGrid = this._spatialGrid;
|
|
5587
|
+
spatialGrid.clear();
|
|
5560
5588
|
for (const sid of nonDynamic) {
|
|
5561
5589
|
const st = world.getComponent(sid, "Transform");
|
|
5562
5590
|
const sc = world.getComponent(sid, "BoxCollider");
|
|
@@ -5571,7 +5599,8 @@ var PhysicsSystem = class {
|
|
|
5571
5599
|
bucket.push(sid);
|
|
5572
5600
|
}
|
|
5573
5601
|
}
|
|
5574
|
-
const jointExcludedPairs =
|
|
5602
|
+
const jointExcludedPairs = this._jointExcludedPairs;
|
|
5603
|
+
jointExcludedPairs.clear();
|
|
5575
5604
|
for (const jid of world.query("Joint")) {
|
|
5576
5605
|
const j = world.getComponent(jid, "Joint");
|
|
5577
5606
|
if (!j.enabled || j.broken) continue;
|
|
@@ -5581,7 +5610,8 @@ var PhysicsSystem = class {
|
|
|
5581
5610
|
}
|
|
5582
5611
|
}
|
|
5583
5612
|
const manifolds = [];
|
|
5584
|
-
const currentCollisionPairs =
|
|
5613
|
+
const currentCollisionPairs = this._currentCollisionPairs;
|
|
5614
|
+
currentCollisionPairs.clear();
|
|
5585
5615
|
for (const id of dynamicBox) {
|
|
5586
5616
|
const rb = world.getComponent(id, "RigidBody");
|
|
5587
5617
|
if (rb.sleeping) continue;
|
|
@@ -5590,7 +5620,8 @@ var PhysicsSystem = class {
|
|
|
5590
5620
|
if (!col.enabled || col.isTrigger) continue;
|
|
5591
5621
|
const dynAABB = getAABB2(transform, col);
|
|
5592
5622
|
const candidateCells = this.getCells(dynAABB.cx, dynAABB.cy, dynAABB.hw, dynAABB.hh);
|
|
5593
|
-
const checked =
|
|
5623
|
+
const checked = this._checkedScratch;
|
|
5624
|
+
checked.clear();
|
|
5594
5625
|
for (const cell of candidateCells) {
|
|
5595
5626
|
const bucket = spatialGrid.get(cell);
|
|
5596
5627
|
if (!bucket) continue;
|
|
@@ -5779,7 +5810,8 @@ var PhysicsSystem = class {
|
|
|
5779
5810
|
const circleCy = ct.y + cc.offsetY;
|
|
5780
5811
|
const circleAABB2 = { cx: circleCx, cy: circleCy, hw: cc.radius, hh: cc.radius };
|
|
5781
5812
|
const candidateCells = this.getCells(circleAABB2.cx, circleAABB2.cy, circleAABB2.hw, circleAABB2.hh);
|
|
5782
|
-
const checked =
|
|
5813
|
+
const checked = this._checkedScratch;
|
|
5814
|
+
checked.clear();
|
|
5783
5815
|
for (const cell of candidateCells) {
|
|
5784
5816
|
const bucket = spatialGrid.get(cell);
|
|
5785
5817
|
if (!bucket) continue;
|
|
@@ -5963,7 +5995,8 @@ var PhysicsSystem = class {
|
|
|
5963
5995
|
const capHw = cc.width / 2;
|
|
5964
5996
|
const capHh = cc.height / 2;
|
|
5965
5997
|
const candidateCells = this.getCells(capCx, capCy, capHw, capHh);
|
|
5966
|
-
const checked =
|
|
5998
|
+
const checked = this._checkedScratch;
|
|
5999
|
+
checked.clear();
|
|
5967
6000
|
for (const cell of candidateCells) {
|
|
5968
6001
|
const bucket = spatialGrid.get(cell);
|
|
5969
6002
|
if (!bucket) continue;
|
|
@@ -6202,7 +6235,8 @@ var PhysicsSystem = class {
|
|
|
6202
6235
|
const polyCx = (minX + maxX) / 2;
|
|
6203
6236
|
const polyCy = (minY + maxY) / 2;
|
|
6204
6237
|
const candidateCells = this.getCells(polyCx, polyCy, polyHw, polyHh);
|
|
6205
|
-
const checked =
|
|
6238
|
+
const checked = this._checkedScratch;
|
|
6239
|
+
checked.clear();
|
|
6206
6240
|
for (const cell of candidateCells) {
|
|
6207
6241
|
const bucket = spatialGrid.get(cell);
|
|
6208
6242
|
if (!bucket) continue;
|
|
@@ -6457,7 +6491,8 @@ var PhysicsSystem = class {
|
|
|
6457
6491
|
const triCx = (minX + maxX) / 2;
|
|
6458
6492
|
const triCy = (minY + maxY) / 2;
|
|
6459
6493
|
const candidateCells = this.getCells(triCx, triCy, triHw, triHh);
|
|
6460
|
-
const checked =
|
|
6494
|
+
const checked = this._checkedScratch;
|
|
6495
|
+
checked.clear();
|
|
6461
6496
|
for (const cell of candidateCells) {
|
|
6462
6497
|
const bucket = spatialGrid.get(cell);
|
|
6463
6498
|
if (!bucket) continue;
|
|
@@ -6956,7 +6991,8 @@ var PhysicsSystem = class {
|
|
|
6956
6991
|
this.hooks.onContactModify(m);
|
|
6957
6992
|
}
|
|
6958
6993
|
}
|
|
6959
|
-
const solverBodies =
|
|
6994
|
+
const solverBodies = this._solverBodies;
|
|
6995
|
+
solverBodies.clear();
|
|
6960
6996
|
for (const id of allBox) {
|
|
6961
6997
|
const rb = world.getComponent(id, "RigidBody");
|
|
6962
6998
|
const t = world.getComponent(id, "Transform");
|
|
@@ -7264,7 +7300,8 @@ var PhysicsSystem = class {
|
|
|
7264
7300
|
(Math.max(startCx, endCx) - Math.min(startCx, endCx)) / 2 + hw,
|
|
7265
7301
|
(Math.max(startCy, endCy) - Math.min(startCy, endCy)) / 2 + hh
|
|
7266
7302
|
);
|
|
7267
|
-
const checked =
|
|
7303
|
+
const checked = this._checkedScratch;
|
|
7304
|
+
checked.clear();
|
|
7268
7305
|
for (const cell of sweepCells) {
|
|
7269
7306
|
const bucket = spatialGrid.get(cell);
|
|
7270
7307
|
if (!bucket) continue;
|
|
@@ -7345,7 +7382,8 @@ var PhysicsSystem = class {
|
|
|
7345
7382
|
hh: col.height / 2
|
|
7346
7383
|
};
|
|
7347
7384
|
const candidateCells = this.getCells(probeAABB.cx, probeAABB.cy, probeAABB.hw, probeAABB.hh);
|
|
7348
|
-
const checked =
|
|
7385
|
+
const checked = this._checkedScratch;
|
|
7386
|
+
checked.clear();
|
|
7349
7387
|
outer: for (const cell of candidateCells) {
|
|
7350
7388
|
const bucket = spatialGrid.get(cell);
|
|
7351
7389
|
if (!bucket) continue;
|
|
@@ -7379,7 +7417,8 @@ var PhysicsSystem = class {
|
|
|
7379
7417
|
hh: cap.height / 2
|
|
7380
7418
|
};
|
|
7381
7419
|
const candidateCells = this.getCells(probeAABB.cx, probeAABB.cy, probeAABB.hw, probeAABB.hh);
|
|
7382
|
-
const checked =
|
|
7420
|
+
const checked = this._checkedScratch;
|
|
7421
|
+
checked.clear();
|
|
7383
7422
|
outerCap: for (const cell of candidateCells) {
|
|
7384
7423
|
const bucket = spatialGrid.get(cell);
|
|
7385
7424
|
if (!bucket) continue;
|
|
@@ -7723,10 +7762,16 @@ var PhysicsSystem = class {
|
|
|
7723
7762
|
this.events?.emit("collisionExit", { a, b, normalX: 0, normalY: 0 });
|
|
7724
7763
|
}
|
|
7725
7764
|
}
|
|
7726
|
-
|
|
7765
|
+
{
|
|
7766
|
+
const prev = this.activeCollisionPairs;
|
|
7767
|
+
this.activeCollisionPairs = currentCollisionPairs;
|
|
7768
|
+
this._currentCollisionPairs = prev;
|
|
7769
|
+
}
|
|
7727
7770
|
const allWithCollider = world.query("Transform", "BoxCollider");
|
|
7728
|
-
const currentTriggerPairs =
|
|
7729
|
-
|
|
7771
|
+
const currentTriggerPairs = this._currentTriggerPairs;
|
|
7772
|
+
currentTriggerPairs.clear();
|
|
7773
|
+
const triggerNormals = this._triggerNormals;
|
|
7774
|
+
triggerNormals.clear();
|
|
7730
7775
|
for (let i = 0; i < allWithCollider.length; i++) {
|
|
7731
7776
|
for (let j = i + 1; j < allWithCollider.length; j++) {
|
|
7732
7777
|
const ia = allWithCollider[i];
|
|
@@ -7762,10 +7807,16 @@ var PhysicsSystem = class {
|
|
|
7762
7807
|
for (const [key, [a, b]] of this.activeTriggerPairs) {
|
|
7763
7808
|
if (!currentTriggerPairs.has(key)) this.events?.emit("triggerExit", { a, b, normalX: 0, normalY: 0 });
|
|
7764
7809
|
}
|
|
7765
|
-
|
|
7810
|
+
{
|
|
7811
|
+
const prev = this.activeTriggerPairs;
|
|
7812
|
+
this.activeTriggerPairs = currentTriggerPairs;
|
|
7813
|
+
this._currentTriggerPairs = prev;
|
|
7814
|
+
}
|
|
7766
7815
|
if (allCircle.length > 0) {
|
|
7767
|
-
const currentCirclePairs =
|
|
7768
|
-
|
|
7816
|
+
const currentCirclePairs = this._currentCirclePairs;
|
|
7817
|
+
currentCirclePairs.clear();
|
|
7818
|
+
const circleNormals = this._circleNormals;
|
|
7819
|
+
circleNormals.clear();
|
|
7769
7820
|
for (let i = 0; i < allCircle.length; i++) {
|
|
7770
7821
|
for (let j = i + 1; j < allCircle.length; j++) {
|
|
7771
7822
|
const ia = allCircle[i];
|
|
@@ -7832,14 +7883,19 @@ var PhysicsSystem = class {
|
|
|
7832
7883
|
for (const [key, [a, b]] of this.activeCirclePairs) {
|
|
7833
7884
|
if (!currentCirclePairs.has(key)) this.events?.emit("circleExit", { a, b, normalX: 0, normalY: 0 });
|
|
7834
7885
|
}
|
|
7835
|
-
|
|
7886
|
+
{
|
|
7887
|
+
const prev = this.activeCirclePairs;
|
|
7888
|
+
this.activeCirclePairs = currentCirclePairs;
|
|
7889
|
+
this._currentCirclePairs = prev;
|
|
7890
|
+
}
|
|
7836
7891
|
} else if (this.activeCirclePairs.size > 0) {
|
|
7837
7892
|
for (const [, [a, b]] of this.activeCirclePairs) this.events?.emit("circleExit", { a, b, normalX: 0, normalY: 0 });
|
|
7838
|
-
this.activeCirclePairs
|
|
7893
|
+
this.activeCirclePairs.clear();
|
|
7839
7894
|
}
|
|
7840
7895
|
const allCompound = world.query("Transform", "CompoundCollider");
|
|
7841
7896
|
if (allCompound.length > 0) {
|
|
7842
|
-
const currentCompoundPairs =
|
|
7897
|
+
const currentCompoundPairs = this._currentCompoundPairs;
|
|
7898
|
+
currentCompoundPairs.clear();
|
|
7843
7899
|
const allBoxEntities = world.query("Transform", "BoxCollider");
|
|
7844
7900
|
for (const cid of allCompound) {
|
|
7845
7901
|
const cc = world.getComponent(cid, "CompoundCollider");
|
|
@@ -7914,13 +7970,18 @@ var PhysicsSystem = class {
|
|
|
7914
7970
|
for (const [key, [a, b]] of this.activeCompoundPairs) {
|
|
7915
7971
|
if (!currentCompoundPairs.has(key)) this.events?.emit("compoundExit", { a, b });
|
|
7916
7972
|
}
|
|
7917
|
-
|
|
7973
|
+
{
|
|
7974
|
+
const prev = this.activeCompoundPairs;
|
|
7975
|
+
this.activeCompoundPairs = currentCompoundPairs;
|
|
7976
|
+
this._currentCompoundPairs = prev;
|
|
7977
|
+
}
|
|
7918
7978
|
} else if (this.activeCompoundPairs.size > 0) {
|
|
7919
7979
|
for (const [, [a, b]] of this.activeCompoundPairs) this.events?.emit("compoundExit", { a, b });
|
|
7920
|
-
this.activeCompoundPairs
|
|
7980
|
+
this.activeCompoundPairs.clear();
|
|
7921
7981
|
}
|
|
7922
7982
|
if (allCapsule.length > 0) {
|
|
7923
|
-
const currentCapsulePairs =
|
|
7983
|
+
const currentCapsulePairs = this._currentCapsulePairs;
|
|
7984
|
+
currentCapsulePairs.clear();
|
|
7924
7985
|
const allBoxForCapsule = world.query("Transform", "BoxCollider");
|
|
7925
7986
|
for (const cid of allCapsule) {
|
|
7926
7987
|
const cc = world.getComponent(cid, "CapsuleCollider");
|
|
@@ -7958,14 +8019,19 @@ var PhysicsSystem = class {
|
|
|
7958
8019
|
for (const [key, [a, b]] of this.activeCapsulePairs) {
|
|
7959
8020
|
if (!currentCapsulePairs.has(key)) this.events?.emit("capsuleExit", { a, b });
|
|
7960
8021
|
}
|
|
7961
|
-
|
|
8022
|
+
{
|
|
8023
|
+
const prev = this.activeCapsulePairs;
|
|
8024
|
+
this.activeCapsulePairs = currentCapsulePairs;
|
|
8025
|
+
this._currentCapsulePairs = prev;
|
|
8026
|
+
}
|
|
7962
8027
|
} else if (this.activeCapsulePairs.size > 0) {
|
|
7963
8028
|
for (const [, [a, b]] of this.activeCapsulePairs) this.events?.emit("capsuleExit", { a, b });
|
|
7964
|
-
this.activeCapsulePairs
|
|
8029
|
+
this.activeCapsulePairs.clear();
|
|
7965
8030
|
}
|
|
7966
8031
|
const allPolygonEntities = [...allPolygon, ...allTriangle];
|
|
7967
8032
|
if (allPolygonEntities.length > 0) {
|
|
7968
|
-
const currentPolyPairs =
|
|
8033
|
+
const currentPolyPairs = this._currentPolygonPairs;
|
|
8034
|
+
currentPolyPairs.clear();
|
|
7969
8035
|
const allBoxForPoly = world.query("Transform", "BoxCollider");
|
|
7970
8036
|
for (const pid of allPolygonEntities) {
|
|
7971
8037
|
const isPoly = world.getComponent(pid, "ConvexPolygonCollider");
|
|
@@ -8046,10 +8112,14 @@ var PhysicsSystem = class {
|
|
|
8046
8112
|
for (const [key, [a, b]] of this.activePolygonPairs) {
|
|
8047
8113
|
if (!currentPolyPairs.has(key)) this.events?.emit("polygonExit", { a, b });
|
|
8048
8114
|
}
|
|
8049
|
-
|
|
8115
|
+
{
|
|
8116
|
+
const prev = this.activePolygonPairs;
|
|
8117
|
+
this.activePolygonPairs = currentPolyPairs;
|
|
8118
|
+
this._currentPolygonPairs = prev;
|
|
8119
|
+
}
|
|
8050
8120
|
} else if (this.activePolygonPairs.size > 0) {
|
|
8051
8121
|
for (const [, [a, b]] of this.activePolygonPairs) this.events?.emit("polygonExit", { a, b });
|
|
8052
|
-
this.activePolygonPairs
|
|
8122
|
+
this.activePolygonPairs.clear();
|
|
8053
8123
|
}
|
|
8054
8124
|
}
|
|
8055
8125
|
// ── Pair pruning ────────────────────────────────────────────────────────
|
package/dist/index.d.ts
CHANGED
|
@@ -67,6 +67,10 @@ interface GameProps$1 {
|
|
|
67
67
|
* - 'onDemand' — sleeps until input arrives or a component calls markDirty().
|
|
68
68
|
* Use for puzzle games, turn-based games, visual novels, level editors, or any
|
|
69
69
|
* scene where nothing changes unless the user acts. Saves battery and CPU.
|
|
70
|
+
*
|
|
71
|
+
* **Captured at mount.** This prop is read once when the Game mounts and
|
|
72
|
+
* baked into the loop. Changing it later has no effect — to switch modes,
|
|
73
|
+
* unmount and remount the Game (e.g. via a `key` change).
|
|
70
74
|
*/
|
|
71
75
|
mode?: GameLoopMode;
|
|
72
76
|
style?: CSSProperties;
|