@relu-interactives/spatial-ecs 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/{chunk-Z6ZMR3CS.js → chunk-DF5SSRN6.js} +75 -4
- package/dist/chunk-DF5SSRN6.js.map +1 -0
- package/dist/{index-CppKDxbu.d.ts → index-D2Jt_JzH.d.ts} +11 -0
- package/dist/{index-I2IsocYW.d.cts → index-DaG03vyN.d.cts} +11 -0
- package/dist/index.cjs +73 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/systems/index.cjs +73 -2
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +1 -1
- package/dist/systems/index.d.ts +1 -1
- package/dist/systems/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-Z6ZMR3CS.js.map +0 -1
|
@@ -736,6 +736,10 @@ declare class XREnvironmentSystem implements EcsSystem {
|
|
|
736
736
|
private roomCaptureRequested;
|
|
737
737
|
/** This frame's inverse viewer matrix, or null when unavailable. */
|
|
738
738
|
private viewerInverse;
|
|
739
|
+
/** This frame's viewer position in reference space, for room election. */
|
|
740
|
+
private viewerPos;
|
|
741
|
+
/** The ONE global room mesh currently allowed to spawn. */
|
|
742
|
+
private electedGlobalMesh;
|
|
739
743
|
private readonly tmpViewerMatrix;
|
|
740
744
|
private readonly tmpViewPos;
|
|
741
745
|
update(world: World, deltaTime?: number): void;
|
|
@@ -786,6 +790,13 @@ declare class XREnvironmentSystem implements EcsSystem {
|
|
|
786
790
|
private findRig;
|
|
787
791
|
private syncPlanes;
|
|
788
792
|
private syncMeshes;
|
|
793
|
+
/**
|
|
794
|
+
* Pick THE room's global mesh: the one whose scan origin is nearest the
|
|
795
|
+
* viewer, sticky to the current choice within a margin so origin jitter
|
|
796
|
+
* can't flap the room. Without a viewer pose (or with a single candidate)
|
|
797
|
+
* the first candidate stands; ties are impossible to break anyway.
|
|
798
|
+
*/
|
|
799
|
+
private electGlobalMesh;
|
|
789
800
|
/**
|
|
790
801
|
* Admission control for a NOT-yet-spawned surface. With a viewer pose
|
|
791
802
|
* available, the surface must behave world-anchored for a few frames before
|
|
@@ -736,6 +736,10 @@ declare class XREnvironmentSystem implements EcsSystem {
|
|
|
736
736
|
private roomCaptureRequested;
|
|
737
737
|
/** This frame's inverse viewer matrix, or null when unavailable. */
|
|
738
738
|
private viewerInverse;
|
|
739
|
+
/** This frame's viewer position in reference space, for room election. */
|
|
740
|
+
private viewerPos;
|
|
741
|
+
/** The ONE global room mesh currently allowed to spawn. */
|
|
742
|
+
private electedGlobalMesh;
|
|
739
743
|
private readonly tmpViewerMatrix;
|
|
740
744
|
private readonly tmpViewPos;
|
|
741
745
|
update(world: World, deltaTime?: number): void;
|
|
@@ -786,6 +790,13 @@ declare class XREnvironmentSystem implements EcsSystem {
|
|
|
786
790
|
private findRig;
|
|
787
791
|
private syncPlanes;
|
|
788
792
|
private syncMeshes;
|
|
793
|
+
/**
|
|
794
|
+
* Pick THE room's global mesh: the one whose scan origin is nearest the
|
|
795
|
+
* viewer, sticky to the current choice within a margin so origin jitter
|
|
796
|
+
* can't flap the room. Without a viewer pose (or with a single candidate)
|
|
797
|
+
* the first candidate stands; ties are impossible to break anyway.
|
|
798
|
+
*/
|
|
799
|
+
private electGlobalMesh;
|
|
789
800
|
/**
|
|
790
801
|
* Admission control for a NOT-yet-spawned surface. With a viewer pose
|
|
791
802
|
* available, the surface must behave world-anchored for a few frames before
|
package/dist/index.cjs
CHANGED
|
@@ -6042,7 +6042,12 @@ var HYDRATABLE_ENTITY_KINDS = /* @__PURE__ */ new Set([
|
|
|
6042
6042
|
"scriptObject",
|
|
6043
6043
|
"xrRig",
|
|
6044
6044
|
"xrInteractor",
|
|
6045
|
-
"teleportArea"
|
|
6045
|
+
"teleportArea",
|
|
6046
|
+
"uiPanel",
|
|
6047
|
+
"uiText",
|
|
6048
|
+
"uiButton",
|
|
6049
|
+
"uiToggle",
|
|
6050
|
+
"uiSlider"
|
|
6046
6051
|
]);
|
|
6047
6052
|
|
|
6048
6053
|
// core/hydration/hydrateWorld.ts
|
|
@@ -12978,6 +12983,11 @@ function debugColorFor(kind, semanticLabel) {
|
|
|
12978
12983
|
}
|
|
12979
12984
|
__name(debugColorFor, "debugColorFor");
|
|
12980
12985
|
var GLOBAL_MESH_DEBUG_OPACITY = 0.35;
|
|
12986
|
+
var GLOBAL_MESH_SWITCH_MARGIN = 1.5;
|
|
12987
|
+
function isGlobalMeshSurface(mesh) {
|
|
12988
|
+
return (mesh.semanticLabel ?? null) === "global mesh";
|
|
12989
|
+
}
|
|
12990
|
+
__name(isGlobalMeshSurface, "isGlobalMeshSurface");
|
|
12981
12991
|
var DEBUG_RENDER_ORDER = 900;
|
|
12982
12992
|
var ROOM_CAPTURE_DELAY_SECONDS = 3;
|
|
12983
12993
|
var SYNTHETIC_FLOOR_EXTENT = 50;
|
|
@@ -13016,6 +13026,10 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
13016
13026
|
this.roomCaptureRequested = false;
|
|
13017
13027
|
/** This frame's inverse viewer matrix, or null when unavailable. */
|
|
13018
13028
|
this.viewerInverse = null;
|
|
13029
|
+
/** This frame's viewer position in reference space, for room election. */
|
|
13030
|
+
this.viewerPos = null;
|
|
13031
|
+
/** The ONE global room mesh currently allowed to spawn. */
|
|
13032
|
+
this.electedGlobalMesh = null;
|
|
13019
13033
|
this.tmpViewerMatrix = new THREE56__namespace.Matrix4();
|
|
13020
13034
|
this.tmpViewPos = new THREE56__namespace.Vector3();
|
|
13021
13035
|
}
|
|
@@ -13056,7 +13070,14 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
13056
13070
|
const useMesh = (mode === "mesh" || mode === "auto") && meshesAvailable;
|
|
13057
13071
|
const usePlanes = mode === "planes" || mode === "auto" && !useMesh;
|
|
13058
13072
|
const viewer = frame.getViewerPose?.(referenceSpace);
|
|
13059
|
-
|
|
13073
|
+
if (viewer) {
|
|
13074
|
+
const vm = viewer.transform.matrix;
|
|
13075
|
+
this.viewerPos = { x: vm[12], y: vm[13], z: vm[14] };
|
|
13076
|
+
this.viewerInverse = this.tmpViewerMatrix.fromArray(vm).invert();
|
|
13077
|
+
} else {
|
|
13078
|
+
this.viewerPos = null;
|
|
13079
|
+
this.viewerInverse = null;
|
|
13080
|
+
}
|
|
13060
13081
|
if (usePlanes) {
|
|
13061
13082
|
this.syncPlanes(world, frame, referenceSpace, deltaTime);
|
|
13062
13083
|
} else if (this.planes.size > 0) {
|
|
@@ -13211,7 +13232,17 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
13211
13232
|
for (const mesh of this.pendingMeshes.keys()) {
|
|
13212
13233
|
if (!detected.has(mesh)) this.pendingMeshes.delete(mesh);
|
|
13213
13234
|
}
|
|
13235
|
+
const electedGlobal = this.electGlobalMesh(frame, detected, referenceSpace);
|
|
13214
13236
|
for (const mesh of detected) {
|
|
13237
|
+
if (isGlobalMeshSurface(mesh) && mesh !== electedGlobal) {
|
|
13238
|
+
const stale = this.meshes.get(mesh);
|
|
13239
|
+
if (stale) {
|
|
13240
|
+
this.destroyEntry(world, stale);
|
|
13241
|
+
this.meshes.delete(mesh);
|
|
13242
|
+
}
|
|
13243
|
+
this.pendingMeshes.delete(mesh);
|
|
13244
|
+
continue;
|
|
13245
|
+
}
|
|
13215
13246
|
const pose = frame.getPose(mesh.meshSpace, referenceSpace);
|
|
13216
13247
|
if (!pose) continue;
|
|
13217
13248
|
const emulated = pose.emulatedPosition === true;
|
|
@@ -13235,6 +13266,45 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
13235
13266
|
if (allowed) this.applyPose(world, entry.entityId, pose);
|
|
13236
13267
|
}
|
|
13237
13268
|
}
|
|
13269
|
+
/**
|
|
13270
|
+
* Pick THE room's global mesh: the one whose scan origin is nearest the
|
|
13271
|
+
* viewer, sticky to the current choice within a margin so origin jitter
|
|
13272
|
+
* can't flap the room. Without a viewer pose (or with a single candidate)
|
|
13273
|
+
* the first candidate stands; ties are impossible to break anyway.
|
|
13274
|
+
*/
|
|
13275
|
+
electGlobalMesh(frame, detected, referenceSpace) {
|
|
13276
|
+
let nearest = null;
|
|
13277
|
+
let nearestDist = Number.POSITIVE_INFINITY;
|
|
13278
|
+
let currentDist = Number.POSITIVE_INFINITY;
|
|
13279
|
+
let currentStillDetected = false;
|
|
13280
|
+
for (const mesh of detected) {
|
|
13281
|
+
if (!isGlobalMeshSurface(mesh)) continue;
|
|
13282
|
+
if (!this.viewerPos) {
|
|
13283
|
+
return this.electedGlobalMesh && detected.has(this.electedGlobalMesh) ? this.electedGlobalMesh : mesh;
|
|
13284
|
+
}
|
|
13285
|
+
const pose = frame.getPose(mesh.meshSpace, referenceSpace);
|
|
13286
|
+
if (!pose) continue;
|
|
13287
|
+
const m = pose.transform.matrix;
|
|
13288
|
+
const d = Math.hypot(
|
|
13289
|
+
m[12] - this.viewerPos.x,
|
|
13290
|
+
m[13] - this.viewerPos.y,
|
|
13291
|
+
m[14] - this.viewerPos.z
|
|
13292
|
+
);
|
|
13293
|
+
if (mesh === this.electedGlobalMesh) {
|
|
13294
|
+
currentDist = d;
|
|
13295
|
+
currentStillDetected = true;
|
|
13296
|
+
}
|
|
13297
|
+
if (d < nearestDist) {
|
|
13298
|
+
nearestDist = d;
|
|
13299
|
+
nearest = mesh;
|
|
13300
|
+
}
|
|
13301
|
+
}
|
|
13302
|
+
if (currentStillDetected && currentDist < nearestDist + GLOBAL_MESH_SWITCH_MARGIN) {
|
|
13303
|
+
return this.electedGlobalMesh;
|
|
13304
|
+
}
|
|
13305
|
+
this.electedGlobalMesh = nearest;
|
|
13306
|
+
return nearest;
|
|
13307
|
+
}
|
|
13238
13308
|
/**
|
|
13239
13309
|
* Admission control for a NOT-yet-spawned surface. With a viewer pose
|
|
13240
13310
|
* available, the surface must behave world-anchored for a few frames before
|
|
@@ -13446,6 +13516,7 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
13446
13516
|
this.clearMap(world, this.meshes);
|
|
13447
13517
|
this.pendingPlanes.clear();
|
|
13448
13518
|
this.pendingMeshes.clear();
|
|
13519
|
+
this.electedGlobalMesh = null;
|
|
13449
13520
|
}
|
|
13450
13521
|
dispose(world) {
|
|
13451
13522
|
this.clearAll(world);
|