@relu-interactives/spatial-ecs 0.2.6 → 0.2.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.
Files changed (49) hide show
  1. package/dist/{System-CIiWteft.d.cts → System-AV2_87Zr.d.cts} +1 -1
  2. package/dist/{System-CIiWteft.d.ts → System-AV2_87Zr.d.ts} +1 -1
  3. package/dist/{Video-Dj4KBqQ1.d.cts → Video-Bn93p6XV.d.cts} +27 -5
  4. package/dist/{Video-B-qMljTn.d.ts → Video-D6mObK_5.d.ts} +27 -5
  5. package/dist/{chunk-R5D5PWXV.js → chunk-AZR6SLQN.js} +16 -4
  6. package/dist/chunk-AZR6SLQN.js.map +1 -0
  7. package/dist/{chunk-EIC5B3A7.js → chunk-LE6ARNYQ.js} +84 -13
  8. package/dist/chunk-LE6ARNYQ.js.map +1 -0
  9. package/dist/{chunk-FDWNCXU3.js → chunk-ODCWJHPS.js} +3 -3
  10. package/dist/{chunk-FDWNCXU3.js.map → chunk-ODCWJHPS.js.map} +1 -1
  11. package/dist/{chunk-G2DUXNTQ.js → chunk-PHIEXEKJ.js} +10 -3
  12. package/dist/chunk-PHIEXEKJ.js.map +1 -0
  13. package/dist/{chunk-NRSUYDBA.js → chunk-TVBWYIGY.js} +67 -44
  14. package/dist/chunk-TVBWYIGY.js.map +1 -0
  15. package/dist/components/index.cjs +13 -1
  16. package/dist/components/index.cjs.map +1 -1
  17. package/dist/components/index.d.cts +2 -2
  18. package/dist/components/index.d.ts +2 -2
  19. package/dist/components/index.js +1 -1
  20. package/dist/factories/index.cjs +92 -9
  21. package/dist/factories/index.cjs.map +1 -1
  22. package/dist/factories/index.d.cts +7 -4
  23. package/dist/factories/index.d.ts +7 -4
  24. package/dist/factories/index.js +3 -3
  25. package/dist/{index-Cf-PaKyN.d.ts → index-B4-ABchF.d.cts} +4 -3
  26. package/dist/{index-B12sx9yF.d.cts → index-BO49V8aS.d.ts} +4 -3
  27. package/dist/index.cjs +207 -55
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +6 -6
  30. package/dist/index.d.ts +6 -6
  31. package/dist/index.js +52 -14
  32. package/dist/index.js.map +1 -1
  33. package/dist/systems/index.cjs +64 -46
  34. package/dist/systems/index.cjs.map +1 -1
  35. package/dist/systems/index.d.cts +5 -4
  36. package/dist/systems/index.d.ts +5 -4
  37. package/dist/systems/index.js +3 -3
  38. package/dist/types.d.cts +1 -1
  39. package/dist/types.d.ts +1 -1
  40. package/dist/worldSnapshotUtils.cjs +8 -1
  41. package/dist/worldSnapshotUtils.cjs.map +1 -1
  42. package/dist/worldSnapshotUtils.d.cts +1 -1
  43. package/dist/worldSnapshotUtils.d.ts +1 -1
  44. package/dist/worldSnapshotUtils.js +1 -1
  45. package/package.json +1 -1
  46. package/dist/chunk-EIC5B3A7.js.map +0 -1
  47. package/dist/chunk-G2DUXNTQ.js.map +0 -1
  48. package/dist/chunk-NRSUYDBA.js.map +0 -1
  49. package/dist/chunk-R5D5PWXV.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -150,6 +150,13 @@ function normalizeDebugValue(value, ctx) {
150
150
  crossFadeDuration: typeof objectValue.crossFadeDuration === "number" && Number.isFinite(objectValue.crossFadeDuration) ? Math.max(0, objectValue.crossFadeDuration) : 0
151
151
  };
152
152
  }
153
+ if (constructorName === "InstanceSlotComponent") {
154
+ return {
155
+ __type: "InstanceSlotComponent",
156
+ groupEntityId: typeof objectValue.groupEntityId === "number" ? objectValue.groupEntityId : -1,
157
+ slotIndex: typeof objectValue.slotIndex === "number" ? objectValue.slotIndex : 0
158
+ };
159
+ }
153
160
  if (constructorName === "InstancedMeshComponent") {
154
161
  const imCtx = {
155
162
  seen: ctx.seen,
@@ -163,7 +170,7 @@ function normalizeDebugValue(value, ctx) {
163
170
  meshParameters: normalizeDebugValue(objectValue.meshParameters, imCtx),
164
171
  castShadow: Boolean(objectValue.castShadow),
165
172
  receiveShadow: Boolean(objectValue.receiveShadow),
166
- instances: normalizeDebugValue(objectValue.instances, imCtx)
173
+ instanceEntityIds: Array.isArray(objectValue.instanceEntityIds) ? [...objectValue.instanceEntityIds] : []
167
174
  };
168
175
  }
169
176
  if (constructorName === "PhysicsComponent") {
@@ -2238,7 +2245,7 @@ var _InstancedMeshComponent = class _InstancedMeshComponent extends Component {
2238
2245
  };
2239
2246
  this.castShadow = options?.castShadow ?? false;
2240
2247
  this.receiveShadow = options?.receiveShadow ?? false;
2241
- this.instances = options?.instances && options.instances.length > 0 ? options.instances : [{ ...DEFAULT_INSTANCE_TRANSFORM }];
2248
+ this.instanceEntityIds = options?.instanceEntityIds ?? [];
2242
2249
  this.instancedMesh = null;
2243
2250
  }
2244
2251
  /** Sanitize and return a copy of the current mesh parameters with valid values. */
@@ -2290,6 +2297,25 @@ function createInstancedMeshComponent(world, entityId, meshKind, meshParameters,
2290
2297
  }
2291
2298
  __name(createInstancedMeshComponent, "createInstancedMeshComponent");
2292
2299
 
2300
+ // core/components/InstanceSlotComponent.ts
2301
+ var _InstanceSlotComponent = class _InstanceSlotComponent extends Component {
2302
+ constructor(groupEntityId, slotIndex) {
2303
+ super();
2304
+ this.groupEntityId = groupEntityId;
2305
+ this.slotIndex = slotIndex;
2306
+ }
2307
+ };
2308
+ __name(_InstanceSlotComponent, "InstanceSlotComponent");
2309
+ var InstanceSlotComponent = _InstanceSlotComponent;
2310
+
2311
+ // core/factories/components/InstanceSlotComponentFactory.ts
2312
+ function createInstanceSlotComponent(world, entityId, groupEntityId, slotIndex) {
2313
+ const component = new InstanceSlotComponent(groupEntityId, slotIndex);
2314
+ world.addComponent(entityId, component);
2315
+ return component;
2316
+ }
2317
+ __name(createInstanceSlotComponent, "createInstanceSlotComponent");
2318
+
2293
2319
  // core/components/Video.ts
2294
2320
  var DEFAULT_VIDEO_OPTIONS = {
2295
2321
  autoplay: false,
@@ -3052,13 +3078,32 @@ function createImageTarget({
3052
3078
  }
3053
3079
  __name(createImageTarget, "createImageTarget");
3054
3080
  function isInstancedMeshKind(value) {
3055
- return value === "cube" || value === "sphere" || value === "plane" || value === "cylinder" || value === "capsule";
3081
+ return value === "cube" || value === "sphere" || value === "plane" || value === "cylinder" || value === "capsule" || value === "model";
3056
3082
  }
3057
3083
  __name(isInstancedMeshKind, "isInstancedMeshKind");
3058
- function isInstanceTransformArray(value) {
3059
- return Array.isArray(value);
3084
+ function createInstanceSlotEntity(world, groupEntityId, slotIndex, label, transform) {
3085
+ const instanceEntityId = world.createEntity();
3086
+ world.addComponent(instanceEntityId, new Name(label));
3087
+ world.addComponent(
3088
+ instanceEntityId,
3089
+ createTransform(
3090
+ transform ? {
3091
+ position: transform.position,
3092
+ rotation: transform.rotation,
3093
+ scale: transform.scale
3094
+ } : void 0
3095
+ )
3096
+ );
3097
+ world.addComponent(
3098
+ instanceEntityId,
3099
+ new InstanceSlotComponent(groupEntityId, slotIndex)
3100
+ );
3101
+ world.addComponent(instanceEntityId, new EntityType("instanceSlot"));
3102
+ world.addComponent(instanceEntityId, new Selectable(true));
3103
+ world.addComponent(instanceEntityId, new ParentId(groupEntityId));
3104
+ return instanceEntityId;
3060
3105
  }
3061
- __name(isInstanceTransformArray, "isInstanceTransformArray");
3106
+ __name(createInstanceSlotEntity, "createInstanceSlotEntity");
3062
3107
  function createInstancedMesh({
3063
3108
  world,
3064
3109
  scene,
@@ -3068,25 +3113,68 @@ function createInstancedMesh({
3068
3113
  const opts = payload.options ?? {};
3069
3114
  const meshKind = isInstancedMeshKind(opts.meshKind) ? opts.meshKind : "cube";
3070
3115
  const meshParameters = opts.meshParameters && typeof opts.meshParameters === "object" ? opts.meshParameters : void 0;
3071
- const instances = isInstanceTransformArray(
3072
- opts.instances
3073
- ) ? opts.instances : void 0;
3074
3116
  const castShadow = typeof opts.castShadow === "boolean" ? opts.castShadow : false;
3075
3117
  const receiveShadow = typeof opts.receiveShadow === "boolean" ? opts.receiveShadow : false;
3118
+ const modelPath = typeof opts.modelPath === "string" ? opts.modelPath : void 0;
3076
3119
  const entityId = createBaseEntity(world, anchor, {
3077
3120
  label: payload.name ?? "Instanced Mesh",
3078
3121
  entityType: "instancedMesh",
3079
3122
  transformInput: payload.transform
3080
3123
  });
3124
+ let instanceEntityIds = [];
3125
+ if (Array.isArray(opts.instanceEntityIds)) {
3126
+ instanceEntityIds = [];
3127
+ } else if (Array.isArray(opts.instances) && opts.instances.length > 0) {
3128
+ const legacyInstances = opts.instances;
3129
+ for (let i = 0; i < legacyInstances.length; i++) {
3130
+ const slotId = createInstanceSlotEntity(
3131
+ world,
3132
+ entityId,
3133
+ i,
3134
+ `Instance ${i + 1}`,
3135
+ legacyInstances[i]
3136
+ );
3137
+ instanceEntityIds.push(slotId);
3138
+ }
3139
+ } else {
3140
+ const slotId = createInstanceSlotEntity(
3141
+ world,
3142
+ entityId,
3143
+ 0,
3144
+ "Instance 1",
3145
+ { ...DEFAULT_INSTANCE_TRANSFORM }
3146
+ );
3147
+ instanceEntityIds = [slotId];
3148
+ }
3081
3149
  createInstancedMeshComponent(world, entityId, meshKind, meshParameters, {
3082
3150
  castShadow,
3083
3151
  receiveShadow,
3084
- instances
3152
+ instanceEntityIds,
3153
+ modelPath
3085
3154
  });
3086
3155
  scene.add(anchor);
3087
3156
  return entityId;
3088
3157
  }
3089
3158
  __name(createInstancedMesh, "createInstancedMesh");
3159
+
3160
+ // core/factories/objects/InstanceSlotFactory.ts
3161
+ function createInstanceSlot({ world, payload }) {
3162
+ const opts = payload.options ?? {};
3163
+ const groupEntityId = typeof opts.groupEntityId === "number" ? opts.groupEntityId : -1;
3164
+ const slotIndex = typeof opts.slotIndex === "number" ? opts.slotIndex : 0;
3165
+ const entityId = world.createEntity();
3166
+ world.addComponent(
3167
+ entityId,
3168
+ new Name(payload.name ?? `Instance ${slotIndex + 1}`)
3169
+ );
3170
+ world.addComponent(entityId, createTransform(payload.transform));
3171
+ world.addComponent(entityId, new InstanceSlotComponent(groupEntityId, slotIndex));
3172
+ world.addComponent(entityId, new EntityType("instanceSlot"));
3173
+ world.addComponent(entityId, new Selectable(true));
3174
+ world.addComponent(entityId, new ParentId(groupEntityId !== -1 ? groupEntityId : null));
3175
+ return entityId;
3176
+ }
3177
+ __name(createInstanceSlot, "createInstanceSlot");
3090
3178
  function createAmbientLight({
3091
3179
  world,
3092
3180
  scene,
@@ -3260,6 +3348,7 @@ __export(components_exports, {
3260
3348
  ImageComponent: () => ImageComponent,
3261
3349
  ImageTarget: () => ImageTarget,
3262
3350
  ImageTargetAnchor: () => ImageTargetAnchor,
3351
+ InstanceSlotComponent: () => InstanceSlotComponent,
3263
3352
  InstancedMeshComponent: () => InstancedMeshComponent,
3264
3353
  LightComponent: () => LightComponent,
3265
3354
  MaterialComponent: () => MaterialComponent,
@@ -3657,6 +3746,7 @@ function registerDefaultFactories(objectManagementSystem) {
3657
3746
  objectManagementSystem.register("image", createImage);
3658
3747
  objectManagementSystem.register("imageTarget", createImageTarget);
3659
3748
  objectManagementSystem.register("instancedMesh", createInstancedMesh);
3749
+ objectManagementSystem.register("instanceSlot", createInstanceSlot);
3660
3750
  objectManagementSystem.register("sprite", createSprite);
3661
3751
  objectManagementSystem.register("audio", createAudio);
3662
3752
  objectManagementSystem.register("camera", createCamera);
@@ -5979,14 +6069,14 @@ var _euler = new THREE34__namespace.Euler();
5979
6069
  var _scale = new THREE34__namespace.Vector3();
5980
6070
  var _matrix = new THREE34__namespace.Matrix4();
5981
6071
  var _modelMatrix = new THREE34__namespace.Matrix4();
5982
- function instanceTransformToMatrix4(inst, out) {
5983
- _position.set(inst.position.x, inst.position.y, inst.position.z);
5984
- _euler.set(inst.rotation.x, inst.rotation.y, inst.rotation.z, "XYZ");
6072
+ function instanceTransformFromComponent(transform, out) {
6073
+ _position.set(transform.position.x, transform.position.y, transform.position.z);
6074
+ _euler.set(transform.rotation.x, transform.rotation.y, transform.rotation.z, "XYZ");
5985
6075
  _quaternion.setFromEuler(_euler);
5986
- _scale.set(inst.scale.x, inst.scale.y, inst.scale.z);
6076
+ _scale.set(transform.scale.x, transform.scale.y, transform.scale.z);
5987
6077
  out.compose(_position, _quaternion, _scale);
5988
6078
  }
5989
- __name(instanceTransformToMatrix4, "instanceTransformToMatrix4");
6079
+ __name(instanceTransformFromComponent, "instanceTransformFromComponent");
5990
6080
  function disposePrimitiveInstancedMesh(mesh) {
5991
6081
  mesh.geometry.dispose();
5992
6082
  if (Array.isArray(mesh.material)) {
@@ -6018,8 +6108,9 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6018
6108
  constructor() {
6019
6109
  /** Signature tracking for geometry + instance count changes. */
6020
6110
  this.geometrySignatures = /* @__PURE__ */ new Map();
6021
- /** Entities whose GLTF model is currently loading. Prevents duplicate load triggers. */
6022
- this.loadingEntities = /* @__PURE__ */ new Set();
6111
+ /** Signature being loaded per entity. Maps entityId → geometrySignature in-flight.
6112
+ * Prevents re-dispatching a load every frame while comp.instancedMesh is still null. */
6113
+ this.loadingSignatures = /* @__PURE__ */ new Map();
6023
6114
  /** Per-mesh data for model kind, populated after GLTF load. */
6024
6115
  this.modelMeshEntries = /* @__PURE__ */ new Map();
6025
6116
  }
@@ -6029,8 +6120,8 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6029
6120
  for (const trackedId of this.geometrySignatures.keys()) {
6030
6121
  if (!alive.has(trackedId)) this.geometrySignatures.delete(trackedId);
6031
6122
  }
6032
- for (const trackedId of this.loadingEntities) {
6033
- if (!alive.has(trackedId)) this.loadingEntities.delete(trackedId);
6123
+ for (const trackedId of this.loadingSignatures.keys()) {
6124
+ if (!alive.has(trackedId)) this.loadingSignatures.delete(trackedId);
6034
6125
  }
6035
6126
  for (const trackedId of this.modelMeshEntries.keys()) {
6036
6127
  if (!alive.has(trackedId)) this.modelMeshEntries.delete(trackedId);
@@ -6044,9 +6135,10 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6044
6135
  const objectRef = world.getComponent(entityId, Object3DRef);
6045
6136
  const anchor = objectRef?.object ?? null;
6046
6137
  if (!anchor) continue;
6047
- const instanceCount = comp.instances.length;
6138
+ const instanceCount = comp.instanceEntityIds.length;
6048
6139
  const geometrySignature = comp.meshKind === "model" ? `model:${comp.modelPath}:${instanceCount}` : `${comp.meshKind}:${JSON.stringify(comp.meshParameters)}:${instanceCount}`;
6049
- const needsRebuild = comp.instancedMesh === null || this.geometrySignatures.get(entityId) !== geometrySignature;
6140
+ const pendingLoadSignature = this.loadingSignatures.get(entityId);
6141
+ const needsRebuild = (comp.instancedMesh === null || this.geometrySignatures.get(entityId) !== geometrySignature) && pendingLoadSignature !== geometrySignature;
6050
6142
  if (needsRebuild) {
6051
6143
  if (comp.instancedMesh) {
6052
6144
  anchor.remove(comp.instancedMesh);
@@ -6057,16 +6149,18 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6057
6149
  }
6058
6150
  comp.instancedMesh = null;
6059
6151
  }
6060
- this.loadingEntities.delete(entityId);
6061
- this.modelMeshEntries.delete(entityId);
6152
+ if (pendingLoadSignature !== void 0 && pendingLoadSignature !== geometrySignature) {
6153
+ this.loadingSignatures.delete(entityId);
6154
+ this.modelMeshEntries.delete(entityId);
6155
+ }
6062
6156
  if (comp.meshKind === "model") {
6063
- if (comp.modelPath && !this.loadingEntities.has(entityId)) {
6064
- this.loadingEntities.add(entityId);
6157
+ if (comp.modelPath && !this.loadingSignatures.has(entityId)) {
6158
+ this.loadingSignatures.set(entityId, geometrySignature);
6065
6159
  const targetSignature = geometrySignature;
6066
6160
  const targetEntityId = entityId;
6067
6161
  loadGLTF(comp.modelPath).then((gltf) => {
6068
6162
  if (!world.hasEntity(targetEntityId)) {
6069
- this.loadingEntities.delete(targetEntityId);
6163
+ this.loadingSignatures.delete(targetEntityId);
6070
6164
  return;
6071
6165
  }
6072
6166
  const currentComp = world.getComponent(
@@ -6074,21 +6168,26 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6074
6168
  InstancedMeshComponent
6075
6169
  );
6076
6170
  if (!currentComp) {
6077
- this.loadingEntities.delete(targetEntityId);
6171
+ this.loadingSignatures.delete(targetEntityId);
6078
6172
  return;
6079
6173
  }
6080
- const currentSig = `model:${currentComp.modelPath}:${currentComp.instances.length}`;
6174
+ const currentSig = `model:${currentComp.modelPath}:${currentComp.instanceEntityIds.length}`;
6081
6175
  if (currentSig !== targetSignature) {
6082
- this.loadingEntities.delete(targetEntityId);
6176
+ this.loadingSignatures.delete(targetEntityId);
6083
6177
  return;
6084
6178
  }
6085
6179
  const currentRef = world.getComponent(targetEntityId, Object3DRef);
6086
6180
  const currentAnchor = currentRef?.object ?? null;
6087
6181
  if (!currentAnchor) {
6088
- this.loadingEntities.delete(targetEntityId);
6182
+ this.loadingSignatures.delete(targetEntityId);
6089
6183
  return;
6090
6184
  }
6091
- const count2 = Math.max(1, currentComp.instances.length);
6185
+ if (currentComp.instancedMesh) {
6186
+ currentAnchor.remove(currentComp.instancedMesh);
6187
+ disposeModelGroup(currentComp.instancedMesh);
6188
+ currentComp.instancedMesh = null;
6189
+ }
6190
+ const count2 = Math.max(1, currentComp.instanceEntityIds.length);
6092
6191
  const entries = [];
6093
6192
  gltf.scene.updateWorldMatrix(true, true);
6094
6193
  gltf.scene.traverse((child) => {
@@ -6106,12 +6205,13 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6106
6205
  instancedMesh2.castShadow = currentComp.castShadow;
6107
6206
  instancedMesh2.receiveShadow = currentComp.receiveShadow;
6108
6207
  for (let i = 0; i < count2; i++) {
6109
- const inst = currentComp.instances[i] ?? {
6110
- position: { x: 0, y: 0, z: 0 },
6111
- rotation: { x: 0, y: 0, z: 0 },
6112
- scale: { x: 1, y: 1, z: 1 }
6113
- };
6114
- instanceTransformToMatrix4(inst, _matrix);
6208
+ const instanceEntityId = currentComp.instanceEntityIds[i];
6209
+ const instTransform = instanceEntityId !== void 0 ? world.getComponent(instanceEntityId, TransformComponent) ?? null : null;
6210
+ if (instTransform) {
6211
+ instanceTransformFromComponent(instTransform, _matrix);
6212
+ } else {
6213
+ _matrix.identity();
6214
+ }
6115
6215
  _modelMatrix.multiplyMatrices(_matrix, localMatrix);
6116
6216
  instancedMesh2.setMatrixAt(i, _modelMatrix);
6117
6217
  }
@@ -6119,7 +6219,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6119
6219
  entries.push({ localMatrix, instancedMesh: instancedMesh2 });
6120
6220
  });
6121
6221
  if (entries.length === 0) {
6122
- this.loadingEntities.delete(targetEntityId);
6222
+ this.loadingSignatures.delete(targetEntityId);
6123
6223
  return;
6124
6224
  }
6125
6225
  const group = new THREE34__namespace.Group();
@@ -6130,9 +6230,9 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6130
6230
  currentComp.instancedMesh = group;
6131
6231
  this.modelMeshEntries.set(targetEntityId, entries);
6132
6232
  this.geometrySignatures.set(targetEntityId, targetSignature);
6133
- this.loadingEntities.delete(targetEntityId);
6233
+ this.loadingSignatures.delete(targetEntityId);
6134
6234
  }).catch(() => {
6135
- this.loadingEntities.delete(targetEntityId);
6235
+ this.loadingSignatures.delete(targetEntityId);
6136
6236
  });
6137
6237
  }
6138
6238
  continue;
@@ -6144,12 +6244,13 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6144
6244
  instancedMesh.castShadow = comp.castShadow;
6145
6245
  instancedMesh.receiveShadow = comp.receiveShadow;
6146
6246
  for (let i = 0; i < count; i++) {
6147
- const inst = comp.instances[i] ?? {
6148
- position: { x: 0, y: 0, z: 0 },
6149
- rotation: { x: 0, y: 0, z: 0 },
6150
- scale: { x: 1, y: 1, z: 1 }
6151
- };
6152
- instanceTransformToMatrix4(inst, _matrix);
6247
+ const instanceEntityId = comp.instanceEntityIds[i];
6248
+ const instTransform = instanceEntityId !== void 0 ? world.getComponent(instanceEntityId, TransformComponent) ?? null : null;
6249
+ if (instTransform) {
6250
+ instanceTransformFromComponent(instTransform, _matrix);
6251
+ } else {
6252
+ _matrix.identity();
6253
+ }
6153
6254
  instancedMesh.setMatrixAt(i, _matrix);
6154
6255
  }
6155
6256
  instancedMesh.instanceMatrix.needsUpdate = true;
@@ -6160,10 +6261,16 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6160
6261
  if (comp.meshKind === "model") {
6161
6262
  const entries = this.modelMeshEntries.get(entityId);
6162
6263
  if (entries) {
6163
- const count = comp.instances.length;
6264
+ const count = comp.instanceEntityIds.length;
6164
6265
  for (const entry of entries) {
6165
6266
  for (let i = 0; i < count; i++) {
6166
- instanceTransformToMatrix4(comp.instances[i], _matrix);
6267
+ const instanceEntityId = comp.instanceEntityIds[i];
6268
+ const instTransform = instanceEntityId !== void 0 ? world.getComponent(instanceEntityId, TransformComponent) ?? null : null;
6269
+ if (instTransform) {
6270
+ instanceTransformFromComponent(instTransform, _matrix);
6271
+ } else {
6272
+ _matrix.identity();
6273
+ }
6167
6274
  _modelMatrix.multiplyMatrices(_matrix, entry.localMatrix);
6168
6275
  entry.instancedMesh.setMatrixAt(i, _modelMatrix);
6169
6276
  }
@@ -6174,9 +6281,15 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
6174
6281
  }
6175
6282
  } else {
6176
6283
  const im = comp.instancedMesh;
6177
- const count = comp.instances.length;
6284
+ const count = comp.instanceEntityIds.length;
6178
6285
  for (let i = 0; i < count; i++) {
6179
- instanceTransformToMatrix4(comp.instances[i], _matrix);
6286
+ const instanceEntityId = comp.instanceEntityIds[i];
6287
+ const instTransform = instanceEntityId !== void 0 ? world.getComponent(instanceEntityId, TransformComponent) ?? null : null;
6288
+ if (instTransform) {
6289
+ instanceTransformFromComponent(instTransform, _matrix);
6290
+ } else {
6291
+ _matrix.identity();
6292
+ }
6180
6293
  im.setMatrixAt(i, _matrix);
6181
6294
  }
6182
6295
  im.instanceMatrix.needsUpdate = true;
@@ -8138,7 +8251,8 @@ function buildComponentValueMaps(snapshot) {
8138
8251
  animationValues: readByComponent(snapshot.components, "AnimationComponent"),
8139
8252
  imageTargetAnchorValues: readByComponent(snapshot.components, "ImageTargetAnchor"),
8140
8253
  scriptValues: readByComponent(snapshot.components, "ScriptComponent"),
8141
- instancedMeshValues: readByComponent(snapshot.components, "InstancedMeshComponent")
8254
+ instancedMeshValues: readByComponent(snapshot.components, "InstancedMeshComponent"),
8255
+ instanceSlotValues: readByComponent(snapshot.components, "InstanceSlotComponent")
8142
8256
  };
8143
8257
  }
8144
8258
  __name(buildComponentValueMaps, "buildComponentValueMaps");
@@ -8252,6 +8366,20 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
8252
8366
  new ScriptComponent(entries)
8253
8367
  );
8254
8368
  }
8369
+ {
8370
+ const imComponent = world.getComponent(targetEntityId, InstancedMeshComponent);
8371
+ if (imComponent && imComponent.instanceEntityIds.length > 0) {
8372
+ imComponent.instanceEntityIds = imComponent.instanceEntityIds.map(
8373
+ (oldId) => idMap.get(oldId) ?? oldId
8374
+ );
8375
+ }
8376
+ }
8377
+ {
8378
+ const slotComponent = world.getComponent(targetEntityId, InstanceSlotComponent);
8379
+ if (slotComponent && slotComponent.groupEntityId !== -1) {
8380
+ slotComponent.groupEntityId = idMap.get(slotComponent.groupEntityId) ?? slotComponent.groupEntityId;
8381
+ }
8382
+ }
8255
8383
  }
8256
8384
  __name(restorePostCreateComponents, "restorePostCreateComponents");
8257
8385
 
@@ -8755,12 +8883,21 @@ function restoreComponentState(world, objectManagementSystem, targetEntityId, so
8755
8883
  if (typeof sourceInstancedMesh.receiveShadow === "boolean") {
8756
8884
  imComponent.receiveShadow = sourceInstancedMesh.receiveShadow;
8757
8885
  }
8758
- if (Array.isArray(sourceInstancedMesh.instances)) {
8759
- imComponent.instances = sourceInstancedMesh.instances;
8886
+ if (Array.isArray(sourceInstancedMesh.instanceEntityIds)) {
8887
+ imComponent.instanceEntityIds = sourceInstancedMesh.instanceEntityIds;
8760
8888
  }
8761
8889
  imComponent.instancedMesh = null;
8762
8890
  }
8763
8891
  }
8892
+ const sourceInstanceSlot = asRecord3(values.instanceSlotValues.get(sourceEntityId));
8893
+ if (sourceInstanceSlot) {
8894
+ const slotComponent = world.getComponent(targetEntityId, InstanceSlotComponent);
8895
+ if (slotComponent) {
8896
+ if (typeof sourceInstanceSlot.slotIndex === "number") {
8897
+ slotComponent.slotIndex = sourceInstanceSlot.slotIndex;
8898
+ }
8899
+ }
8900
+ }
8764
8901
  }
8765
8902
  __name(restoreComponentState, "restoreComponentState");
8766
8903
 
@@ -8784,7 +8921,8 @@ var HYDRATABLE_ENTITY_KINDS = /* @__PURE__ */ new Set([
8784
8921
  "pointLight",
8785
8922
  "spotLight",
8786
8923
  "areaLight",
8787
- "instancedMesh"
8924
+ "instancedMesh",
8925
+ "instanceSlot"
8788
8926
  ]);
8789
8927
 
8790
8928
  // core/hydration/hydrateWorld.ts
@@ -8866,10 +9004,23 @@ function buildEntityCreationPayload(sourceEntityId, kind, componentValues) {
8866
9004
  if (im) {
8867
9005
  payload.options = {
8868
9006
  meshKind: typeof im.meshKind === "string" ? im.meshKind : "cube",
9007
+ modelPath: typeof im.modelPath === "string" ? im.modelPath : void 0,
8869
9008
  meshParameters: asRecord3(im.meshParameters) ?? void 0,
8870
9009
  castShadow: typeof im.castShadow === "boolean" ? im.castShadow : false,
8871
9010
  receiveShadow: typeof im.receiveShadow === "boolean" ? im.receiveShadow : false,
8872
- instances: Array.isArray(im.instances) ? im.instances : void 0
9011
+ // New format: signal the factory to skip child entity creation.
9012
+ // Old format (instances[]): pass through for migration — factory will
9013
+ // create slot entities from the legacy InstanceTransform array.
9014
+ ...Array.isArray(im.instanceEntityIds) ? { instanceEntityIds: im.instanceEntityIds } : Array.isArray(im.instances) ? { instances: im.instances } : {}
9015
+ };
9016
+ }
9017
+ }
9018
+ if (kind === "instanceSlot") {
9019
+ const slot = asRecord3(componentValues.instanceSlotValues.get(sourceEntityId));
9020
+ if (slot) {
9021
+ payload.options = {
9022
+ groupEntityId: typeof slot.groupEntityId === "number" ? slot.groupEntityId : -1,
9023
+ slotIndex: typeof slot.slotIndex === "number" ? slot.slotIndex : 0
8873
9024
  };
8874
9025
  }
8875
9026
  }
@@ -9017,6 +9168,7 @@ exports.createEnvironmentComponent = createEnvironmentComponent;
9017
9168
  exports.createImageComponent = createImageComponent;
9018
9169
  exports.createImageTargetAnchorComponent = createImageTargetAnchorComponent;
9019
9170
  exports.createImageTargetComponent = createImageTargetComponent;
9171
+ exports.createInstanceSlotComponent = createInstanceSlotComponent;
9020
9172
  exports.createInstancedMeshComponent = createInstancedMeshComponent;
9021
9173
  exports.createLightComponent = createLightComponent;
9022
9174
  exports.createMaterialComponent = createMaterialComponent;