@blorkfield/overlay-core 0.8.9 → 0.8.10
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 +2 -0
- package/dist/index.cjs +39 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +39 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -389,6 +389,8 @@ The offset calculation is your responsibility - overlay-core uses whatever posit
|
|
|
389
389
|
|
|
390
390
|
Grab uses delta-based movement: when grabbed, the entity and mouse become linked. The entity moves BY the same amount as the mouse moves, not TO the mouse position. This ensures the entity stays at its original position on grab and follows mouse movement naturally.
|
|
391
391
|
|
|
392
|
+
Grab detection uses a two-pass approach to handle fast-moving bodies. The first pass does an exact point query at the click position. If that misses (the body tunneled through the cursor between frames), a second pass sweeps the body's recent position history (last 5 frames, 20px radius) to catch it. This means you can grab entities even when they are moving quickly.
|
|
393
|
+
|
|
392
394
|
```typescript
|
|
393
395
|
// Grab object at current mouse position (only 'grabable' tagged objects)
|
|
394
396
|
const grabbedId = scene.startGrab();
|
package/dist/index.cjs
CHANGED
|
@@ -1451,6 +1451,12 @@ var OverlayScene = class {
|
|
|
1451
1451
|
this.lastGrabMousePosition = null;
|
|
1452
1452
|
this.grabbedWasDynamic = false;
|
|
1453
1453
|
this.grabVelocity = { x: 0, y: 0 };
|
|
1454
|
+
// Position history for sweep-based grab detection (catches fast-moving bodies)
|
|
1455
|
+
this.bodyPositionHistory = /* @__PURE__ */ new Map();
|
|
1456
|
+
this.grabHistoryFrames = 5;
|
|
1457
|
+
this.grabHistoryRadius = 20;
|
|
1458
|
+
// Number of physics substeps per frame — more substeps = better collision at high speeds, more CPU
|
|
1459
|
+
this.substeps = 2;
|
|
1454
1460
|
/** Handle mouse down - start grab via programmatic API */
|
|
1455
1461
|
this.handleMouseDown = (event) => {
|
|
1456
1462
|
const rect = this.canvas.getBoundingClientRect();
|
|
@@ -1527,6 +1533,10 @@ var OverlayScene = class {
|
|
|
1527
1533
|
};
|
|
1528
1534
|
// ==================== PRIVATE ====================
|
|
1529
1535
|
this.loop = () => {
|
|
1536
|
+
const substepDelta = 1e3 / 60 / this.substeps;
|
|
1537
|
+
for (let i = 0; i < this.substeps; i++) {
|
|
1538
|
+
import_matter_js5.default.Engine.update(this.engine, substepDelta);
|
|
1539
|
+
}
|
|
1530
1540
|
this.effectManager.update();
|
|
1531
1541
|
this.checkTTLExpiration();
|
|
1532
1542
|
this.checkDespawnBelowFloor();
|
|
@@ -1570,6 +1580,14 @@ var OverlayScene = class {
|
|
|
1570
1580
|
if (entry.domElement && entry.tags.includes("falling")) {
|
|
1571
1581
|
this.updateDOMElementTransform(entry);
|
|
1572
1582
|
}
|
|
1583
|
+
if (entry.tags.includes("grabable") && !entry.body.isStatic) {
|
|
1584
|
+
const history = this.bodyPositionHistory.get(entry.body.id) ?? [];
|
|
1585
|
+
history.push({ x: entry.body.position.x, y: entry.body.position.y });
|
|
1586
|
+
if (history.length > this.grabHistoryFrames) {
|
|
1587
|
+
history.shift();
|
|
1588
|
+
}
|
|
1589
|
+
this.bodyPositionHistory.set(entry.body.id, history);
|
|
1590
|
+
}
|
|
1573
1591
|
}
|
|
1574
1592
|
if (!this.config.debug) {
|
|
1575
1593
|
this.drawTTFGlyphs();
|
|
@@ -1831,7 +1849,7 @@ var OverlayScene = class {
|
|
|
1831
1849
|
}
|
|
1832
1850
|
}
|
|
1833
1851
|
if (parts.length > 0) {
|
|
1834
|
-
|
|
1852
|
+
logger.debug("[Pressure]", parts.join(" "));
|
|
1835
1853
|
}
|
|
1836
1854
|
}
|
|
1837
1855
|
/** Calculate weighted pressure from a set of object IDs */
|
|
@@ -2008,7 +2026,6 @@ var OverlayScene = class {
|
|
|
2008
2026
|
}
|
|
2009
2027
|
start() {
|
|
2010
2028
|
import_matter_js5.default.Render.run(this.render);
|
|
2011
|
-
import_matter_js5.default.Runner.run(this.runner, this.engine);
|
|
2012
2029
|
this.loop();
|
|
2013
2030
|
}
|
|
2014
2031
|
stop() {
|
|
@@ -2382,6 +2399,7 @@ var OverlayScene = class {
|
|
|
2382
2399
|
import_matter_js5.default.Composite.allBodies(this.engine.world),
|
|
2383
2400
|
position
|
|
2384
2401
|
);
|
|
2402
|
+
logger.debug("OverlayScene", "Grabbed position " + position + ', had "' + bodies.length + '"');
|
|
2385
2403
|
for (const body of bodies) {
|
|
2386
2404
|
const entry = this.findObjectByBody(body);
|
|
2387
2405
|
if (entry && entry.tags.includes("grabable")) {
|
|
@@ -2393,6 +2411,24 @@ var OverlayScene = class {
|
|
|
2393
2411
|
return entry.id;
|
|
2394
2412
|
}
|
|
2395
2413
|
}
|
|
2414
|
+
const r2 = this.grabHistoryRadius * this.grabHistoryRadius;
|
|
2415
|
+
for (const entry of this.objects.values()) {
|
|
2416
|
+
if (!entry.tags.includes("grabable")) continue;
|
|
2417
|
+
const history = this.bodyPositionHistory.get(entry.body.id);
|
|
2418
|
+
if (!history) continue;
|
|
2419
|
+
for (const pastPos of history) {
|
|
2420
|
+
const dx = position.x - pastPos.x;
|
|
2421
|
+
const dy = position.y - pastPos.y;
|
|
2422
|
+
if (dx * dx + dy * dy <= r2) {
|
|
2423
|
+
this.grabbedObjectId = entry.id;
|
|
2424
|
+
this.lastGrabMousePosition = { x: position.x, y: position.y };
|
|
2425
|
+
this.grabVelocity = { x: 0, y: 0 };
|
|
2426
|
+
this.grabbedWasDynamic = !entry.body.isStatic;
|
|
2427
|
+
import_matter_js5.default.Body.setStatic(entry.body, true);
|
|
2428
|
+
return entry.id;
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2396
2432
|
return null;
|
|
2397
2433
|
}
|
|
2398
2434
|
/**
|
|
@@ -2406,6 +2442,7 @@ var OverlayScene = class {
|
|
|
2406
2442
|
import_matter_js5.default.Sleeping.set(entry.body, false);
|
|
2407
2443
|
import_matter_js5.default.Body.setVelocity(entry.body, this.grabVelocity);
|
|
2408
2444
|
import_matter_js5.default.Body.setAngularVelocity(entry.body, 0);
|
|
2445
|
+
this.bodyPositionHistory.delete(entry.body.id);
|
|
2409
2446
|
}
|
|
2410
2447
|
}
|
|
2411
2448
|
this.grabbedObjectId = null;
|