mage-engine 3.23.36 → 3.23.38

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 (2) hide show
  1. package/dist/mage.js +283 -90
  2. package/package.json +1 -1
package/dist/mage.js CHANGED
@@ -56083,6 +56083,11 @@ const extractBoundingSphere = body => {
56083
56083
  return body.geometry.boundingSphere;
56084
56084
  };
56085
56085
  const extractBiggestBoundingSphere = body => {
56086
+ if (!body || typeof body.traverse !== 'function') {
56087
+ console.warn('[Mage] extractBiggestBoundingSphere received invalid body');
56088
+ return null;
56089
+ }
56090
+
56086
56091
  const spheres = [];
56087
56092
  body.traverse(child => {
56088
56093
  if (child.geometry) {
@@ -58130,7 +58135,7 @@ function applyMiddleware() {
58130
58135
 
58131
58136
  var thunk = createThunkMiddleware();
58132
58137
  thunk.withExtraArgument = createThunkMiddleware;var name = "mage-engine";
58133
- var version$1 = "3.23.36";
58138
+ var version$1 = "3.23.38";
58134
58139
  var description = "A WebGL Javascript Game Engine, built on top of THREE.js and many other libraries.";
58135
58140
  var main = "dist/mage.js";
58136
58141
  var author$1 = {
@@ -60610,6 +60615,11 @@ const disposeGeometry = mesh => {
60610
60615
  }
60611
60616
  };
60612
60617
  const prepareModel = model => {
60618
+ if (!model || typeof model.traverse !== 'function') {
60619
+ console.warn('[Mage] prepareModel received invalid model object:', model);
60620
+ return null; // Return null for invalid models
60621
+ }
60622
+
60613
60623
  setUpLightsAndShadows(model);
60614
60624
  model.traverse(mesh => {
60615
60625
  setUpLightsAndShadows(mesh);
@@ -60766,8 +60776,13 @@ const tweenTo = function (origin, target) {
60766
60776
  z,
60767
60777
  w
60768
60778
  } = _ref;
60779
+ // Ensure values are numbers (not strings) to prevent rendering issues
60780
+ const qx = Number(x) || 0;
60781
+ const qy = Number(y) || 0;
60782
+ const qz = Number(z) || 0;
60783
+ const qw = Number(w) || 1;
60769
60784
 
60770
- _this.getBody().quaternion.set(x, y, z, w);
60785
+ _this.getBody().quaternion.set(qx, qy, qz, qw);
60771
60786
  });
60772
60787
 
60773
60788
  _defineProperty$1(_assertThisInitialized(_this), "setUuid", uuid => {
@@ -61308,8 +61323,12 @@ const tweenTo = function (origin, target) {
61308
61323
  if (this.hasBody()) {
61309
61324
  const scale = { ...this.getScale(),
61310
61325
  ...howbig
61311
- };
61312
- this.body.scale.set(scale.x, scale.y, scale.z);
61326
+ }; // Ensure values are numbers (not strings) to prevent rendering issues
61327
+
61328
+ const sx = Number(scale.x) || 1;
61329
+ const sy = Number(scale.y) || 1;
61330
+ const sz = Number(scale.z) || 1;
61331
+ this.body.scale.set(sx, sy, sz);
61313
61332
  }
61314
61333
  }
61315
61334
  }, {
@@ -61338,8 +61357,12 @@ const tweenTo = function (origin, target) {
61338
61357
  y,
61339
61358
  z,
61340
61359
  ...where
61341
- };
61342
- this.getBody().position.set(position.x, position.y, position.z);
61360
+ }; // Ensure values are numbers (not strings) to prevent rendering issues
61361
+
61362
+ const px = Number(position.x) || 0;
61363
+ const py = Number(position.y) || 0;
61364
+ const pz = Number(position.z) || 0;
61365
+ this.getBody().position.set(px, py, pz);
61343
61366
  }
61344
61367
  }
61345
61368
  }, {
@@ -61361,8 +61384,12 @@ const tweenTo = function (origin, target) {
61361
61384
  y,
61362
61385
  z,
61363
61386
  ...how
61364
- };
61365
- this.getBody().rotation.set(rotation.x, rotation.y, rotation.z);
61387
+ }; // Ensure values are numbers (not strings) to prevent rendering issues
61388
+
61389
+ const rx = Number(rotation.x) || 0;
61390
+ const ry = Number(rotation.y) || 0;
61391
+ const rz = Number(rotation.z) || 0;
61392
+ this.getBody().rotation.set(rx, ry, rz);
61366
61393
  }
61367
61394
  }
61368
61395
  }, {
@@ -62273,8 +62300,13 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62273
62300
  }, {
62274
62301
  key: "setAngularVelocity",
62275
62302
  value: function setAngularVelocity(velocity) {
62276
- this.angularVelocity = velocity;
62277
- Physics$1.updateAngularVelocity(this.uuid(), velocity);
62303
+ const numericVelocity = {
62304
+ x: Number(velocity === null || velocity === void 0 ? void 0 : velocity.x) || 0,
62305
+ y: Number(velocity === null || velocity === void 0 ? void 0 : velocity.y) || 0,
62306
+ z: Number(velocity === null || velocity === void 0 ? void 0 : velocity.z) || 0
62307
+ };
62308
+ this.angularVelocity = numericVelocity;
62309
+ Physics$1.updateAngularVelocity(this.uuid(), numericVelocity);
62278
62310
  }
62279
62311
  }, {
62280
62312
  key: "getLinearVelocity",
@@ -62284,8 +62316,13 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62284
62316
  }, {
62285
62317
  key: "setLinearVelocity",
62286
62318
  value: function setLinearVelocity(velocity) {
62287
- this.linearVelocity = velocity;
62288
- Physics$1.updateLinearVelocity(this.uuid(), velocity);
62319
+ const numericVelocity = {
62320
+ x: Number(velocity === null || velocity === void 0 ? void 0 : velocity.x) || 0,
62321
+ y: Number(velocity === null || velocity === void 0 ? void 0 : velocity.y) || 0,
62322
+ z: Number(velocity === null || velocity === void 0 ? void 0 : velocity.z) || 0
62323
+ };
62324
+ this.linearVelocity = numericVelocity;
62325
+ Physics$1.updateLinearVelocity(this.uuid(), numericVelocity);
62289
62326
  }
62290
62327
  }, {
62291
62328
  key: "isCollidingOnDirection",
@@ -62306,11 +62343,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62306
62343
  key: "setGeometryRotation",
62307
62344
  value: function setGeometryRotation() {
62308
62345
  let rotation = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
62309
- const {
62310
- x = 0,
62311
- y = 0,
62312
- z = 0
62313
- } = rotation;
62346
+ const x = Number(rotation === null || rotation === void 0 ? void 0 : rotation.x) || 0;
62347
+ const y = Number(rotation === null || rotation === void 0 ? void 0 : rotation.y) || 0;
62348
+ const z = Number(rotation === null || rotation === void 0 ? void 0 : rotation.z) || 0;
62314
62349
 
62315
62350
  if (x !== 0) {
62316
62351
  this.getBody().geometry.rotateX(x);
@@ -62366,8 +62401,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62366
62401
  key: "setReflectivity",
62367
62402
  value: function setReflectivity() {
62368
62403
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.REFLECTIVITY];
62404
+ const numericValue = Number(value) || 0;
62369
62405
 
62370
- const _setReflectivity = material => material[PROPERTIES.REFLECTIVITY] = value;
62406
+ const _setReflectivity = material => material[PROPERTIES.REFLECTIVITY] = numericValue;
62371
62407
 
62372
62408
  if (value != undefined) {
62373
62409
  applyMaterialChange(this.getBody(), _setReflectivity);
@@ -62384,8 +62420,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62384
62420
  key: "setRefractionRatio",
62385
62421
  value: function setRefractionRatio() {
62386
62422
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.REFRACTION_RATIO];
62423
+ const numericValue = Number(value) || 0;
62387
62424
 
62388
- const _setRefractionRatio = material => material[PROPERTIES.REFRACTION_RATIO] = value;
62425
+ const _setRefractionRatio = material => material[PROPERTIES.REFRACTION_RATIO] = numericValue;
62389
62426
 
62390
62427
  if (value != undefined) {
62391
62428
  applyMaterialChange(this.getBody(), _setRefractionRatio);
@@ -62458,8 +62495,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62458
62495
  key: "setShininess",
62459
62496
  value: function setShininess() {
62460
62497
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.SHININESS];
62498
+ const numericValue = Number(value) || 0;
62461
62499
 
62462
- const _setShininess = material => material[PROPERTIES.SHININESS] = value;
62500
+ const _setShininess = material => material[PROPERTIES.SHININESS] = numericValue;
62463
62501
 
62464
62502
  applyMaterialChange(this.getBody(), _setShininess);
62465
62503
  }
@@ -62510,8 +62548,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62510
62548
  key: "setMetalness",
62511
62549
  value: function setMetalness() {
62512
62550
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.METALNESS];
62551
+ const numericValue = Number(value) || 0;
62513
62552
 
62514
- const _setMetalness = material => material[PROPERTIES.METALNESS] = value;
62553
+ const _setMetalness = material => material[PROPERTIES.METALNESS] = numericValue;
62515
62554
 
62516
62555
  applyMaterialChange(this.getBody(), _setMetalness);
62517
62556
  }
@@ -62524,8 +62563,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62524
62563
  key: "setRoughness",
62525
62564
  value: function setRoughness() {
62526
62565
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.ROUGHNESS];
62566
+ const numericValue = Number(value) || 0;
62527
62567
 
62528
- const _setRoughness = material => material[PROPERTIES.ROUGHNESS] = value;
62568
+ const _setRoughness = material => material[PROPERTIES.ROUGHNESS] = numericValue;
62529
62569
 
62530
62570
  applyMaterialChange(this.getBody(), _setRoughness);
62531
62571
  }
@@ -62562,8 +62602,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62562
62602
  key: "setEmissiveIntensity",
62563
62603
  value: function setEmissiveIntensity() {
62564
62604
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.EMISSIVE_INTENSITY];
62605
+ const numericValue = Number(value) || 0;
62565
62606
 
62566
- const _setEmissiveIntensity = material => material[PROPERTIES.EMISSIVE_INTENSITY] = value;
62607
+ const _setEmissiveIntensity = material => material[PROPERTIES.EMISSIVE_INTENSITY] = numericValue;
62567
62608
 
62568
62609
  applyMaterialChange(this.getBody(), _setEmissiveIntensity);
62569
62610
  }
@@ -62576,8 +62617,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62576
62617
  key: "setLightMapIntensity",
62577
62618
  value: function setLightMapIntensity() {
62578
62619
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.LIGHT_MAP_INTENSITY];
62620
+ const numericValue = Number(value) || 0;
62579
62621
 
62580
- const _setLightMapIntensity = material => material[PROPERTIES.LIGHT_MAP_INTENSITY] = value;
62622
+ const _setLightMapIntensity = material => material[PROPERTIES.LIGHT_MAP_INTENSITY] = numericValue;
62581
62623
 
62582
62624
  applyMaterialChange(this.getBody(), _setLightMapIntensity);
62583
62625
  }
@@ -62590,8 +62632,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62590
62632
  key: "setAOMapIntensity",
62591
62633
  value: function setAOMapIntensity() {
62592
62634
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.AO_MAP_INTENSITY];
62635
+ const numericValue = Number(value) || 0;
62593
62636
 
62594
- const _setAOMapIntensity = material => material[PROPERTIES.AO_MAP_INTENSITY] = value;
62637
+ const _setAOMapIntensity = material => material[PROPERTIES.AO_MAP_INTENSITY] = numericValue;
62595
62638
 
62596
62639
  applyMaterialChange(this.getBody(), _setAOMapIntensity);
62597
62640
  }
@@ -62604,8 +62647,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62604
62647
  key: "setAoMapIntensity",
62605
62648
  value: function setAoMapIntensity() {
62606
62649
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.AO_MAP_INTENSITY];
62650
+ const numericValue = Number(value) || 0;
62607
62651
 
62608
- const _setAoMapIntensity = material => material[PROPERTIES.AO_MAP_INTENSITY] = value;
62652
+ const _setAoMapIntensity = material => material[PROPERTIES.AO_MAP_INTENSITY] = numericValue;
62609
62653
 
62610
62654
  applyMaterialChange(this.getBody(), _setAoMapIntensity);
62611
62655
  }
@@ -62613,8 +62657,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62613
62657
  key: "setEnvMapIntensity",
62614
62658
  value: function setEnvMapIntensity() {
62615
62659
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.ENV_MAP_INTENSITY];
62660
+ const numericValue = Number(value) || 0;
62616
62661
 
62617
- const _setEnvMapIntensity = material => material[PROPERTIES.ENV_MAP_INTENSITY] = value;
62662
+ const _setEnvMapIntensity = material => material[PROPERTIES.ENV_MAP_INTENSITY] = numericValue;
62618
62663
 
62619
62664
  applyMaterialChange(this.getBody(), _setEnvMapIntensity);
62620
62665
  }
@@ -62627,8 +62672,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62627
62672
  key: "setDisplacementScale",
62628
62673
  value: function setDisplacementScale() {
62629
62674
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.DISPLACEMENT_SCALE];
62675
+ const numericValue = Number(value) || 0;
62630
62676
 
62631
- const _setDisplacementScale = material => material[PROPERTIES.DISPLACEMENT_SCALE] = value;
62677
+ const _setDisplacementScale = material => material[PROPERTIES.DISPLACEMENT_SCALE] = numericValue;
62632
62678
 
62633
62679
  applyMaterialChange(this.getBody(), _setDisplacementScale);
62634
62680
  }
@@ -62641,8 +62687,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62641
62687
  key: "setDisplacementBias",
62642
62688
  value: function setDisplacementBias() {
62643
62689
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.DISPLACEMENT_BIAS];
62690
+ const numericValue = Number(value) || 0;
62644
62691
 
62645
- const _setDisplacementBias = material => material[PROPERTIES.DISPLACEMENT_BIAS] = value;
62692
+ const _setDisplacementBias = material => material[PROPERTIES.DISPLACEMENT_BIAS] = numericValue;
62646
62693
 
62647
62694
  applyMaterialChange(this.getBody(), _setDisplacementBias);
62648
62695
  }
@@ -62655,8 +62702,9 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62655
62702
  key: "setBumpScale",
62656
62703
  value: function setBumpScale() {
62657
62704
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MATERIAL_PROPERTIES_DEFAULT_VALUES[PROPERTIES.BUMP_SCALE];
62705
+ const numericValue = Number(value) || 0;
62658
62706
 
62659
- const _setBumpScale = material => material[PROPERTIES.BUMP_SCALE] = value;
62707
+ const _setBumpScale = material => material[PROPERTIES.BUMP_SCALE] = numericValue;
62660
62708
 
62661
62709
  applyMaterialChange(this.getBody(), _setBumpScale);
62662
62710
  }
@@ -62725,7 +62773,13 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62725
62773
 
62726
62774
  texture.wrapS = textureOptions.wrap;
62727
62775
  texture.wrapT = textureOptions.wrap;
62728
- texture.repeat.set(textureOptions.repeat.x, textureOptions.repeat.y);
62776
+ texture.repeat.set(textureOptions.repeat.x, textureOptions.repeat.y); // Set sRGB encoding for color textures (map, emissiveMap, specularMap)
62777
+ // This is required for textures to display with correct colors
62778
+
62779
+ if (textureType === TEXTURES.MAP || textureType === TEXTURES.EMISSIVE || textureType === TEXTURES.SPECULAR) {
62780
+ texture.encoding = sRGBEncoding;
62781
+ }
62782
+
62729
62783
  material[textureType] = texture;
62730
62784
  material.needsUpdate = true;
62731
62785
  };
@@ -62857,9 +62911,10 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
62857
62911
  key: "setWireframeLineWidth",
62858
62912
  value: function setWireframeLineWidth() {
62859
62913
  let width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
62914
+ const numericWidth = Number(width) || 1;
62860
62915
 
62861
62916
  const _setWireframeLineWidth = material => {
62862
- material.wireframeLinewidth = width;
62917
+ material.wireframeLinewidth = numericWidth;
62863
62918
  };
62864
62919
 
62865
62920
  applyMaterialChange(this.getBody(), _setWireframeLineWidth);
@@ -63489,7 +63544,8 @@ let Line = /*#__PURE__*/function (_Element) {
63489
63544
  key: "setThickness",
63490
63545
  value: function setThickness() {
63491
63546
  let thickness = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_LINE_THICKNESS;
63492
- this.body.material.linewidth = thickness;
63547
+ const numericThickness = Number(thickness) || DEFAULT_LINE_THICKNESS;
63548
+ this.body.material.linewidth = numericThickness;
63493
63549
  }
63494
63550
  }, {
63495
63551
  key: "toJSON",
@@ -63800,29 +63856,33 @@ let Sprite = /*#__PURE__*/function (_Element) {
63800
63856
  key: "setRotation",
63801
63857
  value: function setRotation() {
63802
63858
  let rotation = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getRotation();
63803
- this.setData("rotation", rotation);
63804
- this.getBody().material.rotation = rotation;
63859
+ const numericRotation = Number(rotation) || 0;
63860
+ this.setData("rotation", numericRotation);
63861
+ this.getBody().material.rotation = numericRotation;
63805
63862
  }
63806
63863
  }, {
63807
63864
  key: "setWidth",
63808
63865
  value: function setWidth() {
63809
63866
  let width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.width;
63810
- this.setData("width", width);
63811
- this.getBody().scale.x = width;
63867
+ const numericWidth = Number(width) || 1;
63868
+ this.setData("width", numericWidth);
63869
+ this.getBody().scale.x = numericWidth;
63812
63870
  }
63813
63871
  }, {
63814
63872
  key: "setHeight",
63815
63873
  value: function setHeight() {
63816
63874
  let height = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.height;
63817
- this.setData("height", height);
63818
- this.getBody().scale.y = height;
63875
+ const numericHeight = Number(height) || 1;
63876
+ this.setData("height", numericHeight);
63877
+ this.getBody().scale.y = numericHeight;
63819
63878
  }
63820
63879
  }, {
63821
63880
  key: "setAnisotropy",
63822
63881
  value: function setAnisotropy() {
63823
63882
  let anisotropy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
63824
- this.setData("anisotropy", anisotropy);
63825
- this.getTexture(TEXTURES.MAP).anisotropy = validateAnisotropy(anisotropy);
63883
+ const numericAnisotropy = Number(anisotropy) || 1;
63884
+ this.setData("anisotropy", numericAnisotropy);
63885
+ this.getTexture(TEXTURES.MAP).anisotropy = validateAnisotropy(numericAnisotropy);
63826
63886
  }
63827
63887
  }, {
63828
63888
  key: "setSizeAttenuation",
@@ -76132,7 +76192,11 @@ const buildFBXLoader = () => {
76132
76192
  const textureLoader = new TextureLoader(this.manager).setCrossOrigin(this.crossOrigin);
76133
76193
 
76134
76194
  if (!isAbsoluteURL$1(texture)) {
76135
- textureLoader.setPath(this.resourcePath || texturePath || path);
76195
+ // Use MAGE_ASSETS_BASE_URL + textures/ as fallback when no texture path is specified
76196
+ // This allows FBX models to find textures in the textures directory of deployed builds
76197
+ const baseUrl = env.MAGE_ASSETS_BASE_URL;
76198
+ const defaultTexturePath = baseUrl ? `${baseUrl}/textures/` : null;
76199
+ textureLoader.setPath(this.resourcePath || texturePath || defaultTexturePath || path);
76136
76200
  }
76137
76201
 
76138
76202
  return new FBXTreeParser(textureLoader, this.manager, this.options).parse(fbxTree);
@@ -80631,10 +80695,16 @@ function parallelTraverse(a, b, callback) {
80631
80695
  };
80632
80696
  const FULL_STOP = ".";
80633
80697
 
80634
- const DEFAULTbuildObjectLoader = () => ({
80635
- tracer: new RequirementsTracer(),
80636
- loader: new ObjectLoader()
80637
- });
80698
+ const DEFAULTbuildObjectLoader = () => {
80699
+ const loader = new ObjectLoader(); // Add setOptions for compatibility with the loader interface
80700
+
80701
+ loader.setOptions = () => {};
80702
+
80703
+ return {
80704
+ tracer: new RequirementsTracer(),
80705
+ loader
80706
+ };
80707
+ };
80638
80708
 
80639
80709
  const loaders = {
80640
80710
  [EXTENSIONS.JSON]: DEFAULTbuildObjectLoader,
@@ -80733,11 +80803,22 @@ const getLoaderFromExtension = (extension, options) => {
80733
80803
  };
80734
80804
  };
80735
80805
 
80736
- const glbParser = _ref => {
80737
- let {
80806
+ const glbParser = gltf => {
80807
+ // GLTF/GLB loader returns { scene, animations, ... }
80808
+ if (!gltf || !gltf.scene) {
80809
+ var _gltf$constructor;
80810
+
80811
+ console.error('[Mage] GLB parser received invalid GLTF object:', {
80812
+ type: gltf === null || gltf === void 0 ? void 0 : (_gltf$constructor = gltf.constructor) === null || _gltf$constructor === void 0 ? void 0 : _gltf$constructor.name,
80813
+ keys: gltf ? Object.keys(gltf) : []
80814
+ });
80815
+ return null;
80816
+ }
80817
+
80818
+ const {
80738
80819
  scene,
80739
80820
  animations
80740
- } = _ref;
80821
+ } = gltf;
80741
80822
  scene.traverse(object => {
80742
80823
  if (object.isMesh) {
80743
80824
  object.castShadow = true;
@@ -80749,28 +80830,60 @@ const glbParser = _ref => {
80749
80830
  };
80750
80831
  };
80751
80832
 
80752
- const gltfParser = _ref2 => {
80753
- let {
80754
- scene,
80755
- animations
80756
- } = _ref2;
80833
+ const gltfParser = gltf => {
80834
+ // GLTF loader returns { scene, animations, ... }
80835
+ if (!gltf || !gltf.scene) {
80836
+ var _gltf$constructor2;
80837
+
80838
+ console.error('[Mage] GLTF parser received invalid GLTF object:', {
80839
+ type: gltf === null || gltf === void 0 ? void 0 : (_gltf$constructor2 = gltf.constructor) === null || _gltf$constructor2 === void 0 ? void 0 : _gltf$constructor2.name,
80840
+ keys: gltf ? Object.keys(gltf) : []
80841
+ });
80842
+ return null;
80843
+ }
80844
+
80757
80845
  return {
80758
- scene,
80759
- animations
80846
+ scene: gltf.scene,
80847
+ animations: gltf.animations
80760
80848
  };
80761
80849
  };
80762
80850
 
80763
- const defaultParser = scene => ({
80764
- scene
80765
- });
80851
+ const defaultParser = scene => {
80852
+ // Validate the scene is a proper THREE.js object
80853
+ if (!scene || typeof scene.traverse !== 'function') {
80854
+ var _scene$constructor;
80766
80855
 
80767
- const colladaParser = _ref3 => {
80768
- let {
80856
+ console.error('[Mage] Default parser received invalid scene object:', {
80857
+ type: scene === null || scene === void 0 ? void 0 : (_scene$constructor = scene.constructor) === null || _scene$constructor === void 0 ? void 0 : _scene$constructor.name,
80858
+ isObject3D: scene === null || scene === void 0 ? void 0 : scene.isObject3D,
80859
+ keys: scene ? Object.keys(scene) : []
80860
+ });
80861
+ return null;
80862
+ }
80863
+
80864
+ return {
80865
+ scene
80866
+ };
80867
+ };
80868
+
80869
+ const colladaParser = collada => {
80870
+ // Collada loader returns { animations, scene, ... }
80871
+ if (!collada || !collada.scene) {
80872
+ var _collada$constructor;
80873
+
80874
+ console.error('[Mage] Collada parser received invalid object:', {
80875
+ type: collada === null || collada === void 0 ? void 0 : (_collada$constructor = collada.constructor) === null || _collada$constructor === void 0 ? void 0 : _collada$constructor.name,
80876
+ keys: collada ? Object.keys(collada) : []
80877
+ });
80878
+ return null;
80879
+ }
80880
+
80881
+ const {
80769
80882
  animations,
80770
80883
  scene,
80771
80884
  rawSceneData,
80772
80885
  buildVisualScene
80773
- } = _ref3;
80886
+ } = collada;
80774
80887
  scene.traverse(node => {
80775
80888
  if (node.isSkinnedMesh) {
80776
80889
  node.frustumCulled = false;
@@ -80785,6 +80898,18 @@ const colladaParser = _ref3 => {
80785
80898
  };
80786
80899
 
80787
80900
  const fbxParser = scene => {
80901
+ // Validate the FBX loader returned a proper THREE.js object
80902
+ if (!scene || typeof scene.traverse !== 'function') {
80903
+ var _scene$constructor2;
80904
+
80905
+ console.error('[Mage] FBX parser received invalid scene object:', {
80906
+ type: scene === null || scene === void 0 ? void 0 : (_scene$constructor2 = scene.constructor) === null || _scene$constructor2 === void 0 ? void 0 : _scene$constructor2.name,
80907
+ isObject3D: scene === null || scene === void 0 ? void 0 : scene.isObject3D,
80908
+ keys: scene ? Object.keys(scene) : []
80909
+ });
80910
+ return null;
80911
+ }
80912
+
80788
80913
  scene.traverse(node => {
80789
80914
  if (node.isSkinnedMesh) {
80790
80915
  processMaterial(node.material, material => material.skinning = true);
@@ -80846,40 +80971,64 @@ let Models = /*#__PURE__*/function (_EventDispatcher) {
80846
80971
  _defineProperty$1(_assertThisInitialized(_this), "create", function (name) {
80847
80972
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
80848
80973
  const builtAssetId = buildAssetId(name, _this.currentLevel);
80974
+ const modelData = _this.map[name] || _this.map[builtAssetId];
80975
+
80976
+ if (!modelData) {
80977
+ console.warn(`[Mage] Model "${name}" not found in map. Available: ${Object.keys(_this.map).join(', ')}`);
80978
+ return false;
80979
+ }
80980
+
80849
80981
  const {
80850
80982
  scene,
80851
80983
  animations,
80852
80984
  extension
80853
- } = _this.map[name] || _this.map[builtAssetId] || {};
80985
+ } = modelData; // Validate that scene is a valid THREE.js object with required methods
80854
80986
 
80855
- if (scene) {
80856
- const elementOptions = {
80857
- name,
80858
- builtAssetId,
80859
- ...options
80860
- };
80861
- let model = scene.clone();
80987
+ if (!scene || typeof scene.clone !== 'function' || typeof scene.traverse !== 'function') {
80988
+ console.warn(`[Mage] Model "${name}" has invalid scene object. Got:`, Object.keys(modelData));
80989
+ return false;
80990
+ }
80862
80991
 
80863
- if (extension !== EXTENSIONS.COLLADA && hasAnimations(animations)) {
80864
- // we have no idea how to clone collada for the time being
80992
+ const elementOptions = {
80993
+ name,
80994
+ builtAssetId,
80995
+ ...options
80996
+ };
80997
+ let model;
80998
+ const useSkeletonClone = extension !== EXTENSIONS.COLLADA && hasAnimations(animations);
80999
+
81000
+ try {
81001
+ if (useSkeletonClone) {
80865
81002
  model = SkeletonUtils.clone(scene);
81003
+ } else {
81004
+ model = scene.clone();
80866
81005
  }
81006
+ } catch (cloneError) {
81007
+ console.error(`[Mage] Error cloning model "${name}":`, cloneError);
81008
+ return false;
81009
+ } // Validate the cloned model
80867
81010
 
80868
- const element = new Element$1({
80869
- body: prepareModel(model),
80870
- ...elementOptions
80871
- });
80872
- element.setEntityType(ENTITY_TYPES.MODEL.TYPE);
80873
- element.setEntitySubtype(ENTITY_TYPES.MODEL.SUBTYPES.DEFAULT);
80874
81011
 
80875
- if (hasAnimations(animations)) {
80876
- element.addAnimationHandler(animations);
80877
- }
81012
+ const preparedBody = prepareModel(model);
81013
+
81014
+ if (!preparedBody) {
81015
+ console.warn(`[Mage] Model "${name}" failed to prepare after cloning`);
81016
+ return false;
81017
+ } // IMPORTANT: body must come AFTER elementOptions spread to ensure
81018
+ // our preparedBody is used, not any 'body' property from saved options
81019
+
81020
+
81021
+ const element = new Element$1({ ...elementOptions,
81022
+ body: preparedBody
81023
+ });
81024
+ element.setEntityType(ENTITY_TYPES.MODEL.TYPE);
81025
+ element.setEntitySubtype(ENTITY_TYPES.MODEL.SUBTYPES.DEFAULT);
80878
81026
 
80879
- return element;
81027
+ if (hasAnimations(animations)) {
81028
+ element.addAnimationHandler(animations);
80880
81029
  }
80881
81030
 
80882
- return false;
81031
+ return element;
80883
81032
  });
80884
81033
 
80885
81034
  _defineProperty$1(_assertThisInitialized(_this), "storeModel", (name, model, extension) => {
@@ -80910,8 +81059,23 @@ let Models = /*#__PURE__*/function (_EventDispatcher) {
80910
81059
  return Promise.resolve();
80911
81060
  }
80912
81061
 
80913
- const path = _this.models[name];
80914
- return _this.loadAssetByPath(path, name, options);
81062
+ const modelConfig = _this.models[name]; // Support both string paths and objects with path + dependencies
81063
+ // String format: "models/mymodel.fbx"
81064
+ // Object format: { path: "models/mymodel.fbx", dependencies: { texture: "textures/tex.png" } }
81065
+
81066
+ if (typeof modelConfig === "string") {
81067
+ return _this.loadAssetByPath(modelConfig, name, options);
81068
+ } else if (modelConfig && typeof modelConfig === "object") {
81069
+ const {
81070
+ path,
81071
+ dependencies = {}
81072
+ } = modelConfig;
81073
+ return _this.loadAssetByPath(path, name, { ...options,
81074
+ ...dependencies
81075
+ });
81076
+ }
81077
+
81078
+ return Promise.resolve();
80915
81079
  });
80916
81080
 
80917
81081
  _defineProperty$1(_assertThisInitialized(_this), "loadAssetByPath", function (path, name) {
@@ -80928,10 +81092,10 @@ let Models = /*#__PURE__*/function (_EventDispatcher) {
80928
81092
  tracer
80929
81093
  } = getLoaderFromExtension(extension, options);
80930
81094
  const parser = getModelParserFromExtension(extension);
80931
- tracer.addEventListener(REQUIREMENTS_EVENTS.MISSING, _ref4 => {
81095
+ tracer.addEventListener(REQUIREMENTS_EVENTS.MISSING, _ref => {
80932
81096
  let {
80933
81097
  requirements
80934
- } = _ref4;
81098
+ } = _ref;
80935
81099
 
80936
81100
  _this.dispatchEvent({
80937
81101
  type: `${REQUIREMENTS_EVENTS.MISSING}:${name}`,
@@ -93974,15 +94138,44 @@ let Sky = /*#__PURE__*/function (_Element) {
93974
94138
 
93975
94139
  for (const elementData of elements) {
93976
94140
  try {
93977
- if (elementData.entitySubType === ENTITY_TYPES.MODEL.TYPE) {
94141
+ // Check entityType for models (entitySubType would be MODEL.SUBTYPE.DEFAULT)
94142
+ if (elementData.entityType === ENTITY_TYPES.MODEL.TYPE) {
93978
94143
  const {
93979
- options: modelOptions
94144
+ options: modelOptions = {}
93980
94145
  } = elementData;
93981
94146
  const {
93982
94147
  name,
94148
+ assetPath,
94149
+ dependencies = {},
93983
94150
  ...rest
93984
94151
  } = modelOptions;
93985
- await Importer.completeElementCreation(Models$1.create(name, rest), elementData, options);
94152
+
94153
+ if (!name) {
94154
+ console.warn(`[Mage] Model element missing name in options:`, elementData);
94155
+ continue;
94156
+ } // Load the model first if it's not already loaded
94157
+ // This handles page refresh in the editor where models need to be reloaded
94158
+
94159
+
94160
+ if (assetPath) {
94161
+ const loadResult = await Models$1.loadAssetByPath(assetPath, name, dependencies);
94162
+
94163
+ if (!loadResult) {
94164
+ console.warn(`[Mage] Failed to load model "${name}" from ${assetPath}`);
94165
+ }
94166
+ }
94167
+
94168
+ const model = Models$1.create(name, {
94169
+ assetPath,
94170
+ dependencies,
94171
+ ...rest
94172
+ });
94173
+
94174
+ if (model) {
94175
+ await Importer.completeElementCreation(model, elementData, options);
94176
+ } else {
94177
+ console.warn(`[Mage] Could not create model "${name}" - check assetPath: ${assetPath}`);
94178
+ }
93986
94179
  } else {
93987
94180
  switch (elementData.entitySubType) {
93988
94181
  case ENTITY_TYPES.MESH.SUBTYPES.CUBE:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mage-engine",
3
- "version": "3.23.36",
3
+ "version": "3.23.38",
4
4
  "description": "A WebGL Javascript Game Engine, built on top of THREE.js and many other libraries.",
5
5
  "main": "dist/mage.js",
6
6
  "author": {