@2112-lab/central-plant 0.1.0 → 0.1.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.
Files changed (43) hide show
  1. package/dist/bundle/index.js +7782 -6543
  2. package/dist/cjs/_virtual/_rollupPluginBabelHelpers.js +23 -10
  3. package/dist/cjs/node_modules/@2112-lab/pathfinder/dist/index.esm.js +1448 -0
  4. package/dist/cjs/src/animationManager.js +15 -15
  5. package/dist/cjs/src/componentManager.js +8 -8
  6. package/dist/cjs/src/disposalManager.js +12 -12
  7. package/dist/cjs/src/environmentManager.js +392 -99
  8. package/dist/cjs/src/hotReloadManager.js +26 -26
  9. package/dist/cjs/src/index.js +19 -66
  10. package/dist/cjs/src/keyboardControlsManager.js +23 -23
  11. package/dist/cjs/src/nameUtils.js +21 -21
  12. package/dist/cjs/src/pathfindingManager.js +311 -129
  13. package/dist/cjs/src/performanceMonitor.js +52 -52
  14. package/dist/cjs/src/sceneExportManager.js +23 -23
  15. package/dist/cjs/src/sceneInitializationManager.js +18 -18
  16. package/dist/cjs/src/textureConfig.js +469 -40
  17. package/dist/cjs/src/transformControlsManager.js +79 -79
  18. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +21 -10
  19. package/dist/esm/node_modules/@2112-lab/pathfinder/dist/index.esm.js +1444 -0
  20. package/dist/esm/src/animationManager.js +15 -15
  21. package/dist/esm/src/componentManager.js +8 -8
  22. package/dist/esm/src/disposalManager.js +12 -12
  23. package/dist/esm/src/environmentManager.js +393 -100
  24. package/dist/esm/src/hotReloadManager.js +26 -26
  25. package/dist/esm/src/index.js +19 -66
  26. package/dist/esm/src/keyboardControlsManager.js +23 -23
  27. package/dist/esm/src/nameUtils.js +21 -21
  28. package/dist/esm/src/pathfindingManager.js +313 -129
  29. package/dist/esm/src/performanceMonitor.js +52 -52
  30. package/dist/esm/src/sceneExportManager.js +23 -23
  31. package/dist/esm/src/sceneInitializationManager.js +18 -18
  32. package/dist/esm/src/textureConfig.js +469 -42
  33. package/dist/esm/src/transformControlsManager.js +79 -79
  34. package/dist/index.d.ts +255 -259
  35. package/package.json +52 -53
  36. package/dist/cjs/src/ConnectionManager.js +0 -114
  37. package/dist/cjs/src/Pathfinder.js +0 -88
  38. package/dist/cjs/src/modelPreloader.js +0 -360
  39. package/dist/cjs/src/sceneOperationsManager.js +0 -560
  40. package/dist/esm/src/ConnectionManager.js +0 -110
  41. package/dist/esm/src/Pathfinder.js +0 -84
  42. package/dist/esm/src/modelPreloader.js +0 -337
  43. package/dist/esm/src/sceneOperationsManager.js +0 -536
@@ -25,9 +25,51 @@ function _interopNamespace(e) {
25
25
 
26
26
  var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
27
27
 
28
+ /**
29
+ * Helper function to get asset paths that works in both bundled and modular contexts
30
+ * @param {string} assetPath - Relative path from the assets directory
31
+ * @returns {string} - The full path to the asset
32
+ */
33
+ function getAssetPath(assetPath) {
34
+ // Strip leading slash if present
35
+ if (assetPath.startsWith('/')) {
36
+ assetPath = assetPath.substring(1);
37
+ }
38
+
39
+ // In browser context, check for different module formats
40
+ if (typeof window !== 'undefined') {
41
+ // For bundled version, assets should be in dist/bundle/assets/
42
+ // For ESM/CJS, assets should be in their respective folders
43
+
44
+ // Try to determine if we're using the bundled version or ESM/CJS
45
+ var isBundled = typeof CentralPlantUtils !== 'undefined';
46
+
47
+ // Check if we're running in a Nuxt.js environment (localhost:3000 is a common dev server)
48
+ var isNuxtEnv = window.location.hostname === 'localhost' && (window.location.port === '3000' || window.location.port === '3001');
49
+ if (isNuxtEnv) {
50
+ // In Nuxt.js environment, assets are likely in the /static directory at the root
51
+ return "/".concat(assetPath); // No /assets/ prefix in the URL path
52
+ } else if (isBundled) {
53
+ // Get the base URL for the module
54
+ var baseUrl = (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.src || new URL('src/textureConfig.js', document.baseURI).href));
55
+ // In bundled format, assets are in the assets folder next to the bundle
56
+ return new URL("./assets/".concat(assetPath), baseUrl).href;
57
+ } else {
58
+ // Get the base URL for the module
59
+ var _baseUrl = (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.src || new URL('src/textureConfig.js', document.baseURI).href));
60
+ // In ESM/CJS format, need to go up relative to current module path
61
+ return new URL("../assets/".concat(assetPath), _baseUrl).href;
62
+ }
63
+ }
64
+
65
+ // In Node.js context
66
+ return "assets/".concat(assetPath);
67
+ }
28
68
  var TEXTURE_SETS = {
29
69
  // Light metallic texture using the gravel_embedded_concrete with metallic properties
30
70
  light_metal: {
71
+ // Local path first, with fallback to S3
72
+ localPath: 'textures/gravel_embedded_concrete_1k',
31
73
  path: 'https://central-plant-assets.s3.us-east-1.amazonaws.com/textures/gravel_embedded_concrete_1k',
32
74
  files: {
33
75
  diffuse: 'diffuse.jpg',
@@ -53,6 +95,8 @@ var TEXTURE_SETS = {
53
95
  }
54
96
  },
55
97
  brick: {
98
+ // Local path first, with fallback to S3
99
+ localPath: 'textures/pavement_03_1k',
56
100
  path: 'https://central-plant-assets.s3.us-east-1.amazonaws.com/textures/pavement_03_1k',
57
101
  files: {
58
102
  diffuse: 'diffuse.jpg',
@@ -75,6 +119,8 @@ var TEXTURE_SETS = {
75
119
  }
76
120
  },
77
121
  gravel_embedded_concrete: {
122
+ // Local path first, with fallback to S3
123
+ localPath: 'textures/gravel_embedded_concrete_1k',
78
124
  path: 'https://central-plant-assets.s3.us-east-1.amazonaws.com/textures/gravel_embedded_concrete_1k',
79
125
  files: {
80
126
  diffuse: 'diffuse.jpg',
@@ -95,8 +141,8 @@ var TEXTURE_SETS = {
95
141
  }
96
142
  };
97
143
 
98
- /**
99
- * Create a Three.js texture with appropriate settings
144
+ /**
145
+ * Create a Three.js texture with appropriate settings
100
146
  */
101
147
  function createTexture(textureLoader, url) {
102
148
  var repeat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
@@ -107,89 +153,472 @@ function createTexture(textureLoader, url) {
107
153
  textureLoader = new THREE__namespace.TextureLoader();
108
154
  }
109
155
  try {
110
- var texture = textureLoader.load(url);
111
- texture.wrapS = THREE__namespace.RepeatWrapping;
112
- texture.wrapT = THREE__namespace.RepeatWrapping;
113
- texture.repeat.set(repeat.x, repeat.y);
114
- texture.colorSpace = THREE__namespace.SRGBColorSpace;
115
- return texture;
156
+ console.log("\uD83D\uDD0D Beginning texture load from: ".concat(url));
157
+
158
+ // Create placeholder texture for immediate use
159
+ // This will prevent the "no image data found" warning
160
+ var placeholderTexture = createPlaceholderTexture(0xcccccc);
161
+
162
+ // Create a promise to track when the real texture is loaded
163
+ var loadPromise = new Promise(function (resolve, reject) {
164
+ textureLoader.load(url, function (loadedTexture) {
165
+ console.log("\u2705 Successfully loaded texture from: ".concat(url));
166
+
167
+ // Check if the loaded texture has valid image data
168
+ if (loadedTexture.image && (loadedTexture.image instanceof HTMLImageElement && loadedTexture.image.complete || !(loadedTexture.image instanceof HTMLImageElement))) {
169
+ console.log("\u2705 Image data verified for ".concat(url));
170
+
171
+ // Explicitly set colorSpace for all textures to ensure proper rendering
172
+ if (loadedTexture.colorSpace !== undefined) {
173
+ loadedTexture.colorSpace = THREE__namespace.SRGBColorSpace;
174
+ console.log("\uD83C\uDFA8 Set colorSpace to SRGBColorSpace for ".concat(url));
175
+ } else if (loadedTexture.encoding !== undefined) {
176
+ loadedTexture.encoding = THREE__namespace.sRGBEncoding;
177
+ console.log("\uD83C\uDFA8 Set encoding to sRGBEncoding for ".concat(url));
178
+ }
179
+
180
+ // Configure texture properties
181
+ loadedTexture.wrapS = THREE__namespace.RepeatWrapping;
182
+ loadedTexture.wrapT = THREE__namespace.RepeatWrapping;
183
+ loadedTexture.repeat.set(repeat.x, repeat.y);
184
+ loadedTexture.needsUpdate = true;
185
+ resolve(loadedTexture);
186
+ } else {
187
+ console.warn("\u26A0\uFE0F Loaded texture from ".concat(url, " but image data is not ready"));
188
+ reject(new Error('Texture loaded but image data not ready'));
189
+ }
190
+ }, function (progressEvent) {
191
+ if (progressEvent.lengthComputable) {
192
+ var percentComplete = progressEvent.loaded / progressEvent.total * 100;
193
+ console.log("Loading texture ".concat(url, ": ").concat(Math.round(percentComplete), "% complete"));
194
+ }
195
+ }, function (error) {
196
+ console.error("\u274C Error loading texture from ".concat(url, ":"), error);
197
+ reject(error);
198
+ });
199
+ });
200
+
201
+ // Configure placeholder texture properties
202
+ placeholderTexture.wrapS = THREE__namespace.RepeatWrapping;
203
+ placeholderTexture.wrapT = THREE__namespace.RepeatWrapping;
204
+ placeholderTexture.repeat.set(repeat.x, repeat.y);
205
+
206
+ // Store the load promise and url for later reference
207
+ placeholderTexture.loadPromise = loadPromise;
208
+ placeholderTexture.url = url;
209
+
210
+ // When the real texture loads, we'll swap it in
211
+ loadPromise.then(function (realTexture) {
212
+ // Copy all properties from the real texture to the placeholder
213
+ Object.keys(realTexture).forEach(function (key) {
214
+ // Skip certain properties that shouldn't be copied
215
+ if (['uuid', 'id', 'version', 'isTexture'].includes(key)) return;
216
+ placeholderTexture[key] = realTexture[key];
217
+ });
218
+ placeholderTexture.image = realTexture.image;
219
+ placeholderTexture.source = realTexture.source;
220
+ placeholderTexture.needsUpdate = true;
221
+ console.log("\uD83D\uDD04 Updated placeholder texture with real image data for ".concat(url));
222
+ }).catch(function () {
223
+ console.warn("\u26A0\uFE0F Using placeholder for texture: ".concat(url));
224
+ });
225
+ return placeholderTexture;
116
226
  } catch (error) {
117
227
  console.error("Failed to load texture: ".concat(url), error);
118
- return null;
228
+ return createPlaceholderTexture(0xdd3333); // Red placeholder for errors
119
229
  }
120
230
  }
121
231
 
122
- /**
123
- * Load a texture set and create a material
232
+ /**
233
+ * Load a texture set and create a material
124
234
  */
125
235
  function loadTextureSetAndCreateMaterial(_x, _x2) {
126
236
  return _loadTextureSetAndCreateMaterial.apply(this, arguments);
127
237
  }
238
+
239
+ /**
240
+ * Check if a texture has valid image data
241
+ * @param {THREE.Texture} texture - The texture to check
242
+ * @returns {boolean} - Whether the texture has valid image data
243
+ */
128
244
  function _loadTextureSetAndCreateMaterial() {
129
- _loadTextureSetAndCreateMaterial = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee(component, textureSetName) {
130
- var textureSet, textureLoader, repeat, loadedTextures, loadTexture, material;
131
- return _rollupPluginBabelHelpers.regenerator().w(function (_context) {
132
- while (1) switch (_context.n) {
245
+ _loadTextureSetAndCreateMaterial = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee4(component, textureSetName) {
246
+ var _textureSet$materialP2;
247
+ var textureSet, textureLoader, repeat, loadedTextures, checkFileExists, loadTexture, texturePromises, hasAnyTextures, _textureSet$materialP, fallbackColor, texturesWithValidData, _i2, _Object$entries, _Object$entries$_i, type, texture, material;
248
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context4) {
249
+ while (1) switch (_context4.n) {
133
250
  case 0:
134
251
  if (component) {
135
- _context.n = 1;
252
+ _context4.n = 1;
136
253
  break;
137
254
  }
138
255
  console.warn('Component is required for texture loading');
139
- return _context.a(2, new THREE__namespace.MeshStandardMaterial({
256
+ return _context4.a(2, new THREE__namespace.MeshStandardMaterial({
140
257
  color: 0xaaaaaa
141
258
  }));
142
259
  case 1:
143
260
  textureSet = TEXTURE_SETS[textureSetName];
144
261
  if (textureSet) {
145
- _context.n = 2;
262
+ _context4.n = 2;
146
263
  break;
147
264
  }
148
265
  console.warn("Texture set not found: ".concat(textureSetName));
149
- return _context.a(2, new THREE__namespace.MeshStandardMaterial({
266
+ return _context4.a(2, new THREE__namespace.MeshStandardMaterial({
150
267
  color: 0xaaaaaa
151
268
  }));
152
269
  case 2:
153
- textureLoader = component.textureLoader || new THREE__namespace.TextureLoader();
270
+ console.log("\uD83C\uDF08 Loading texture set: ".concat(textureSetName));
271
+ textureLoader = component.textureLoader || new THREE__namespace.TextureLoader(); // Set cross-origin attribute to allow texture loading from different domains
272
+ if (typeof textureLoader.setCrossOrigin === 'function') {
273
+ textureLoader.setCrossOrigin('anonymous');
274
+ console.log('📡 Set cross-origin to anonymous for texture loading');
275
+ }
154
276
  repeat = textureSet.repeat || {
155
277
  x: 1,
156
278
  y: 1
157
279
  };
158
- loadedTextures = {}; // Function to load a specific texture from the set
159
- loadTexture = function loadTexture(type) {
160
- if (!textureSet.files[type]) return null;
161
- var url = "".concat(textureSet.path, "/").concat(textureSet.files[type]);
162
- return createTexture(textureLoader, url, repeat);
163
- }; // Load all textures in the set
164
- Object.keys(textureSet.files).forEach(function (type) {
165
- loadedTextures[type] = loadTexture(type);
280
+ loadedTextures = {}; // Function to check if a file exists
281
+ checkFileExists = /*#__PURE__*/function () {
282
+ var _ref = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee(url) {
283
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context) {
284
+ while (1) switch (_context.n) {
285
+ case 0:
286
+ if (!(typeof window !== 'undefined')) {
287
+ _context.n = 1;
288
+ break;
289
+ }
290
+ return _context.a(2, new Promise(function (resolve) {
291
+ var img = new Image();
292
+ img.onload = function () {
293
+ return resolve(true);
294
+ };
295
+ img.onerror = function () {
296
+ return resolve(false);
297
+ };
298
+ img.src = url;
299
+ setTimeout(function () {
300
+ return resolve(false);
301
+ }, 2000);
302
+ }));
303
+ case 1:
304
+ return _context.a(2, false);
305
+ }
306
+ }, _callee);
307
+ }));
308
+ return function checkFileExists(_x3) {
309
+ return _ref.apply(this, arguments);
310
+ };
311
+ }(); // Function to load a specific texture from the set
312
+ loadTexture = /*#__PURE__*/function () {
313
+ var _ref2 = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee2(type) {
314
+ var paths, _i, _paths, path, exists;
315
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context2) {
316
+ while (1) switch (_context2.n) {
317
+ case 0:
318
+ if (textureSet.files[type]) {
319
+ _context2.n = 1;
320
+ break;
321
+ }
322
+ return _context2.a(2, null);
323
+ case 1:
324
+ // Try multiple paths to find the texture
325
+ paths = []; // 1. Try local bundled path first
326
+ if (textureSet.localPath) {
327
+ paths.push(getAssetPath("".concat(textureSet.localPath, "/").concat(textureSet.files[type])));
328
+ }
329
+
330
+ // 2. Try direct path to static folder
331
+ paths.push("/textures/".concat(textureSetName, "_1k/").concat(textureSet.files[type]));
332
+
333
+ // 3. Try remote path as fallback
334
+ if (textureSet.path) {
335
+ paths.push("".concat(textureSet.path, "/").concat(textureSet.files[type]));
336
+ }
337
+ console.log("\uD83D\uDD0D Will try loading texture ".concat(type, " from paths:"), paths);
338
+
339
+ // Try each path until one works
340
+ _i = 0, _paths = paths;
341
+ case 2:
342
+ if (!(_i < _paths.length)) {
343
+ _context2.n = 6;
344
+ break;
345
+ }
346
+ path = _paths[_i];
347
+ console.log("\uD83D\uDD04 Checking if texture exists at: ".concat(path));
348
+ _context2.n = 3;
349
+ return checkFileExists(path);
350
+ case 3:
351
+ exists = _context2.v;
352
+ if (!exists) {
353
+ _context2.n = 4;
354
+ break;
355
+ }
356
+ console.log("\u2705 Texture found at: ".concat(path));
357
+ return _context2.a(2, createTexture(textureLoader, path, repeat));
358
+ case 4:
359
+ console.log("\u274C Texture not found at: ".concat(path));
360
+ case 5:
361
+ _i++;
362
+ _context2.n = 2;
363
+ break;
364
+ case 6:
365
+ console.error("\u274C Failed to load ".concat(type, " texture from any path"));
366
+ return _context2.a(2, null);
367
+ }
368
+ }, _callee2);
369
+ }));
370
+ return function loadTexture(_x4) {
371
+ return _ref2.apply(this, arguments);
372
+ };
373
+ }(); // Load all textures in the set
374
+ texturePromises = Object.keys(textureSet.files).map(/*#__PURE__*/function () {
375
+ var _ref3 = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee3(type) {
376
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context3) {
377
+ while (1) switch (_context3.n) {
378
+ case 0:
379
+ _context3.n = 1;
380
+ return loadTexture(type);
381
+ case 1:
382
+ loadedTextures[type] = _context3.v;
383
+ return _context3.a(2, {
384
+ type: type,
385
+ texture: loadedTextures[type]
386
+ });
387
+ }
388
+ }, _callee3);
389
+ }));
390
+ return function (_x5) {
391
+ return _ref3.apply(this, arguments);
392
+ };
393
+ }());
394
+ _context4.n = 3;
395
+ return Promise.all(texturePromises);
396
+ case 3:
397
+ // Log successful texture loads
398
+ Object.entries(loadedTextures).forEach(function (_ref4) {
399
+ var _ref5 = _rollupPluginBabelHelpers.slicedToArray(_ref4, 2),
400
+ type = _ref5[0],
401
+ texture = _ref5[1];
402
+ console.log("".concat(texture ? '✅' : '❌', " ").concat(type, " texture: ").concat(texture ? 'Loaded' : 'Failed'));
403
+ }); // Create material with textures and properties
404
+ console.log('Creating material with loaded textures and properties:', textureSet.materialProps);
405
+
406
+ // Check if we have at least one texture that's not null
407
+ hasAnyTextures = Object.values(loadedTextures).some(function (texture) {
408
+ return texture !== null;
166
409
  });
410
+ if (hasAnyTextures) {
411
+ _context4.n = 4;
412
+ break;
413
+ }
414
+ console.warn('⚠️ No textures loaded successfully for material. Using fallback color material.');
415
+
416
+ // Create a colored material as fallback
417
+ fallbackColor = ((_textureSet$materialP = textureSet.materialProps) === null || _textureSet$materialP === void 0 ? void 0 : _textureSet$materialP.color) || 0xaaaaaa;
418
+ return _context4.a(2, new THREE__namespace.MeshStandardMaterial({
419
+ color: fallbackColor,
420
+ roughness: 0.8,
421
+ metalness: 0.2,
422
+ side: THREE__namespace.DoubleSide
423
+ }));
424
+ case 4:
425
+ // Verify if the textures have valid image data
426
+ texturesWithValidData = {};
427
+ for (_i2 = 0, _Object$entries = Object.entries(loadedTextures); _i2 < _Object$entries.length; _i2++) {
428
+ _Object$entries$_i = _rollupPluginBabelHelpers.slicedToArray(_Object$entries[_i2], 2), type = _Object$entries$_i[0], texture = _Object$entries$_i[1];
429
+ if (texture && hasValidImageData(texture)) {
430
+ console.log("\u2705 Texture '".concat(type, "' has valid image data"));
431
+ texturesWithValidData[type] = texture;
432
+ } else if (texture) {
433
+ console.log("\u26A0\uFE0F Texture '".concat(type, "' doesn't have valid image data yet"));
434
+ // Keep the texture even if it doesn't have valid data yet
435
+ // Our createTexture function now handles this with placeholders
436
+ texturesWithValidData[type] = texture;
437
+ }
438
+ }
167
439
 
168
- // Create material with textures and properties
169
- material = new THREE__namespace.MeshStandardMaterial(_rollupPluginBabelHelpers.objectSpread2({
170
- map: loadedTextures.diffuse,
171
- normalMap: loadedTextures.normal,
172
- roughnessMap: loadedTextures.roughness,
173
- metalnessMap: loadedTextures.metalness,
174
- aoMap: loadedTextures.ao,
175
- displacementMap: loadedTextures.displacement
176
- }, textureSet.materialProps)); // Add the environment map if available from the component
440
+ // Create the standard material with loaded textures
441
+ material = new THREE__namespace.MeshStandardMaterial(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({
442
+ map: texturesWithValidData.diffuse,
443
+ normalMap: texturesWithValidData.normal,
444
+ roughnessMap: texturesWithValidData.roughness,
445
+ metalnessMap: texturesWithValidData.metalness,
446
+ aoMap: texturesWithValidData.ao,
447
+ displacementMap: texturesWithValidData.displacement
448
+ }, textureSet.materialProps), {}, {
449
+ side: THREE__namespace.DoubleSide // Always set DoubleSide to avoid rendering issues
450
+ })); // Ensure color is applied even if textures are loading
451
+
452
+ if ((!material.map || !hasValidImageData(material.map)) && (_textureSet$materialP2 = textureSet.materialProps) !== null && _textureSet$materialP2 !== void 0 && _textureSet$materialP2.color) {
453
+ material.color = new THREE__namespace.Color(textureSet.materialProps.color);
454
+ console.log("\uD83C\uDFA8 Applied fallback color: #".concat(material.color.getHexString()));
455
+ }
456
+
457
+ // Make sure material updates when textures load
458
+ material.needsUpdate = true;
459
+
460
+ // Add the environment map if available from the component
177
461
  if (component.scene && component.scene.environment) {
178
462
  material.envMap = component.scene.environment;
463
+ console.log('🌐 Added environment map to material');
179
464
  }
180
- return _context.a(2, material);
465
+
466
+ // Set up texture load monitoring for each texture with a load promise
467
+ Object.entries(texturesWithValidData).forEach(function (_ref6) {
468
+ var _ref7 = _rollupPluginBabelHelpers.slicedToArray(_ref6, 2),
469
+ type = _ref7[0],
470
+ texture = _ref7[1];
471
+ if (texture && texture.loadPromise) {
472
+ texture.loadPromise.then(function () {
473
+ console.log("\u2705 Texture '".concat(type, "' finished loading, updating material"));
474
+ material.needsUpdate = true;
475
+ }).catch(function (error) {
476
+ console.warn("\u26A0\uFE0F Failed to load '".concat(type, "' texture:"), error);
477
+ });
478
+ }
479
+ });
480
+ return _context4.a(2, material);
181
481
  }
182
- }, _callee);
482
+ }, _callee4);
183
483
  }));
184
484
  return _loadTextureSetAndCreateMaterial.apply(this, arguments);
185
485
  }
486
+ function hasValidImageData(texture) {
487
+ if (!texture) return false;
488
+
489
+ // Check if image exists
490
+ if (!texture.image) return false;
491
+
492
+ // For image objects, check width and height
493
+ if (texture.image instanceof HTMLImageElement || texture.image instanceof HTMLCanvasElement) {
494
+ return texture.image.width > 0 && texture.image.height > 0;
495
+ }
496
+
497
+ // For other image types (like ImageBitmap)
498
+ if (texture.image.data && Array.isArray(texture.image.data)) {
499
+ return texture.image.data.length > 0;
500
+ }
501
+ return false;
502
+ }
503
+
504
+ /**
505
+ * Create a placeholder colored texture when image loading fails
506
+ * @param {number} color - The color for the placeholder texture
507
+ * @param {number} size - The size of the texture in pixels
508
+ * @returns {THREE.Texture} - A colored placeholder texture
509
+ */
510
+ function createPlaceholderTexture() {
511
+ var color = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0xcccccc;
512
+ var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 64;
513
+ // Create a canvas element
514
+ var canvas = document.createElement('canvas');
515
+ canvas.width = size;
516
+ canvas.height = size;
517
+
518
+ // Get the 2D context and fill with color
519
+ var context = canvas.getContext('2d');
520
+ if (context) {
521
+ var hexColor = '#' + color.toString(16).padStart(6, '0');
522
+ context.fillStyle = hexColor;
523
+ context.fillRect(0, 0, size, size);
524
+
525
+ // Optional: Add a pattern to make it obvious it's a placeholder
526
+ context.fillStyle = '#' + (color + 0x222222 & 0xffffff).toString(16);
527
+ context.fillRect(0, 0, size / 2, size / 2);
528
+ context.fillRect(size / 2, size / 2, size / 2, size / 2);
529
+ }
530
+
531
+ // Create a texture from the canvas
532
+ var texture = new THREE__namespace.CanvasTexture(canvas);
533
+ texture.needsUpdate = true;
534
+
535
+ // Set proper color space
536
+ if (texture.colorSpace !== undefined) {
537
+ texture.colorSpace = THREE__namespace.SRGBColorSpace;
538
+ } else if (texture.encoding !== undefined) {
539
+ texture.encoding = THREE__namespace.sRGBEncoding;
540
+ }
541
+ return texture;
542
+ }
543
+
544
+ /**
545
+ * Helper function to check Three.js compatibility and configuration
546
+ */
547
+ function checkThreeJSCompatibility() {
548
+ console.group('🔍 Three.js Compatibility Check');
549
+
550
+ // Check Three.js version
551
+ console.log('Three.js version:', THREE__namespace.REVISION);
552
+
553
+ // Check color space constants
554
+ console.log('Color space support:', {
555
+ SRGBColorSpace: typeof THREE__namespace.SRGBColorSpace !== 'undefined',
556
+ LinearSRGBColorSpace: typeof THREE__namespace.LinearSRGBColorSpace !== 'undefined',
557
+ sRGBEncoding: typeof THREE__namespace.sRGBEncoding !== 'undefined'
558
+ });
559
+
560
+ // Check texture-related features
561
+ console.log('Texture features:', {
562
+ TextureLoader: typeof THREE__namespace.TextureLoader === 'function',
563
+ RepeatWrapping: typeof THREE__namespace.RepeatWrapping !== 'undefined',
564
+ MirroredRepeatWrapping: typeof THREE__namespace.MirroredRepeatWrapping !== 'undefined'
565
+ });
566
+
567
+ // Check shader and material features
568
+ console.log('Material features:', {
569
+ MeshStandardMaterial: typeof THREE__namespace.MeshStandardMaterial === 'function',
570
+ MeshBasicMaterial: typeof THREE__namespace.MeshBasicMaterial === 'function',
571
+ ShaderMaterial: typeof THREE__namespace.ShaderMaterial === 'function'
572
+ });
573
+ console.groupEnd();
574
+ return {
575
+ version: THREE__namespace.REVISION,
576
+ hasNewColorSpace: typeof THREE__namespace.SRGBColorSpace !== 'undefined',
577
+ hasOldEncoding: typeof THREE__namespace.sRGBEncoding !== 'undefined',
578
+ hasTextureLoader: typeof THREE__namespace.TextureLoader === 'function'
579
+ };
580
+ }
581
+ function forceUpdateMaterials(scene) {
582
+ if (!scene) return;
583
+ console.log('🔄 Forcing update on all scene materials...');
584
+ var materialCount = 0;
585
+ scene.traverse(function (node) {
586
+ if (node.isMesh && node.material) {
587
+ var materials = Array.isArray(node.material) ? node.material : [node.material];
588
+ materials.forEach(function (material) {
589
+ if (material) {
590
+ material.needsUpdate = true;
591
+ materialCount++;
592
+
593
+ // Ensure maps are properly set
594
+ if (material.map) {
595
+ material.map.needsUpdate = true;
596
+ }
597
+ if (material.normalMap) {
598
+ material.normalMap.needsUpdate = true;
599
+ }
600
+ if (material.roughnessMap) {
601
+ material.roughnessMap.needsUpdate = true;
602
+ }
603
+ }
604
+ });
605
+ }
606
+ });
607
+ console.log("\u2705 Updated ".concat(materialCount, " materials in the scene"));
608
+ }
186
609
  var textureConfig = {
187
610
  TEXTURE_SETS: TEXTURE_SETS,
188
611
  createTexture: createTexture,
189
- loadTextureSetAndCreateMaterial: loadTextureSetAndCreateMaterial
612
+ loadTextureSetAndCreateMaterial: loadTextureSetAndCreateMaterial,
613
+ checkThreeJSCompatibility: checkThreeJSCompatibility,
614
+ forceUpdateMaterials: forceUpdateMaterials,
615
+ hasValidImageData: hasValidImageData,
616
+ createPlaceholderTexture: createPlaceholderTexture
190
617
  };
191
618
 
192
619
  exports.TEXTURE_SETS = TEXTURE_SETS;
620
+ exports.checkThreeJSCompatibility = checkThreeJSCompatibility;
193
621
  exports.createTexture = createTexture;
194
622
  exports["default"] = textureConfig;
623
+ exports.forceUpdateMaterials = forceUpdateMaterials;
195
624
  exports.loadTextureSetAndCreateMaterial = loadTextureSetAndCreateMaterial;