@2112-lab/central-plant 0.1.78 → 0.1.80

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.
@@ -33,173 +33,88 @@ var EnvironmentManager = /*#__PURE__*/function () {
33
33
  this.sceneViewer = sceneViewer;
34
34
  }
35
35
 
36
+ // ──────────────────────────────────────────────
37
+ // Skybox / environment map
38
+ // ──────────────────────────────────────────────
39
+
36
40
  /**
37
- * Create skybox with HDR environment mapping
41
+ * Create a lightweight procedural sky (default).
42
+ *
43
+ * Builds a gradient-sky sphere + hemisphere light, then bakes a small
44
+ * PMREM environment map for PBR reflections. Total GPU cost is ~1-2 MB
45
+ * compared to ~50-70 MB for the previous HDR pipeline.
38
46
  */
39
47
  return _rollupPluginBabelHelpers.createClass(EnvironmentManager, [{
40
48
  key: "createSkybox",
41
- value: (function () {
49
+ value: function () {
42
50
  var _createSkybox = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee() {
43
- var component, pmremGenerator, loaders, applyEnvironmentMap, _loop, _ret, _i, _loaders, ambientLight, skyScene;
44
- return _rollupPluginBabelHelpers.regenerator().w(function (_context3) {
45
- while (1) switch (_context3.n) {
51
+ var component, _t;
52
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context) {
53
+ while (1) switch (_context.n) {
46
54
  case 0:
47
55
  component = this.sceneViewer;
48
- pmremGenerator = new THREE__namespace.PMREMGenerator(component.renderer);
49
- pmremGenerator.compileEquirectangularShader();
50
- loaders = [{
51
- type: 'hdr',
52
- loader: new RGBELoader.RGBELoader(),
53
- paths: ['/skyboxes/kloofendal_48d_partly_cloudy_puresky_2k.hdr', '/skyboxes/kloofendal_48d_partly_cloudy_puresky_1k.hdr']
54
- }, {
55
- type: 'jpeg',
56
- loader: component.textureLoader,
57
- paths: ['/skyboxes/sky_fallback.jpg']
58
- }];
59
- applyEnvironmentMap = function applyEnvironmentMap(envTexture, type) {
60
- try {
61
- var _component$scene$envi, _component$scene$back;
62
- envTexture.mapping = THREE__namespace.EquirectangularReflectionMapping;
63
- var processedEnvMap = pmremGenerator.fromEquirectangular(envTexture).texture;
64
- if ((_component$scene$envi = component.scene.environment) !== null && _component$scene$envi !== void 0 && _component$scene$envi.dispose) component.scene.environment.dispose();
65
- if ((_component$scene$back = component.scene.background) !== null && _component$scene$back !== void 0 && _component$scene$back.dispose) component.scene.background.dispose();
66
- component.scene.environment = processedEnvMap;
67
- component.scene.background = processedEnvMap;
68
- envTexture.dispose();
69
- console.log("\u2705 ".concat(type.toUpperCase(), " environment map applied successfully"));
70
- return true;
71
- } catch (error) {
72
- console.warn("\u274C Failed to apply ".concat(type, " environment map:"), error);
73
- return false;
74
- }
75
- };
76
- _loop = /*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _loop() {
77
- var _loaders$_i, type, loader, paths, _iterator, _step, _loop2, _ret2, _t2;
78
- return _rollupPluginBabelHelpers.regenerator().w(function (_context2) {
79
- while (1) switch (_context2.n) {
80
- case 0:
81
- _loaders$_i = _loaders[_i], type = _loaders$_i.type, loader = _loaders$_i.loader, paths = _loaders$_i.paths;
82
- _iterator = _rollupPluginBabelHelpers.createForOfIteratorHelper(paths);
83
- _context2.p = 1;
84
- _loop2 = /*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _loop2() {
85
- var path, texture, _t;
86
- return _rollupPluginBabelHelpers.regenerator().w(function (_context) {
87
- while (1) switch (_context.n) {
88
- case 0:
89
- path = _step.value;
90
- _context.p = 1;
91
- console.log("\uD83D\uDD04 Attempting to load ".concat(type.toUpperCase(), ": ").concat(path));
92
- _context.n = 2;
93
- return new Promise(function (resolve, reject) {
94
- var timeout = setTimeout(function () {
95
- return reject(new Error('Timeout'));
96
- }, 10000);
97
- loader.load(path, function (tex) {
98
- clearTimeout(timeout);
99
- resolve(tex);
100
- }, undefined, function (err) {
101
- clearTimeout(timeout);
102
- reject(err);
103
- });
104
- });
105
- case 2:
106
- texture = _context.v;
107
- if (!applyEnvironmentMap(texture, type)) {
108
- _context.n = 3;
109
- break;
110
- }
111
- pmremGenerator.dispose();
112
- return _context.a(2, {
113
- v: {
114
- v: void 0
115
- }
116
- });
117
- case 3:
118
- _context.n = 5;
119
- break;
120
- case 4:
121
- _context.p = 4;
122
- _t = _context.v;
123
- console.warn("\u26A0\uFE0F Failed to load ".concat(path, ":"), _t.message);
124
- case 5:
125
- return _context.a(2);
126
- }
127
- }, _loop2, null, [[1, 4]]);
128
- });
129
- _iterator.s();
130
- case 2:
131
- if ((_step = _iterator.n()).done) {
132
- _context2.n = 5;
133
- break;
134
- }
135
- return _context2.d(_rollupPluginBabelHelpers.regeneratorValues(_loop2()), 3);
136
- case 3:
137
- _ret2 = _context2.v;
138
- if (!_ret2) {
139
- _context2.n = 4;
140
- break;
141
- }
142
- return _context2.a(2, _ret2.v);
143
- case 4:
144
- _context2.n = 2;
145
- break;
146
- case 5:
147
- _context2.n = 7;
148
- break;
149
- case 6:
150
- _context2.p = 6;
151
- _t2 = _context2.v;
152
- _iterator.e(_t2);
153
- case 7:
154
- _context2.p = 7;
155
- _iterator.f();
156
- return _context2.f(7);
157
- case 8:
158
- return _context2.a(2);
159
- }
160
- }, _loop, null, [[1, 6, 7, 8]]);
161
- });
162
- _i = 0, _loaders = loaders;
163
- case 1:
164
- if (!(_i < _loaders.length)) {
165
- _context3.n = 4;
166
- break;
167
- }
168
- return _context3.d(_rollupPluginBabelHelpers.regeneratorValues(_loop()), 2);
56
+ _context.p = 1;
57
+ _context.n = 2;
58
+ return this._applyProceduralSky(component);
169
59
  case 2:
170
- _ret = _context3.v;
171
- if (!_ret) {
172
- _context3.n = 3;
173
- break;
174
- }
175
- return _context3.a(2, _ret.v);
176
- case 3:
177
- _i++;
178
- _context3.n = 1;
60
+ console.log('✅ Procedural sky environment applied');
61
+ _context.n = 4;
179
62
  break;
63
+ case 3:
64
+ _context.p = 3;
65
+ _t = _context.v;
66
+ console.warn('⚠️ Procedural sky failed, applying plain color fallback:', _t);
67
+ this.setColorBackground();
180
68
  case 4:
181
- console.log('🎨 Using procedural sky fallback');
182
- ambientLight = new THREE__namespace.AmbientLight(0xffffff, 0.6);
183
- component.scene.add(ambientLight);
184
- skyScene = new THREE__namespace.Scene(); // Create hemisphere light with Z-up orientation - sky color up, ground color down
185
- skyScene.add(new THREE__namespace.HemisphereLight(0x87CEEB, 0x444477, 1));
186
- component.scene.environment = pmremGenerator.fromScene(skyScene).texture;
187
- component.scene.background = new THREE__namespace.Color(0x87CEEB);
188
- pmremGenerator.dispose();
189
- case 5:
190
- return _context3.a(2);
69
+ return _context.a(2);
191
70
  }
192
- }, _callee, this);
71
+ }, _callee, this, [[1, 3]]);
193
72
  }));
194
73
  function createSkybox() {
195
74
  return _createSkybox.apply(this, arguments);
196
75
  }
197
76
  return createSkybox;
198
77
  }()
78
+ /**
79
+ * Build a procedural sky environment.
80
+ *
81
+ * Uses two separate, lightweight resources:
82
+ * - **Background**: Canvas-rendered gradient texture mapped as equirectangular
83
+ * (512 × 256 px ≈ 0.5 MB GPU).
84
+ * - **Environment**: PMREM baked from a HemisphereLight scene for PBR IBL
85
+ * reflections (~1 MB GPU).
86
+ *
87
+ * Custom ShaderMaterials are intentionally avoided inside the PMREM pipeline
88
+ * because `PMREMGenerator.fromScene()` uses its own cube-face cameras that
89
+ * can produce black output with non-standard shaders.
90
+ * @private
91
+ */
92
+ }, {
93
+ key: "_applyProceduralSky",
94
+ value: function _applyProceduralSky(component) {
95
+ var _component$scene$envi, _component$scene$back;
96
+ // Dispose of existing textures
97
+ if ((_component$scene$envi = component.scene.environment) !== null && _component$scene$envi !== void 0 && _component$scene$envi.dispose) component.scene.environment.dispose();
98
+ if ((_component$scene$back = component.scene.background) !== null && _component$scene$back !== void 0 && _component$scene$back.dispose) component.scene.background.dispose();
99
+
100
+ // ── 1. Solid-colour background ──────────────────────────────────────────
101
+ // A plain THREE.Color is coordinate-system agnostic (no equirectangular
102
+ // mapping that assumes Y-up), cheap (zero GPU textures), and looks clean.
103
+ component.scene.background = new THREE__namespace.Color(0xbcddeb); // light sky blue
104
+
105
+ // ── 2. PMREM env-map from HemisphereLight for PBR IBL reflections ───────
106
+ // Intensity must be high enough to light MeshPhysicalMaterial surfaces
107
+ // that the directional lights don't reach evenly (wall backs, crevices).
108
+ var pmremGenerator = new THREE__namespace.PMREMGenerator(component.renderer);
109
+ var lightScene = new THREE__namespace.Scene();
110
+ lightScene.add(new THREE__namespace.HemisphereLight(0xbcddeb, 0x444477, 3.0));
111
+ component.scene.environment = pmremGenerator.fromScene(lightScene).texture;
112
+ pmremGenerator.dispose();
113
+ }
114
+
199
115
  /**
200
116
  * Setup scene lighting
201
117
  */
202
- )
203
118
  }, {
204
119
  key: "setupLighting",
205
120
  value: function setupLighting() {
@@ -225,15 +140,27 @@ var EnvironmentManager = /*#__PURE__*/function () {
225
140
  component.scene.add(sunLight);
226
141
  // component.scene.add(sunLight.target)
227
142
 
228
- // // Ambient hemispheric light
229
- // const ambientLight = new THREE.HemisphereLight(0xffffff, 0x444466, 0.35)
230
- // component.scene.add(ambientLight)
143
+ // Flat ambient light – ensures no surface is ever fully black regardless
144
+ // of orientation. Low intensity so it doesn't wash out lit surfaces.
145
+ var flatAmbient = new THREE__namespace.AmbientLight(0xffffff, 1.0);
146
+ component.scene.add(flatAmbient);
147
+
148
+ // Hemispheric ambient – adds sky/ground colour tint on surfaces the
149
+ // directional lights miss (essential without an HDR environment map).
150
+ var ambientLight = new THREE__namespace.HemisphereLight(0xffffff, 0x444466, 1.0);
151
+ component.scene.add(ambientLight);
231
152
 
232
153
  // Fill light (secondary directional light) - adjusted for Z-up coordinate system with flipped Y
233
- var fillLight = new THREE__namespace.DirectionalLight(0xffffff, 2.0);
154
+ var fillLight = new THREE__namespace.DirectionalLight(0xffffff, 3.0);
234
155
  fillLight.position.set(10, -10, 10); // X=-10, Y=-10 (flipped), Z=10 (up in Z-up system)
235
156
  component.scene.add(fillLight);
236
157
 
158
+ // Back-fill light – illuminates rear-facing walls and equipment backs
159
+ // that the sun and primary fill can't reach.
160
+ var backFillLight = new THREE__namespace.DirectionalLight(0xddeeff, 3.0);
161
+ backFillLight.position.set(-10, 10, 8);
162
+ component.scene.add(backFillLight);
163
+
237
164
  // // Rim light (for edge definition)
238
165
  // const rimLight = new THREE.DirectionalLight(0xffffff, 0.9)
239
166
  // rimLight.position.set(0, 0, -20)
@@ -262,9 +189,9 @@ var EnvironmentManager = /*#__PURE__*/function () {
262
189
  key: "addTexturedGround",
263
190
  value: (function () {
264
191
  var _addTexturedGround = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee2() {
265
- var component, groundSize, groundGeometry, groundMaterial, ground, texturedMaterial, _t3;
266
- return _rollupPluginBabelHelpers.regenerator().w(function (_context4) {
267
- while (1) switch (_context4.n) {
192
+ var component, groundSize, groundGeometry, groundMaterial, ground, texturedMaterial, _t2;
193
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context2) {
194
+ while (1) switch (_context2.n) {
268
195
  case 0:
269
196
  component = this.sceneViewer;
270
197
  console.debug('Starting addTexturedGround...');
@@ -283,23 +210,23 @@ var EnvironmentManager = /*#__PURE__*/function () {
283
210
  ground.uuid = 'GROUND'; // Set UUID to match JSON data structure
284
211
  ground.userData.isBaseGround = true;
285
212
  component.scene.add(ground);
286
- _context4.p = 1;
213
+ _context2.p = 1;
287
214
  console.debug('Loading concrete texture set...');
288
- _context4.n = 2;
215
+ _context2.n = 2;
289
216
  return textureConfig.loadTextureSetAndCreateMaterial('gravel_embedded_concrete', component.textureLoader);
290
217
  case 2:
291
- texturedMaterial = _context4.v;
218
+ texturedMaterial = _context2.v;
292
219
  ground.material = texturedMaterial;
293
220
  ground.material.needsUpdate = true;
294
221
  console.log('✅ Ground material updated with textures');
295
- _context4.n = 4;
222
+ _context2.n = 4;
296
223
  break;
297
224
  case 3:
298
- _context4.p = 3;
299
- _t3 = _context4.v;
300
- console.warn('Error loading ground textures:', _t3);
225
+ _context2.p = 3;
226
+ _t2 = _context2.v;
227
+ console.warn('Error loading ground textures:', _t2);
301
228
  case 4:
302
- return _context4.a(2);
229
+ return _context2.a(2);
303
230
  }
304
231
  }, _callee2, this, [[1, 3]]);
305
232
  }));
@@ -316,9 +243,9 @@ var EnvironmentManager = /*#__PURE__*/function () {
316
243
  key: "addBrickWalls",
317
244
  value: (function () {
318
245
  var _addBrickWalls = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee3() {
319
- var component, wallHeight, wallThickness, groundSize, halfGroundSize, brickMaterial, createWalls, texturedBrickMaterial, _t4;
320
- return _rollupPluginBabelHelpers.regenerator().w(function (_context5) {
321
- while (1) switch (_context5.n) {
246
+ var component, wallHeight, wallThickness, groundSize, halfGroundSize, brickMaterial, createWalls, texturedBrickMaterial, _t3;
247
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context3) {
248
+ while (1) switch (_context3.n) {
322
249
  case 0:
323
250
  component = this.sceneViewer;
324
251
  console.debug('Starting addBrickWalls...');
@@ -420,12 +347,12 @@ var EnvironmentManager = /*#__PURE__*/function () {
420
347
  };
421
348
  createWalls(brickMaterial);
422
349
  console.debug('Basic brick walls created');
423
- _context5.p = 1;
350
+ _context3.p = 1;
424
351
  console.debug('Loading brick texture set...');
425
- _context5.n = 2;
352
+ _context3.n = 2;
426
353
  return textureConfig.loadTextureSetAndCreateMaterial('brick', component.textureLoader);
427
354
  case 2:
428
- texturedBrickMaterial = _context5.v;
355
+ texturedBrickMaterial = _context3.v;
429
356
  component.scene.traverse(function (object) {
430
357
  if (object.isMesh && object.userData.isBrickWall) {
431
358
  object.material = texturedBrickMaterial;
@@ -433,14 +360,14 @@ var EnvironmentManager = /*#__PURE__*/function () {
433
360
  }
434
361
  });
435
362
  console.log('✅ Brick walls updated with textures');
436
- _context5.n = 4;
363
+ _context3.n = 4;
437
364
  break;
438
365
  case 3:
439
- _context5.p = 3;
440
- _t4 = _context5.v;
441
- console.warn('Error loading brick textures:', _t4);
366
+ _context3.p = 3;
367
+ _t3 = _context3.v;
368
+ console.warn('Error loading brick textures:', _t3);
442
369
  case 4:
443
- return _context5.a(2);
370
+ return _context3.a(2);
444
371
  }
445
372
  }, _callee3, this, [[1, 3]]);
446
373
  }));
@@ -489,23 +416,23 @@ var EnvironmentManager = /*#__PURE__*/function () {
489
416
  key: "initializeEnvironment",
490
417
  value: (function () {
491
418
  var _initializeEnvironment = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee4() {
492
- return _rollupPluginBabelHelpers.regenerator().w(function (_context6) {
493
- while (1) switch (_context6.n) {
419
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context4) {
420
+ while (1) switch (_context4.n) {
494
421
  case 0:
495
- _context6.n = 1;
422
+ _context4.n = 1;
496
423
  return this.createSkybox();
497
424
  case 1:
498
425
  this.setupLighting();
499
- _context6.n = 2;
426
+ _context4.n = 2;
500
427
  return this.addTexturedGround();
501
428
  case 2:
502
- _context6.n = 3;
429
+ _context4.n = 3;
503
430
  return this.addBrickWalls();
504
431
  case 3:
505
432
  this.addHorizonFog();
506
433
  console.log('Environment initialization completed');
507
434
  case 4:
508
- return _context6.a(2);
435
+ return _context4.a(2);
509
436
  }
510
437
  }, _callee4, this);
511
438
  }));
@@ -546,60 +473,50 @@ var EnvironmentManager = /*#__PURE__*/function () {
546
473
 
547
474
  /**
548
475
  * Set the skybox type dynamically
549
- * @param {string} skyboxType - 'HDR', 'Fallback', or 'Color'
476
+ * @param {'Procedural'|'HDR'|'Color'} skyboxType
550
477
  */
551
478
  }, {
552
479
  key: "setSkyboxType",
553
480
  value: (function () {
554
481
  var _setSkyboxType = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee5(skyboxType) {
555
- var component, _component$scene$envi3, _component$scene$back3, _pmremGenerator, _t5, _t6;
556
- return _rollupPluginBabelHelpers.regenerator().w(function (_context7) {
557
- while (1) switch (_context7.n) {
482
+ var component, _component$scene$envi3, _component$scene$back3, _t4, _t5;
483
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context5) {
484
+ while (1) switch (_context5.n) {
558
485
  case 0:
559
486
  component = this.sceneViewer;
560
- _context7.p = 1;
487
+ _context5.p = 1;
561
488
  console.log("\uD83C\uDF0C Changing skybox type to: ".concat(skyboxType));
562
489
 
563
490
  // Dispose of current environment textures
564
- if ((_component$scene$envi3 = component.scene.environment) !== null && _component$scene$envi3 !== void 0 && _component$scene$envi3.dispose) {
565
- component.scene.environment.dispose();
566
- }
567
- if ((_component$scene$back3 = component.scene.background) !== null && _component$scene$back3 !== void 0 && _component$scene$back3.dispose) {
568
- component.scene.background.dispose();
569
- }
570
- _pmremGenerator = new THREE__namespace.PMREMGenerator(component.renderer);
571
- _pmremGenerator.compileEquirectangularShader();
572
- _t5 = skyboxType;
573
- _context7.n = _t5 === 'HDR' ? 2 : _t5 === 'Fallback' ? 4 : _t5 === 'Color' ? 6 : 7;
491
+ if ((_component$scene$envi3 = component.scene.environment) !== null && _component$scene$envi3 !== void 0 && _component$scene$envi3.dispose) component.scene.environment.dispose();
492
+ if ((_component$scene$back3 = component.scene.background) !== null && _component$scene$back3 !== void 0 && _component$scene$back3.dispose) component.scene.background.dispose();
493
+ _t4 = skyboxType;
494
+ _context5.n = _t4 === 'Procedural' ? 2 : _t4 === 'HDR' ? 3 : _t4 === 'Color' ? 5 : 6;
574
495
  break;
575
496
  case 2:
576
- _context7.n = 3;
577
- return this.loadHDRSkybox(_pmremGenerator);
497
+ this._applyProceduralSky(component);
498
+ return _context5.a(3, 7);
578
499
  case 3:
579
- return _context7.a(3, 8);
500
+ _context5.n = 4;
501
+ return this._loadHDRSkybox(component);
580
502
  case 4:
581
- _context7.n = 5;
582
- return this.loadFallbackSkybox(_pmremGenerator);
503
+ return _context5.a(3, 7);
583
504
  case 5:
584
- return _context7.a(3, 8);
505
+ this._setColorBackground(component);
506
+ return _context5.a(3, 7);
585
507
  case 6:
586
- this.setColorBackground();
587
- return _context7.a(3, 8);
508
+ console.warn("Unknown skybox type: ".concat(skyboxType, ", using Procedural"));
509
+ this._applyProceduralSky(component);
588
510
  case 7:
589
- console.warn("Unknown skybox type: ".concat(skyboxType, ", falling back to HDR"));
590
- _context7.n = 8;
591
- return this.loadHDRSkybox(_pmremGenerator);
511
+ console.log("\u2705 Skybox type changed to: ".concat(skyboxType));
512
+ return _context5.a(2, true);
592
513
  case 8:
593
- _pmremGenerator.dispose();
594
- console.log("Skybox type changed to: ".concat(skyboxType));
595
- return _context7.a(2, true);
596
- case 9:
597
- _context7.p = 9;
598
- _t6 = _context7.v;
599
- console.error('❌ Error setting skybox type:', _t6);
600
- return _context7.a(2, false);
514
+ _context5.p = 8;
515
+ _t5 = _context5.v;
516
+ console.error('❌ Error setting skybox type:', _t5);
517
+ return _context5.a(2, false);
601
518
  }
602
- }, _callee5, this, [[1, 9]]);
519
+ }, _callee5, this, [[1, 8]]);
603
520
  }));
604
521
  function setSkyboxType(_x) {
605
522
  return _setSkyboxType.apply(this, arguments);
@@ -607,29 +524,34 @@ var EnvironmentManager = /*#__PURE__*/function () {
607
524
  return setSkyboxType;
608
525
  }()
609
526
  /**
610
- * Load HDR skybox specifically
527
+ * Load HDR skybox on demand (high quality, high memory).
528
+ * Tries 1k first to save memory; falls back to color on failure.
529
+ * @private
611
530
  */
612
531
  )
613
532
  }, {
614
- key: "loadHDRSkybox",
533
+ key: "_loadHDRSkybox",
615
534
  value: (function () {
616
- var _loadHDRSkybox = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee6(pmremGenerator) {
617
- var component, rgbeLoader, hdrPaths, _loop3, _ret3, _i2, _hdrPaths;
618
- return _rollupPluginBabelHelpers.regenerator().w(function (_context9) {
619
- while (1) switch (_context9.n) {
535
+ var _loadHDRSkybox2 = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee6(component) {
536
+ var rgbeLoader, pmremGenerator, hdrPaths, _loop, _ret, _i, _hdrPaths;
537
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context7) {
538
+ while (1) switch (_context7.n) {
620
539
  case 0:
621
- component = this.sceneViewer;
622
540
  rgbeLoader = new RGBELoader.RGBELoader();
623
- hdrPaths = ['/skyboxes/kloofendal_48d_partly_cloudy_puresky_2k.hdr', '/skyboxes/kloofendal_48d_partly_cloudy_puresky_1k.hdr'];
624
- _loop3 = /*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _loop3() {
625
- var path, texture, processedEnvMap, _t7;
626
- return _rollupPluginBabelHelpers.regenerator().w(function (_context8) {
627
- while (1) switch (_context8.n) {
541
+ pmremGenerator = new THREE__namespace.PMREMGenerator(component.renderer);
542
+ pmremGenerator.compileEquirectangularShader();
543
+
544
+ // Prefer the 1k variant (~20 MB GPU) over 2k (~50 MB GPU)
545
+ hdrPaths = ['/skyboxes/kloofendal_48d_partly_cloudy_puresky_1k.hdr', '/skyboxes/kloofendal_48d_partly_cloudy_puresky_2k.hdr'];
546
+ _loop = /*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _loop() {
547
+ var path, texture, processedEnvMap, _t6;
548
+ return _rollupPluginBabelHelpers.regenerator().w(function (_context6) {
549
+ while (1) switch (_context6.n) {
628
550
  case 0:
629
- path = _hdrPaths[_i2];
630
- _context8.p = 1;
551
+ path = _hdrPaths[_i];
552
+ _context6.p = 1;
631
553
  console.log("\uD83D\uDD04 Loading HDR: ".concat(path));
632
- _context8.n = 2;
554
+ _context6.n = 2;
633
555
  return new Promise(function (resolve, reject) {
634
556
  var timeout = setTimeout(function () {
635
557
  return reject(new Error('Timeout'));
@@ -643,123 +565,79 @@ var EnvironmentManager = /*#__PURE__*/function () {
643
565
  });
644
566
  });
645
567
  case 2:
646
- texture = _context8.v;
568
+ texture = _context6.v;
647
569
  texture.mapping = THREE__namespace.EquirectangularReflectionMapping;
648
570
  processedEnvMap = pmremGenerator.fromEquirectangular(texture).texture;
649
571
  component.scene.environment = processedEnvMap;
650
572
  component.scene.background = processedEnvMap;
651
573
  texture.dispose();
574
+ pmremGenerator.dispose();
652
575
  console.log('✅ HDR skybox loaded successfully');
653
- return _context8.a(2, {
576
+ return _context6.a(2, {
654
577
  v: void 0
655
578
  });
656
579
  case 3:
657
- _context8.p = 3;
658
- _t7 = _context8.v;
659
- console.warn("\u26A0\uFE0F Failed to load HDR skybox ".concat(path, ":"), _t7.message);
580
+ _context6.p = 3;
581
+ _t6 = _context6.v;
582
+ console.warn("\u26A0\uFE0F Failed to load HDR skybox ".concat(path, ":"), _t6.message);
660
583
  case 4:
661
- return _context8.a(2);
584
+ return _context6.a(2);
662
585
  }
663
- }, _loop3, null, [[1, 3]]);
586
+ }, _loop, null, [[1, 3]]);
664
587
  });
665
- _i2 = 0, _hdrPaths = hdrPaths;
588
+ _i = 0, _hdrPaths = hdrPaths;
666
589
  case 1:
667
- if (!(_i2 < _hdrPaths.length)) {
668
- _context9.n = 4;
590
+ if (!(_i < _hdrPaths.length)) {
591
+ _context7.n = 4;
669
592
  break;
670
593
  }
671
- return _context9.d(_rollupPluginBabelHelpers.regeneratorValues(_loop3()), 2);
594
+ return _context7.d(_rollupPluginBabelHelpers.regeneratorValues(_loop()), 2);
672
595
  case 2:
673
- _ret3 = _context9.v;
674
- if (!_ret3) {
675
- _context9.n = 3;
596
+ _ret = _context7.v;
597
+ if (!_ret) {
598
+ _context7.n = 3;
676
599
  break;
677
600
  }
678
- return _context9.a(2, _ret3.v);
601
+ return _context7.a(2, _ret.v);
679
602
  case 3:
680
- _i2++;
681
- _context9.n = 1;
603
+ _i++;
604
+ _context7.n = 1;
682
605
  break;
683
606
  case 4:
607
+ pmremGenerator.dispose();
684
608
  throw new Error('Failed to load any HDR skybox');
685
609
  case 5:
686
- return _context9.a(2);
610
+ return _context7.a(2);
687
611
  }
688
- }, _callee6, this);
612
+ }, _callee6);
689
613
  }));
690
- function loadHDRSkybox(_x2) {
691
- return _loadHDRSkybox.apply(this, arguments);
614
+ function _loadHDRSkybox(_x2) {
615
+ return _loadHDRSkybox2.apply(this, arguments);
692
616
  }
693
- return loadHDRSkybox;
617
+ return _loadHDRSkybox;
694
618
  }()
695
619
  /**
696
- * Load fallback JPEG skybox
620
+ * Set solid color background with basic ambient lighting.
621
+ * @private
697
622
  */
698
623
  )
699
624
  }, {
700
- key: "loadFallbackSkybox",
701
- value: (function () {
702
- var _loadFallbackSkybox = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee7(pmremGenerator) {
703
- var component, texture, processedEnvMap, _t8;
704
- return _rollupPluginBabelHelpers.regenerator().w(function (_context0) {
705
- while (1) switch (_context0.n) {
706
- case 0:
707
- component = this.sceneViewer;
708
- _context0.p = 1;
709
- console.log('🔄 Loading fallback skybox');
710
- _context0.n = 2;
711
- return new Promise(function (resolve, reject) {
712
- var timeout = setTimeout(function () {
713
- return reject(new Error('Timeout'));
714
- }, 10000);
715
- component.textureLoader.load('/skyboxes/sky_fallback.jpg', function (tex) {
716
- clearTimeout(timeout);
717
- resolve(tex);
718
- }, undefined, function (err) {
719
- clearTimeout(timeout);
720
- reject(err);
721
- });
722
- });
723
- case 2:
724
- texture = _context0.v;
725
- texture.mapping = THREE__namespace.EquirectangularReflectionMapping;
726
- processedEnvMap = pmremGenerator.fromEquirectangular(texture).texture;
727
- component.scene.environment = processedEnvMap;
728
- component.scene.background = processedEnvMap;
729
- texture.dispose();
730
- console.log('✅ Fallback skybox loaded successfully');
731
- _context0.n = 4;
732
- break;
733
- case 3:
734
- _context0.p = 3;
735
- _t8 = _context0.v;
736
- console.warn('⚠️ Failed to load fallback skybox:', _t8.message);
737
- throw _t8;
738
- case 4:
739
- return _context0.a(2);
740
- }
741
- }, _callee7, this, [[1, 3]]);
742
- }));
743
- function loadFallbackSkybox(_x3) {
744
- return _loadFallbackSkybox.apply(this, arguments);
745
- }
746
- return loadFallbackSkybox;
747
- }()
625
+ key: "_setColorBackground",
626
+ value: function _setColorBackground(component) {
627
+ component.scene.environment = null;
628
+ component.scene.background = new THREE__namespace.Color(0xffffff);
629
+ var ambientLight = new THREE__namespace.AmbientLight(0xffffff, 0.6);
630
+ component.scene.add(ambientLight);
631
+ console.log('✅ Color background set successfully');
632
+ }
633
+
748
634
  /**
749
- * Set solid color background
635
+ * Public convenience alias for setColorBackground (backwards compat)
750
636
  */
751
- )
752
637
  }, {
753
638
  key: "setColorBackground",
754
639
  value: function setColorBackground() {
755
- var component = this.sceneViewer;
756
- component.scene.environment = null;
757
- component.scene.background = new THREE__namespace.Color(0xffffff); // White background
758
-
759
- // Add basic ambient lighting since we don't have environment lighting
760
- var ambientLight = new THREE__namespace.AmbientLight(0xffffff, 0.6);
761
- component.scene.add(ambientLight);
762
- console.log('✅ Color background set successfully');
640
+ this._setColorBackground(this.sceneViewer);
763
641
  }
764
642
  }]);
765
643
  }();