@relu-interactives/spatial-ecs 0.2.5 → 0.2.6
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/{Video-DCMCLInA.d.ts → Video-B-qMljTn.d.ts} +15 -7
- package/dist/{Video-ChVFs9Tl.d.cts → Video-Dj4KBqQ1.d.cts} +15 -7
- package/dist/{chunk-4A66FSFT.js → chunk-EIC5B3A7.js} +4 -4
- package/dist/{chunk-4A66FSFT.js.map → chunk-EIC5B3A7.js.map} +1 -1
- package/dist/{chunk-CRP3W2GK.js → chunk-FDWNCXU3.js} +3 -3
- package/dist/{chunk-CRP3W2GK.js.map → chunk-FDWNCXU3.js.map} +1 -1
- package/dist/{chunk-NB6I5JJN.js → chunk-G2DUXNTQ.js} +3 -2
- package/dist/chunk-G2DUXNTQ.js.map +1 -0
- package/dist/{chunk-RXCUHGRB.js → chunk-NRSUYDBA.js} +183 -32
- package/dist/chunk-NRSUYDBA.js.map +1 -0
- package/dist/{chunk-KRZLEPRI.js → chunk-R5D5PWXV.js} +6 -2
- package/dist/chunk-R5D5PWXV.js.map +1 -0
- package/dist/components/index.cjs +4 -0
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +1 -1
- package/dist/factories/index.cjs +4 -0
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +1 -1
- package/dist/factories/index.d.ts +1 -1
- package/dist/factories/index.js +3 -3
- package/dist/{index-D1I5L7bA.d.cts → index-B12sx9yF.d.cts} +1 -1
- package/dist/{index-DGZDgt3p.d.ts → index-Cf-PaKyN.d.ts} +1 -1
- package/dist/index.cjs +187 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +12 -9
- package/dist/index.js.map +1 -1
- package/dist/systems/index.cjs +183 -28
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +16 -4
- package/dist/systems/index.d.ts +16 -4
- package/dist/systems/index.js +3 -3
- package/dist/worldSnapshotUtils.cjs +1 -0
- package/dist/worldSnapshotUtils.cjs.map +1 -1
- package/dist/worldSnapshotUtils.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-KRZLEPRI.js.map +0 -1
- package/dist/chunk-NB6I5JJN.js.map +0 -1
- package/dist/chunk-RXCUHGRB.js.map +0 -1
package/dist/systems/index.cjs
CHANGED
|
@@ -1325,6 +1325,7 @@ var DEFAULT_INSTANCED_MESH_PARAMETERS = {
|
|
|
1325
1325
|
capsule: DEFAULT_MESH_GEOMETRY_PARAMETERS.capsule,
|
|
1326
1326
|
cube: DEFAULT_MESH_GEOMETRY_PARAMETERS.cube,
|
|
1327
1327
|
cylinder: DEFAULT_MESH_GEOMETRY_PARAMETERS.cylinder,
|
|
1328
|
+
model: DEFAULT_MESH_GEOMETRY_PARAMETERS.cube,
|
|
1328
1329
|
plane: DEFAULT_MESH_GEOMETRY_PARAMETERS.plane,
|
|
1329
1330
|
sphere: DEFAULT_MESH_GEOMETRY_PARAMETERS.sphere
|
|
1330
1331
|
};
|
|
@@ -1332,6 +1333,7 @@ var _InstancedMeshComponent = class _InstancedMeshComponent extends Component {
|
|
|
1332
1333
|
constructor(meshKind = "cube", meshParameters, options) {
|
|
1333
1334
|
super();
|
|
1334
1335
|
this.meshKind = meshKind;
|
|
1336
|
+
this.modelPath = options?.modelPath ?? "";
|
|
1335
1337
|
this.meshParameters = {
|
|
1336
1338
|
...DEFAULT_INSTANCED_MESH_PARAMETERS[meshKind],
|
|
1337
1339
|
...meshParameters ?? {}
|
|
@@ -1374,6 +1376,8 @@ var _InstancedMeshComponent = class _InstancedMeshComponent extends Component {
|
|
|
1374
1376
|
height: sanitize(p.height, MIN_DIM)
|
|
1375
1377
|
};
|
|
1376
1378
|
}
|
|
1379
|
+
case "model":
|
|
1380
|
+
return DEFAULT_MESH_GEOMETRY_PARAMETERS.cube;
|
|
1377
1381
|
}
|
|
1378
1382
|
}
|
|
1379
1383
|
};
|
|
@@ -4133,6 +4137,32 @@ var _MeshGeometrySystem = class _MeshGeometrySystem {
|
|
|
4133
4137
|
};
|
|
4134
4138
|
__name(_MeshGeometrySystem, "MeshGeometrySystem");
|
|
4135
4139
|
var MeshGeometrySystem = _MeshGeometrySystem;
|
|
4140
|
+
var DRACO_DECODER_PATH = resolveDracoDecoderPath();
|
|
4141
|
+
var loadGLTF = /* @__PURE__ */ __name((path) => {
|
|
4142
|
+
return new Promise((resolve, reject) => {
|
|
4143
|
+
const loader = new GLTFLoader_js.GLTFLoader();
|
|
4144
|
+
try {
|
|
4145
|
+
const dracoLoader = new DRACOLoader_js.DRACOLoader();
|
|
4146
|
+
dracoLoader.setDecoderPath(DRACO_DECODER_PATH);
|
|
4147
|
+
loader.setDRACOLoader(dracoLoader);
|
|
4148
|
+
} catch (error) {
|
|
4149
|
+
console.debug("DRACOLoader setup failed or unavailable", error);
|
|
4150
|
+
}
|
|
4151
|
+
loader.load(
|
|
4152
|
+
path,
|
|
4153
|
+
(gltf) => {
|
|
4154
|
+
resolve(gltf);
|
|
4155
|
+
},
|
|
4156
|
+
void 0,
|
|
4157
|
+
(error) => {
|
|
4158
|
+
console.debug("GLTFLoader failed to load", error);
|
|
4159
|
+
reject(error);
|
|
4160
|
+
}
|
|
4161
|
+
);
|
|
4162
|
+
});
|
|
4163
|
+
}, "loadGLTF");
|
|
4164
|
+
|
|
4165
|
+
// core/systems/InstancedMeshSystem.ts
|
|
4136
4166
|
function buildGeometry(component) {
|
|
4137
4167
|
const p = component.getSanitizedParameters();
|
|
4138
4168
|
switch (component.meshKind) {
|
|
@@ -4156,6 +4186,8 @@ function buildGeometry(component) {
|
|
|
4156
4186
|
const params = p;
|
|
4157
4187
|
return new THREE13__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
|
|
4158
4188
|
}
|
|
4189
|
+
default:
|
|
4190
|
+
return new THREE13__namespace.BoxGeometry(1, 1, 1);
|
|
4159
4191
|
}
|
|
4160
4192
|
}
|
|
4161
4193
|
__name(buildGeometry, "buildGeometry");
|
|
@@ -4164,6 +4196,7 @@ var _quaternion = new THREE13__namespace.Quaternion();
|
|
|
4164
4196
|
var _euler = new THREE13__namespace.Euler();
|
|
4165
4197
|
var _scale = new THREE13__namespace.Vector3();
|
|
4166
4198
|
var _matrix = new THREE13__namespace.Matrix4();
|
|
4199
|
+
var _modelMatrix = new THREE13__namespace.Matrix4();
|
|
4167
4200
|
function instanceTransformToMatrix4(inst, out) {
|
|
4168
4201
|
_position.set(inst.position.x, inst.position.y, inst.position.z);
|
|
4169
4202
|
_euler.set(inst.rotation.x, inst.rotation.y, inst.rotation.z, "XYZ");
|
|
@@ -4172,51 +4205,156 @@ function instanceTransformToMatrix4(inst, out) {
|
|
|
4172
4205
|
out.compose(_position, _quaternion, _scale);
|
|
4173
4206
|
}
|
|
4174
4207
|
__name(instanceTransformToMatrix4, "instanceTransformToMatrix4");
|
|
4208
|
+
function disposePrimitiveInstancedMesh(mesh) {
|
|
4209
|
+
mesh.geometry.dispose();
|
|
4210
|
+
if (Array.isArray(mesh.material)) {
|
|
4211
|
+
for (const m of mesh.material) {
|
|
4212
|
+
m.dispose();
|
|
4213
|
+
}
|
|
4214
|
+
} else {
|
|
4215
|
+
mesh.material.dispose();
|
|
4216
|
+
}
|
|
4217
|
+
}
|
|
4218
|
+
__name(disposePrimitiveInstancedMesh, "disposePrimitiveInstancedMesh");
|
|
4219
|
+
function disposeModelGroup(group) {
|
|
4220
|
+
group.traverse((child) => {
|
|
4221
|
+
const im = child;
|
|
4222
|
+
if (im.isInstancedMesh) {
|
|
4223
|
+
im.geometry.dispose();
|
|
4224
|
+
if (Array.isArray(im.material)) {
|
|
4225
|
+
for (const m of im.material) {
|
|
4226
|
+
m.dispose();
|
|
4227
|
+
}
|
|
4228
|
+
} else {
|
|
4229
|
+
im.material.dispose();
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
});
|
|
4233
|
+
}
|
|
4234
|
+
__name(disposeModelGroup, "disposeModelGroup");
|
|
4175
4235
|
var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
4176
4236
|
constructor() {
|
|
4177
4237
|
/** Signature tracking for geometry + instance count changes. */
|
|
4178
4238
|
this.geometrySignatures = /* @__PURE__ */ new Map();
|
|
4239
|
+
/** Entities whose GLTF model is currently loading. Prevents duplicate load triggers. */
|
|
4240
|
+
this.loadingEntities = /* @__PURE__ */ new Set();
|
|
4241
|
+
/** Per-mesh data for model kind, populated after GLTF load. */
|
|
4242
|
+
this.modelMeshEntries = /* @__PURE__ */ new Map();
|
|
4179
4243
|
}
|
|
4180
4244
|
update(world) {
|
|
4181
4245
|
const entityIds = world.query(InstancedMeshComponent);
|
|
4182
4246
|
const alive = new Set(entityIds);
|
|
4183
4247
|
for (const trackedId of this.geometrySignatures.keys()) {
|
|
4184
|
-
if (!alive.has(trackedId))
|
|
4185
|
-
|
|
4186
|
-
|
|
4248
|
+
if (!alive.has(trackedId)) this.geometrySignatures.delete(trackedId);
|
|
4249
|
+
}
|
|
4250
|
+
for (const trackedId of this.loadingEntities) {
|
|
4251
|
+
if (!alive.has(trackedId)) this.loadingEntities.delete(trackedId);
|
|
4252
|
+
}
|
|
4253
|
+
for (const trackedId of this.modelMeshEntries.keys()) {
|
|
4254
|
+
if (!alive.has(trackedId)) this.modelMeshEntries.delete(trackedId);
|
|
4187
4255
|
}
|
|
4188
4256
|
for (const entityId of entityIds) {
|
|
4189
4257
|
const comp = world.getComponent(
|
|
4190
4258
|
entityId,
|
|
4191
4259
|
InstancedMeshComponent
|
|
4192
4260
|
);
|
|
4193
|
-
if (!comp)
|
|
4194
|
-
continue;
|
|
4195
|
-
}
|
|
4196
|
-
let anchor = null;
|
|
4261
|
+
if (!comp) continue;
|
|
4197
4262
|
const objectRef = world.getComponent(entityId, Object3DRef);
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
}
|
|
4201
|
-
if (!anchor) {
|
|
4202
|
-
continue;
|
|
4203
|
-
}
|
|
4263
|
+
const anchor = objectRef?.object ?? null;
|
|
4264
|
+
if (!anchor) continue;
|
|
4204
4265
|
const instanceCount = comp.instances.length;
|
|
4205
|
-
const geometrySignature = `${comp.meshKind}:${JSON.stringify(comp.meshParameters)}:${instanceCount}`;
|
|
4266
|
+
const geometrySignature = comp.meshKind === "model" ? `model:${comp.modelPath}:${instanceCount}` : `${comp.meshKind}:${JSON.stringify(comp.meshParameters)}:${instanceCount}`;
|
|
4206
4267
|
const needsRebuild = comp.instancedMesh === null || this.geometrySignatures.get(entityId) !== geometrySignature;
|
|
4207
4268
|
if (needsRebuild) {
|
|
4208
4269
|
if (comp.instancedMesh) {
|
|
4209
4270
|
anchor.remove(comp.instancedMesh);
|
|
4210
|
-
comp.instancedMesh.
|
|
4211
|
-
|
|
4212
|
-
for (const m of comp.instancedMesh.material) {
|
|
4213
|
-
m.dispose();
|
|
4214
|
-
}
|
|
4271
|
+
if (comp.instancedMesh.isInstancedMesh) {
|
|
4272
|
+
disposePrimitiveInstancedMesh(comp.instancedMesh);
|
|
4215
4273
|
} else {
|
|
4216
|
-
comp.instancedMesh
|
|
4274
|
+
disposeModelGroup(comp.instancedMesh);
|
|
4217
4275
|
}
|
|
4218
4276
|
comp.instancedMesh = null;
|
|
4219
4277
|
}
|
|
4278
|
+
this.loadingEntities.delete(entityId);
|
|
4279
|
+
this.modelMeshEntries.delete(entityId);
|
|
4280
|
+
if (comp.meshKind === "model") {
|
|
4281
|
+
if (comp.modelPath && !this.loadingEntities.has(entityId)) {
|
|
4282
|
+
this.loadingEntities.add(entityId);
|
|
4283
|
+
const targetSignature = geometrySignature;
|
|
4284
|
+
const targetEntityId = entityId;
|
|
4285
|
+
loadGLTF(comp.modelPath).then((gltf) => {
|
|
4286
|
+
if (!world.hasEntity(targetEntityId)) {
|
|
4287
|
+
this.loadingEntities.delete(targetEntityId);
|
|
4288
|
+
return;
|
|
4289
|
+
}
|
|
4290
|
+
const currentComp = world.getComponent(
|
|
4291
|
+
targetEntityId,
|
|
4292
|
+
InstancedMeshComponent
|
|
4293
|
+
);
|
|
4294
|
+
if (!currentComp) {
|
|
4295
|
+
this.loadingEntities.delete(targetEntityId);
|
|
4296
|
+
return;
|
|
4297
|
+
}
|
|
4298
|
+
const currentSig = `model:${currentComp.modelPath}:${currentComp.instances.length}`;
|
|
4299
|
+
if (currentSig !== targetSignature) {
|
|
4300
|
+
this.loadingEntities.delete(targetEntityId);
|
|
4301
|
+
return;
|
|
4302
|
+
}
|
|
4303
|
+
const currentRef = world.getComponent(targetEntityId, Object3DRef);
|
|
4304
|
+
const currentAnchor = currentRef?.object ?? null;
|
|
4305
|
+
if (!currentAnchor) {
|
|
4306
|
+
this.loadingEntities.delete(targetEntityId);
|
|
4307
|
+
return;
|
|
4308
|
+
}
|
|
4309
|
+
const count2 = Math.max(1, currentComp.instances.length);
|
|
4310
|
+
const entries = [];
|
|
4311
|
+
gltf.scene.updateWorldMatrix(true, true);
|
|
4312
|
+
gltf.scene.traverse((child) => {
|
|
4313
|
+
const meshChild = child;
|
|
4314
|
+
if (!meshChild.isMesh) return;
|
|
4315
|
+
const geometry2 = meshChild.geometry.clone();
|
|
4316
|
+
const sourceMaterial = Array.isArray(meshChild.material) ? meshChild.material.map((m) => m.clone()) : meshChild.material.clone();
|
|
4317
|
+
meshChild.updateWorldMatrix(true, false);
|
|
4318
|
+
const localMatrix = meshChild.matrixWorld.clone();
|
|
4319
|
+
const instancedMesh2 = new THREE13__namespace.InstancedMesh(
|
|
4320
|
+
geometry2,
|
|
4321
|
+
Array.isArray(sourceMaterial) ? sourceMaterial : sourceMaterial,
|
|
4322
|
+
count2
|
|
4323
|
+
);
|
|
4324
|
+
instancedMesh2.castShadow = currentComp.castShadow;
|
|
4325
|
+
instancedMesh2.receiveShadow = currentComp.receiveShadow;
|
|
4326
|
+
for (let i = 0; i < count2; i++) {
|
|
4327
|
+
const inst = currentComp.instances[i] ?? {
|
|
4328
|
+
position: { x: 0, y: 0, z: 0 },
|
|
4329
|
+
rotation: { x: 0, y: 0, z: 0 },
|
|
4330
|
+
scale: { x: 1, y: 1, z: 1 }
|
|
4331
|
+
};
|
|
4332
|
+
instanceTransformToMatrix4(inst, _matrix);
|
|
4333
|
+
_modelMatrix.multiplyMatrices(_matrix, localMatrix);
|
|
4334
|
+
instancedMesh2.setMatrixAt(i, _modelMatrix);
|
|
4335
|
+
}
|
|
4336
|
+
instancedMesh2.instanceMatrix.needsUpdate = true;
|
|
4337
|
+
entries.push({ localMatrix, instancedMesh: instancedMesh2 });
|
|
4338
|
+
});
|
|
4339
|
+
if (entries.length === 0) {
|
|
4340
|
+
this.loadingEntities.delete(targetEntityId);
|
|
4341
|
+
return;
|
|
4342
|
+
}
|
|
4343
|
+
const group = new THREE13__namespace.Group();
|
|
4344
|
+
for (const entry of entries) {
|
|
4345
|
+
group.add(entry.instancedMesh);
|
|
4346
|
+
}
|
|
4347
|
+
currentAnchor.add(group);
|
|
4348
|
+
currentComp.instancedMesh = group;
|
|
4349
|
+
this.modelMeshEntries.set(targetEntityId, entries);
|
|
4350
|
+
this.geometrySignatures.set(targetEntityId, targetSignature);
|
|
4351
|
+
this.loadingEntities.delete(targetEntityId);
|
|
4352
|
+
}).catch(() => {
|
|
4353
|
+
this.loadingEntities.delete(targetEntityId);
|
|
4354
|
+
});
|
|
4355
|
+
}
|
|
4356
|
+
continue;
|
|
4357
|
+
}
|
|
4220
4358
|
const count = Math.max(1, instanceCount);
|
|
4221
4359
|
const geometry = buildGeometry(comp);
|
|
4222
4360
|
const material = new THREE13__namespace.MeshStandardMaterial({ color: "#ffffff" });
|
|
@@ -4237,15 +4375,32 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
4237
4375
|
comp.instancedMesh = instancedMesh;
|
|
4238
4376
|
this.geometrySignatures.set(entityId, geometrySignature);
|
|
4239
4377
|
} else {
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4378
|
+
if (comp.meshKind === "model") {
|
|
4379
|
+
const entries = this.modelMeshEntries.get(entityId);
|
|
4380
|
+
if (entries) {
|
|
4381
|
+
const count = comp.instances.length;
|
|
4382
|
+
for (const entry of entries) {
|
|
4383
|
+
for (let i = 0; i < count; i++) {
|
|
4384
|
+
instanceTransformToMatrix4(comp.instances[i], _matrix);
|
|
4385
|
+
_modelMatrix.multiplyMatrices(_matrix, entry.localMatrix);
|
|
4386
|
+
entry.instancedMesh.setMatrixAt(i, _modelMatrix);
|
|
4387
|
+
}
|
|
4388
|
+
entry.instancedMesh.instanceMatrix.needsUpdate = true;
|
|
4389
|
+
entry.instancedMesh.castShadow = comp.castShadow;
|
|
4390
|
+
entry.instancedMesh.receiveShadow = comp.receiveShadow;
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
} else {
|
|
4394
|
+
const im = comp.instancedMesh;
|
|
4395
|
+
const count = comp.instances.length;
|
|
4396
|
+
for (let i = 0; i < count; i++) {
|
|
4397
|
+
instanceTransformToMatrix4(comp.instances[i], _matrix);
|
|
4398
|
+
im.setMatrixAt(i, _matrix);
|
|
4399
|
+
}
|
|
4400
|
+
im.instanceMatrix.needsUpdate = true;
|
|
4401
|
+
im.castShadow = comp.castShadow;
|
|
4402
|
+
im.receiveShadow = comp.receiveShadow;
|
|
4245
4403
|
}
|
|
4246
|
-
im.instanceMatrix.needsUpdate = true;
|
|
4247
|
-
im.castShadow = comp.castShadow;
|
|
4248
|
-
im.receiveShadow = comp.receiveShadow;
|
|
4249
4404
|
}
|
|
4250
4405
|
}
|
|
4251
4406
|
}
|