@2112-lab/central-plant 0.1.0

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 (54) hide show
  1. package/README.md +0 -0
  2. package/dist/bundle/index.js +14259 -0
  3. package/dist/cjs/_virtual/_rollupPluginBabelHelpers.js +353 -0
  4. package/dist/cjs/node_modules/three/examples/jsm/controls/OrbitControls.js +1292 -0
  5. package/dist/cjs/node_modules/three/examples/jsm/controls/TransformControls.js +1543 -0
  6. package/dist/cjs/node_modules/three/examples/jsm/loaders/GLTFLoader.js +4374 -0
  7. package/dist/cjs/node_modules/three/examples/jsm/loaders/RGBELoader.js +465 -0
  8. package/dist/cjs/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +117 -0
  9. package/dist/cjs/src/ConnectionManager.js +114 -0
  10. package/dist/cjs/src/Pathfinder.js +88 -0
  11. package/dist/cjs/src/animationManager.js +121 -0
  12. package/dist/cjs/src/componentManager.js +151 -0
  13. package/dist/cjs/src/debugLogger.js +176 -0
  14. package/dist/cjs/src/disposalManager.js +185 -0
  15. package/dist/cjs/src/environmentManager.js +1015 -0
  16. package/dist/cjs/src/hotReloadManager.js +252 -0
  17. package/dist/cjs/src/index.js +126 -0
  18. package/dist/cjs/src/keyboardControlsManager.js +206 -0
  19. package/dist/cjs/src/modelPreloader.js +360 -0
  20. package/dist/cjs/src/nameUtils.js +106 -0
  21. package/dist/cjs/src/pathfindingManager.js +321 -0
  22. package/dist/cjs/src/performanceMonitor.js +718 -0
  23. package/dist/cjs/src/sceneExportManager.js +292 -0
  24. package/dist/cjs/src/sceneInitializationManager.js +540 -0
  25. package/dist/cjs/src/sceneOperationsManager.js +560 -0
  26. package/dist/cjs/src/textureConfig.js +195 -0
  27. package/dist/cjs/src/transformControlsManager.js +851 -0
  28. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +328 -0
  29. package/dist/esm/node_modules/three/examples/jsm/controls/OrbitControls.js +1287 -0
  30. package/dist/esm/node_modules/three/examples/jsm/controls/TransformControls.js +1537 -0
  31. package/dist/esm/node_modules/three/examples/jsm/loaders/GLTFLoader.js +4370 -0
  32. package/dist/esm/node_modules/three/examples/jsm/loaders/RGBELoader.js +461 -0
  33. package/dist/esm/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +113 -0
  34. package/dist/esm/src/ConnectionManager.js +110 -0
  35. package/dist/esm/src/Pathfinder.js +84 -0
  36. package/dist/esm/src/animationManager.js +112 -0
  37. package/dist/esm/src/componentManager.js +123 -0
  38. package/dist/esm/src/debugLogger.js +167 -0
  39. package/dist/esm/src/disposalManager.js +155 -0
  40. package/dist/esm/src/environmentManager.js +989 -0
  41. package/dist/esm/src/hotReloadManager.js +244 -0
  42. package/dist/esm/src/index.js +117 -0
  43. package/dist/esm/src/keyboardControlsManager.js +196 -0
  44. package/dist/esm/src/modelPreloader.js +337 -0
  45. package/dist/esm/src/nameUtils.js +99 -0
  46. package/dist/esm/src/pathfindingManager.js +295 -0
  47. package/dist/esm/src/performanceMonitor.js +712 -0
  48. package/dist/esm/src/sceneExportManager.js +286 -0
  49. package/dist/esm/src/sceneInitializationManager.js +513 -0
  50. package/dist/esm/src/sceneOperationsManager.js +536 -0
  51. package/dist/esm/src/textureConfig.js +168 -0
  52. package/dist/esm/src/transformControlsManager.js +827 -0
  53. package/dist/index.d.ts +259 -0
  54. package/package.json +53 -0
@@ -0,0 +1,536 @@
1
+ import { createClass as _createClass, objectSpread2 as _objectSpread2, classCallCheck as _classCallCheck, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../_virtual/_rollupPluginBabelHelpers.js';
2
+ import { findObjectByHardcodedUuid } from './nameUtils.js';
3
+
4
+ /**
5
+ * SceneOperationsManager
6
+ * Handles scene loading, clearing, and object management operations
7
+ */
8
+
9
+ var THREE;
10
+
11
+ /**
12
+ * Dynamically import ThreeJS when in browser environment
13
+ */
14
+ function importDependencies() {
15
+ return _importDependencies.apply(this, arguments);
16
+ }
17
+ function _importDependencies() {
18
+ _importDependencies = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
19
+ var _t;
20
+ return _regenerator().w(function (_context) {
21
+ while (1) switch (_context.n) {
22
+ case 0:
23
+ if (!(typeof window !== 'undefined')) {
24
+ _context.n = 4;
25
+ break;
26
+ }
27
+ _context.p = 1;
28
+ _context.n = 2;
29
+ return import('three');
30
+ case 2:
31
+ THREE = _context.v;
32
+ _context.n = 4;
33
+ break;
34
+ case 3:
35
+ _context.p = 3;
36
+ _t = _context.v;
37
+ console.error('Failed to load Three.js:', _t);
38
+ throw new Error('SceneOperationsManager: Required dependencies could not be loaded');
39
+ case 4:
40
+ return _context.a(2);
41
+ }
42
+ }, _callee, null, [[1, 3]]);
43
+ }));
44
+ return _importDependencies.apply(this, arguments);
45
+ }
46
+
47
+ /**
48
+ * Class for managing scene operations like loading, clearing, and object management
49
+ */
50
+ var SceneOperationsManager = /*#__PURE__*/function () {
51
+ /**
52
+ * Create a SceneOperationsManager
53
+ * @param {Object} component - The component with scene, camera, renderer, etc.
54
+ */
55
+ function SceneOperationsManager(component) {
56
+ _classCallCheck(this, SceneOperationsManager);
57
+ this.component = component;
58
+
59
+ // Initialize if in browser environment
60
+ if (typeof window !== 'undefined') {
61
+ importDependencies();
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Clear scene objects while preserving base environment
67
+ */
68
+ return _createClass(SceneOperationsManager, [{
69
+ key: "clearSceneObjects",
70
+ value: function clearSceneObjects() {
71
+ var component = this.component;
72
+ console.log('🧹 Starting scene clear operation...');
73
+
74
+ // First, deselect any currently selected object
75
+ this.deselectObject();
76
+
77
+ // Store reference to transform controls to ensure it's not removed
78
+ var transformControlsRef = null;
79
+ if (component.transformManager && component.transformManager.transformControls) {
80
+ // Explicitly disable transform controls before clearing
81
+ console.log('🔧 Disabling transform controls before scene clear');
82
+ component.transformManager.setEnabled(false);
83
+ component.transformManager.transformControls.visible = false;
84
+ transformControlsRef = component.transformManager.transformControls;
85
+ console.log('🔧 Stored reference to existing transform controls');
86
+ }
87
+ var objectsToRemove = [];
88
+ var transformControlsFound = 0;
89
+ var totalChildren = 0;
90
+ component.scene.traverse(function (child) {
91
+ var _child$userData, _child$userData2, _child$userData3, _child$userData4, _child$geometry;
92
+ totalChildren++;
93
+
94
+ // Check for transform controls using multiple detection methods
95
+ var isTransformControl = child === transformControlsRef || ((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.isTransformControls) || child.isTransformControls || child.type && child.type.includes('TransformControls');
96
+ if (isTransformControl) {
97
+ transformControlsFound++;
98
+ console.log('🔧 Found transform controls, preserving:', child.uuid);
99
+ }
100
+
101
+ // Remove imported scene objects but preserve base ground, walls, lights, and transform controls
102
+ if (child !== component.scene && !((_child$userData2 = child.userData) !== null && _child$userData2 !== void 0 && _child$userData2.isBrickWall) && !((_child$userData3 = child.userData) !== null && _child$userData3 !== void 0 && _child$userData3.isBaseGround) && !((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBaseGrid) && !isTransformControl && !child.isLight && ((_child$geometry = child.geometry) === null || _child$geometry === void 0 ? void 0 : _child$geometry.type) !== 'PlaneGeometry') {
103
+ objectsToRemove.push(child);
104
+ }
105
+ });
106
+ console.log("\uD83D\uDCCA Scene analysis: ".concat(totalChildren, " total children, ").concat(transformControlsFound, " transform controls found, ").concat(objectsToRemove.length, " objects to remove"));
107
+ objectsToRemove.forEach(function (obj) {
108
+ component.scene.remove(obj);
109
+
110
+ // Dispose of geometry and materials to prevent memory leaks
111
+ if (obj.geometry) obj.geometry.dispose();
112
+ if (obj.material) {
113
+ if (Array.isArray(obj.material)) {
114
+ obj.material.forEach(function (mat) {
115
+ return mat.dispose();
116
+ });
117
+ } else {
118
+ obj.material.dispose();
119
+ }
120
+ }
121
+ });
122
+
123
+ // Clear any references to removed objects
124
+ component.selectedObjectForTransform = null;
125
+ if (component.transformHistory) {
126
+ component.transformHistory = [];
127
+ }
128
+
129
+ // Make sure transform controls exist after clearing
130
+ if (!component.transformManager || !component.transformManager.transformControls) {
131
+ console.log('🔧 Transform controls missing after scene clear, reinitializing...');
132
+ if (typeof component.initTransformControls === 'function') {
133
+ component.initTransformControls();
134
+ }
135
+ }
136
+
137
+ // Ensure transform controls are still properly attached after scene operations
138
+ this.ensureTransformControlsAttached(false);
139
+ console.log('✅ Scene clear operation completed');
140
+ }
141
+
142
+ /**
143
+ * Ensure transform controls remain properly attached after scene operations
144
+ * @param {boolean} attachToSelected - Whether to attach to selected object
145
+ */
146
+ }, {
147
+ key: "ensureTransformControlsAttached",
148
+ value: function ensureTransformControlsAttached() {
149
+ var attachToSelected = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
150
+ var component = this.component;
151
+ if (component.transformManager) {
152
+ // Re-enable transform controls after scene operations
153
+ component.transformManager.setEnabled(true);
154
+
155
+ // Reattach to selected object if one exists and flag is true
156
+ if (attachToSelected && component.selectedObjectForTransform) {
157
+ component.transformManager.selectObject(component.selectedObjectForTransform);
158
+ }
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Deselect any selected object
164
+ */
165
+ }, {
166
+ key: "deselectObject",
167
+ value: function deselectObject() {
168
+ var component = this.component;
169
+ if (component.transformManager && component.selectedObjectForTransform) {
170
+ component.transformManager.deselectObject();
171
+ component.selectedObjectForTransform = null;
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Load scene data from JSON
177
+ * @param {Object|string} sceneData - Scene data object or JSON string
178
+ */
179
+ }, {
180
+ key: "loadSceneData",
181
+ value: function loadSceneData(sceneData) {
182
+ var component = this.component;
183
+ console.log('📥 Starting scene load operation...');
184
+
185
+ // Parse JSON if string provided
186
+ var parsedData = sceneData;
187
+ if (typeof sceneData === 'string') {
188
+ try {
189
+ parsedData = JSON.parse(sceneData);
190
+ } catch (e) {
191
+ console.error('❌ Failed to parse scene data:', e);
192
+ return false;
193
+ }
194
+ }
195
+
196
+ // Validate scene data format
197
+ if (!parsedData || !parsedData.scene || !parsedData.scene.object) {
198
+ console.error('❌ Invalid scene data format');
199
+ return false;
200
+ }
201
+
202
+ // Store reference to scene data
203
+ component.currentSceneData = parsedData;
204
+
205
+ // Clear existing scene objects
206
+ this.clearSceneObjects();
207
+
208
+ // Load scene objects
209
+ this._loadSceneObjects(parsedData.scene.object);
210
+
211
+ // Load connections if applicable
212
+ if (parsedData.connections && Array.isArray(parsedData.connections)) {
213
+ this._loadConnections(parsedData.connections);
214
+ }
215
+ console.log('✅ Scene load completed');
216
+ return true;
217
+ }
218
+
219
+ /**
220
+ * Load scene objects from parsed scene data
221
+ * @param {Object} sceneObject - The root scene object from parsed data
222
+ * @private
223
+ */
224
+ }, {
225
+ key: "_loadSceneObjects",
226
+ value: function _loadSceneObjects(sceneObject) {
227
+ var _this = this;
228
+ var component = this.component;
229
+
230
+ // Recursively process all object children
231
+ if (sceneObject.children && Array.isArray(sceneObject.children)) {
232
+ sceneObject.children.forEach(function (childData) {
233
+ var childObject = _this._createObjectFromData(childData);
234
+ if (childObject) {
235
+ component.scene.add(childObject);
236
+ }
237
+ });
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Create a Three.js object from object data
243
+ * @param {Object} objectData - The object data from parsed scene
244
+ * @returns {THREE.Object3D} The created object or null if invalid
245
+ * @private
246
+ */
247
+ }, {
248
+ key: "_createObjectFromData",
249
+ value: function _createObjectFromData(objectData) {
250
+ var _this2 = this;
251
+ // Ensure THREE is loaded
252
+ if (!THREE) {
253
+ console.warn('⚠️ THREE.js not loaded, cannot create objects');
254
+ return null;
255
+ }
256
+
257
+ // Create base object
258
+ var object = new THREE.Object3D();
259
+
260
+ // Set UUID (use hardcoded UUID if possible)
261
+ if (objectData.uuid) {
262
+ object.uuid = objectData.uuid;
263
+ }
264
+
265
+ // Set name
266
+ object.name = objectData.name || 'Unnamed';
267
+
268
+ // Set position
269
+ if (objectData.position) {
270
+ object.position.set(objectData.position.x || 0, objectData.position.y || 0, objectData.position.z || 0);
271
+ }
272
+
273
+ // Set rotation (convert from degrees to radians)
274
+ if (objectData.rotation) {
275
+ object.rotation.set((objectData.rotation.x || 0) * (Math.PI / 180), (objectData.rotation.y || 0) * (Math.PI / 180), (objectData.rotation.z || 0) * (Math.PI / 180));
276
+ }
277
+
278
+ // Set scale
279
+ if (objectData.scale) {
280
+ object.scale.set(objectData.scale.x || 1, objectData.scale.y || 1, objectData.scale.z || 1);
281
+ }
282
+
283
+ // Set userData
284
+ if (objectData.userData) {
285
+ object.userData = _objectSpread2({}, objectData.userData);
286
+ }
287
+
288
+ // Special handling for different object types
289
+ this._setupObjectByType(object, objectData);
290
+
291
+ // Process children recursively
292
+ if (objectData.children && Array.isArray(objectData.children)) {
293
+ objectData.children.forEach(function (childData) {
294
+ var childObject = _this2._createObjectFromData(childData);
295
+ if (childObject) {
296
+ object.add(childObject);
297
+ }
298
+ });
299
+ }
300
+ return object;
301
+ }
302
+
303
+ /**
304
+ * Set up object properties based on type
305
+ * @param {THREE.Object3D} object - The object to set up
306
+ * @param {Object} objectData - The object data
307
+ * @private
308
+ */
309
+ }, {
310
+ key: "_setupObjectByType",
311
+ value: function _setupObjectByType(object, objectData) {
312
+ var _objectData$userData, _objectData$userData2;
313
+ // Handle library component objects
314
+ if ((_objectData$userData = objectData.userData) !== null && _objectData$userData !== void 0 && _objectData$userData.componentType && (_objectData$userData2 = objectData.userData) !== null && _objectData$userData2 !== void 0 && _objectData$userData2.libraryId) {
315
+ // If model preloader is available, attempt to load model
316
+ if (this.component.modelPreloader) {
317
+ this.component.modelPreloader.loadComponentById(objectData.userData.libraryId, function (model) {
318
+ if (model) {
319
+ // Copy model but preserve our object's transform and userData
320
+ var position = object.position.clone();
321
+ var rotation = object.rotation.clone();
322
+ var scale = object.scale.clone();
323
+ var userData = _objectSpread2({}, object.userData);
324
+
325
+ // Copy model properties to our object
326
+ object.copy(model);
327
+
328
+ // Restore transform and userData
329
+ object.position.copy(position);
330
+ object.rotation.copy(rotation);
331
+ object.scale.copy(scale);
332
+ object.userData = userData;
333
+ console.log("\u2705 Loaded model for ".concat(objectData.name, " (").concat(objectData.userData.libraryId, ")"));
334
+ }
335
+ });
336
+ }
337
+ }
338
+
339
+ // Handle primitive geometry
340
+ if (objectData.geometry) {
341
+ var geometry;
342
+
343
+ // Create appropriate geometry based on type hint
344
+ if (objectData.geometry === 'CONNECTOR-GEO') {
345
+ geometry = new THREE.SphereGeometry(0.5, 16, 16);
346
+ } else if (objectData.geometry === 'GATEWAY-GEO') {
347
+ geometry = new THREE.CylinderGeometry(0.5, 0.5, 1, 16);
348
+ } else {
349
+ // Default to box geometry for other types
350
+ geometry = new THREE.BoxGeometry(1, 1, 1);
351
+ }
352
+
353
+ // Create mesh with geometry and basic material
354
+ var material = new THREE.MeshStandardMaterial({
355
+ color: 0x999999,
356
+ transparent: true,
357
+ opacity: 0.7
358
+ });
359
+ var mesh = new THREE.Mesh(geometry, material);
360
+
361
+ // Copy transform from parent
362
+ mesh.position.copy(object.position);
363
+ mesh.rotation.copy(object.rotation);
364
+ mesh.scale.copy(object.scale);
365
+
366
+ // Reset parent transform since the mesh now has it
367
+ object.position.set(0, 0, 0);
368
+ object.rotation.set(0, 0, 0);
369
+ object.scale.set(1, 1, 1);
370
+
371
+ // Add mesh as child of parent
372
+ object.add(mesh);
373
+ }
374
+ }
375
+
376
+ /**
377
+ * Load connections from scene data
378
+ * @param {Array} connections - Array of connection objects
379
+ * @private
380
+ */
381
+ }, {
382
+ key: "_loadConnections",
383
+ value: function _loadConnections(connections) {
384
+ var component = this.component;
385
+ if (!component.pathfindingManager) {
386
+ console.warn('⚠️ Cannot load connections: pathfindingManager not available');
387
+ return;
388
+ }
389
+
390
+ // Clear existing connections
391
+ if (component.pathfindingManager.clearAllPaths) {
392
+ component.pathfindingManager.clearAllPaths();
393
+ }
394
+
395
+ // Process each connection
396
+ connections.forEach(function (connection) {
397
+ if (!connection.source || !connection.target) {
398
+ return;
399
+ }
400
+
401
+ // Find source and target objects
402
+ var sourceObj = findObjectByHardcodedUuid(component.scene, connection.source);
403
+ var targetObj = findObjectByHardcodedUuid(component.scene, connection.target);
404
+ if (sourceObj && targetObj) {
405
+ // Create connection if objects found
406
+ component.pathfindingManager.createConnection(sourceObj, targetObj, connection.type || 'default');
407
+ } else {
408
+ console.warn("\u26A0\uFE0F Could not create connection: objects not found (".concat(connection.source, " -> ").concat(connection.target, ")"));
409
+ }
410
+ });
411
+ }
412
+
413
+ /**
414
+ * Find object in scene by name
415
+ * @param {string} name - The name to search for
416
+ * @returns {THREE.Object3D|null} The found object or null
417
+ */
418
+ }, {
419
+ key: "findObjectByName",
420
+ value: function findObjectByName(name) {
421
+ if (!name || !this.component.scene) {
422
+ return null;
423
+ }
424
+ var foundObject = null;
425
+ this.component.scene.traverse(function (child) {
426
+ if (child.name === name) {
427
+ foundObject = child;
428
+ }
429
+ });
430
+ return foundObject;
431
+ }
432
+
433
+ /**
434
+ * Find object in scene by UUID
435
+ * @param {string} uuid - The UUID to search for
436
+ * @returns {THREE.Object3D|null} The found object or null
437
+ */
438
+ }, {
439
+ key: "findObjectByUuid",
440
+ value: function findObjectByUuid(uuid) {
441
+ if (!uuid || !this.component.scene) {
442
+ return null;
443
+ }
444
+ var foundObject = null;
445
+ this.component.scene.traverse(function (child) {
446
+ if (child.uuid === uuid) {
447
+ foundObject = child;
448
+ }
449
+ });
450
+ return foundObject;
451
+ }
452
+
453
+ /**
454
+ * Remove an object from the scene
455
+ * @param {THREE.Object3D} object - The object to remove
456
+ */
457
+ }, {
458
+ key: "removeObject",
459
+ value: function removeObject(object) {
460
+ if (!object || !this.component.scene) {
461
+ return false;
462
+ }
463
+
464
+ // Deselect if this is the selected object
465
+ if (this.component.selectedObjectForTransform === object) {
466
+ this.deselectObject();
467
+ }
468
+
469
+ // Remove from scene
470
+ this.component.scene.remove(object);
471
+
472
+ // Dispose resources
473
+ if (object.geometry) object.geometry.dispose();
474
+ if (object.material) {
475
+ if (Array.isArray(object.material)) {
476
+ object.material.forEach(function (mat) {
477
+ return mat.dispose();
478
+ });
479
+ } else {
480
+ object.material.dispose();
481
+ }
482
+ }
483
+ return true;
484
+ }
485
+
486
+ /**
487
+ * Duplicate an object in the scene
488
+ * @param {THREE.Object3D} sourceObject - The object to duplicate
489
+ * @param {Object} [options] - Options for duplication
490
+ * @param {THREE.Vector3} [options.positionOffset] - Position offset for the duplicate
491
+ * @returns {THREE.Object3D|null} The duplicated object or null if failed
492
+ */
493
+ }, {
494
+ key: "duplicateObject",
495
+ value: function duplicateObject(sourceObject) {
496
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
497
+ if (!sourceObject || !this.component.scene) {
498
+ return null;
499
+ }
500
+
501
+ // Create clone of source object
502
+ var clonedObject = sourceObject.clone();
503
+
504
+ // Generate new UUID to ensure uniqueness
505
+ clonedObject.uuid = THREE.MathUtils.generateUUID();
506
+
507
+ // Update name to indicate it's a copy
508
+ if (!clonedObject.name.includes('_copy')) {
509
+ clonedObject.name = "".concat(clonedObject.name, "_copy");
510
+ }
511
+
512
+ // Apply position offset if specified
513
+ if (options.positionOffset) {
514
+ clonedObject.position.add(options.positionOffset);
515
+ } else {
516
+ // Default offset if none provided
517
+ clonedObject.position.x += 2;
518
+ }
519
+
520
+ // Add to scene
521
+ this.component.scene.add(clonedObject);
522
+ return clonedObject;
523
+ }
524
+ }]);
525
+ }();
526
+
527
+ /**
528
+ * Factory function to get SceneOperationsManager instance
529
+ * @param {CentralPlantComponent} component - The component instance
530
+ * @returns {SceneOperationsManager} SceneOperationsManager instance
531
+ */
532
+ function getSceneOperationsManager(component) {
533
+ return new SceneOperationsManager(component);
534
+ }
535
+
536
+ export { SceneOperationsManager, SceneOperationsManager as default, getSceneOperationsManager };
@@ -0,0 +1,168 @@
1
+ import { asyncToGenerator as _asyncToGenerator, regenerator as _regenerator, objectSpread2 as _objectSpread2 } from '../_virtual/_rollupPluginBabelHelpers.js';
2
+ import * as THREE from 'three';
3
+
4
+ var TEXTURE_SETS = {
5
+ // Light metallic texture using the gravel_embedded_concrete with metallic properties
6
+ light_metal: {
7
+ path: 'https://central-plant-assets.s3.us-east-1.amazonaws.com/textures/gravel_embedded_concrete_1k',
8
+ files: {
9
+ diffuse: 'diffuse.jpg',
10
+ normal: 'normal.jpg',
11
+ roughness: 'rough.jpg'
12
+ },
13
+ repeat: {
14
+ x: 2,
15
+ y: 2
16
+ },
17
+ // Moderate tiling for surface detail
18
+ materialProps: {
19
+ color: 0xb8b8b8,
20
+ // Light metallic base color
21
+ metalness: 0.3,
22
+ roughness: 0.3,
23
+ normalScale: [0.4, 0.4],
24
+ // Subtle surface detail
25
+ clearcoat: 0.3,
26
+ clearcoatRoughness: 0.2,
27
+ envMapIntensity: 1.6,
28
+ reflectivity: 0.5
29
+ }
30
+ },
31
+ brick: {
32
+ path: 'https://central-plant-assets.s3.us-east-1.amazonaws.com/textures/pavement_03_1k',
33
+ files: {
34
+ diffuse: 'diffuse.jpg',
35
+ normal: 'normal.jpg',
36
+ roughness: 'rough.jpg'
37
+ },
38
+ repeat: {
39
+ x: 7.5,
40
+ y: 0.75
41
+ },
42
+ // Adjust for proper brick scale
43
+ materialProps: {
44
+ color: 0x998888,
45
+ roughness: 0.9,
46
+ metalness: 0.1,
47
+ normalScale: [1.5, 1.5],
48
+ bumpScale: 0.05,
49
+ clearcoat: 0.05,
50
+ clearcoatRoughness: 0.4
51
+ }
52
+ },
53
+ gravel_embedded_concrete: {
54
+ path: 'https://central-plant-assets.s3.us-east-1.amazonaws.com/textures/gravel_embedded_concrete_1k',
55
+ files: {
56
+ diffuse: 'diffuse.jpg',
57
+ normal: 'normal.jpg',
58
+ roughness: 'rough.jpg'
59
+ },
60
+ repeat: {
61
+ x: 3,
62
+ y: 3
63
+ },
64
+ materialProps: {
65
+ color: 0xffffff,
66
+ roughness: 0.9,
67
+ metalness: 0.1,
68
+ normalScale: [1.0, 1.0],
69
+ bumpScale: 0.1
70
+ }
71
+ }
72
+ };
73
+
74
+ /**
75
+ * Create a Three.js texture with appropriate settings
76
+ */
77
+ function createTexture(textureLoader, url) {
78
+ var repeat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
79
+ x: 1,
80
+ y: 1
81
+ };
82
+ if (!textureLoader) {
83
+ textureLoader = new THREE.TextureLoader();
84
+ }
85
+ try {
86
+ var texture = textureLoader.load(url);
87
+ texture.wrapS = THREE.RepeatWrapping;
88
+ texture.wrapT = THREE.RepeatWrapping;
89
+ texture.repeat.set(repeat.x, repeat.y);
90
+ texture.colorSpace = THREE.SRGBColorSpace;
91
+ return texture;
92
+ } catch (error) {
93
+ console.error("Failed to load texture: ".concat(url), error);
94
+ return null;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Load a texture set and create a material
100
+ */
101
+ function loadTextureSetAndCreateMaterial(_x, _x2) {
102
+ return _loadTextureSetAndCreateMaterial.apply(this, arguments);
103
+ }
104
+ function _loadTextureSetAndCreateMaterial() {
105
+ _loadTextureSetAndCreateMaterial = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(component, textureSetName) {
106
+ var textureSet, textureLoader, repeat, loadedTextures, loadTexture, material;
107
+ return _regenerator().w(function (_context) {
108
+ while (1) switch (_context.n) {
109
+ case 0:
110
+ if (component) {
111
+ _context.n = 1;
112
+ break;
113
+ }
114
+ console.warn('Component is required for texture loading');
115
+ return _context.a(2, new THREE.MeshStandardMaterial({
116
+ color: 0xaaaaaa
117
+ }));
118
+ case 1:
119
+ textureSet = TEXTURE_SETS[textureSetName];
120
+ if (textureSet) {
121
+ _context.n = 2;
122
+ break;
123
+ }
124
+ console.warn("Texture set not found: ".concat(textureSetName));
125
+ return _context.a(2, new THREE.MeshStandardMaterial({
126
+ color: 0xaaaaaa
127
+ }));
128
+ case 2:
129
+ textureLoader = component.textureLoader || new THREE.TextureLoader();
130
+ repeat = textureSet.repeat || {
131
+ x: 1,
132
+ y: 1
133
+ };
134
+ loadedTextures = {}; // Function to load a specific texture from the set
135
+ loadTexture = function loadTexture(type) {
136
+ if (!textureSet.files[type]) return null;
137
+ var url = "".concat(textureSet.path, "/").concat(textureSet.files[type]);
138
+ return createTexture(textureLoader, url, repeat);
139
+ }; // Load all textures in the set
140
+ Object.keys(textureSet.files).forEach(function (type) {
141
+ loadedTextures[type] = loadTexture(type);
142
+ });
143
+
144
+ // Create material with textures and properties
145
+ material = new THREE.MeshStandardMaterial(_objectSpread2({
146
+ map: loadedTextures.diffuse,
147
+ normalMap: loadedTextures.normal,
148
+ roughnessMap: loadedTextures.roughness,
149
+ metalnessMap: loadedTextures.metalness,
150
+ aoMap: loadedTextures.ao,
151
+ displacementMap: loadedTextures.displacement
152
+ }, textureSet.materialProps)); // Add the environment map if available from the component
153
+ if (component.scene && component.scene.environment) {
154
+ material.envMap = component.scene.environment;
155
+ }
156
+ return _context.a(2, material);
157
+ }
158
+ }, _callee);
159
+ }));
160
+ return _loadTextureSetAndCreateMaterial.apply(this, arguments);
161
+ }
162
+ var textureConfig = {
163
+ TEXTURE_SETS: TEXTURE_SETS,
164
+ createTexture: createTexture,
165
+ loadTextureSetAndCreateMaterial: loadTextureSetAndCreateMaterial
166
+ };
167
+
168
+ export { TEXTURE_SETS, createTexture, textureConfig as default, loadTextureSetAndCreateMaterial };