@2112-lab/central-plant 0.1.94 → 0.1.96
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.
- package/dist/bundle/index.js +79 -27
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/behaviors/BehaviorManager.js +9 -0
- package/dist/cjs/src/managers/environment/environmentManager.js +6 -8
- package/dist/cjs/src/managers/scene/modelManager.js +7 -3
- package/dist/cjs/src/managers/scene/sceneOperationsManager.js +56 -15
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/behaviors/BehaviorManager.js +9 -0
- package/dist/esm/src/managers/environment/environmentManager.js +6 -8
- package/dist/esm/src/managers/scene/modelManager.js +7 -3
- package/dist/esm/src/managers/scene/sceneOperationsManager.js +56 -15
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -25184,8 +25184,8 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
25184
25184
|
case 0:
|
|
25185
25185
|
component = this.sceneViewer;
|
|
25186
25186
|
console.debug('Starting addTexturedGround...');
|
|
25187
|
-
groundSize =
|
|
25188
|
-
groundGeometry = new THREE__namespace.
|
|
25187
|
+
groundSize = 90;
|
|
25188
|
+
groundGeometry = new THREE__namespace.CircleGeometry(groundSize / 2, 16);
|
|
25189
25189
|
groundMaterial = new THREE__namespace.MeshStandardMaterial({
|
|
25190
25190
|
color: 0x777777,
|
|
25191
25191
|
metalness: 0.2,
|
|
@@ -25373,7 +25373,7 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
25373
25373
|
key: "addHorizonFog",
|
|
25374
25374
|
value: function addHorizonFog() {
|
|
25375
25375
|
var component = this.sceneViewer;
|
|
25376
|
-
var groundSize =
|
|
25376
|
+
var groundSize = 60;
|
|
25377
25377
|
var fogSize = groundSize * 10;
|
|
25378
25378
|
var fogMaterial = new THREE__namespace.ShaderMaterial({
|
|
25379
25379
|
transparent: true,
|
|
@@ -25392,7 +25392,7 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
25392
25392
|
var fogGeometry = new THREE__namespace.PlaneGeometry(fogSize, fogSize);
|
|
25393
25393
|
var fogPlane = new THREE__namespace.Mesh(fogGeometry, fogMaterial);
|
|
25394
25394
|
fogPlane.rotation.x = 0; // No rotation needed for Z-up coordinate system
|
|
25395
|
-
fogPlane.position.z = -
|
|
25395
|
+
fogPlane.position.z = -8.0; // Position fog plane below ground level
|
|
25396
25396
|
fogPlane.name = "fogPlane";
|
|
25397
25397
|
component.scene.add(fogPlane);
|
|
25398
25398
|
return fogPlane;
|
|
@@ -25415,12 +25415,10 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
25415
25415
|
_context4.n = 2;
|
|
25416
25416
|
return this.addTexturedGround();
|
|
25417
25417
|
case 2:
|
|
25418
|
-
|
|
25419
|
-
return this.addBrickWalls();
|
|
25420
|
-
case 3:
|
|
25418
|
+
// await this.addBrickWalls()
|
|
25421
25419
|
this.addHorizonFog();
|
|
25422
25420
|
console.log('Environment initialization completed');
|
|
25423
|
-
case
|
|
25421
|
+
case 3:
|
|
25424
25422
|
return _context4.a(2);
|
|
25425
25423
|
}
|
|
25426
25424
|
}, _callee4, this);
|
|
@@ -28581,6 +28579,15 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
28581
28579
|
value: function _applyAction(object, propertyPath, value) {
|
|
28582
28580
|
if (!object || typeof propertyPath !== 'string') return;
|
|
28583
28581
|
var parts = propertyPath.split('.');
|
|
28582
|
+
|
|
28583
|
+
// Clone shared material onto this mesh before mutating any material property.
|
|
28584
|
+
// Three.js reuses the same Material instance across all meshes loaded from the
|
|
28585
|
+
// same GLB, so without cloning a color/emissive change would bleed to every
|
|
28586
|
+
// other component instance that shares the model.
|
|
28587
|
+
if (parts[0] === 'material' && object.isMesh && object.material && !object.userData._behaviorMaterialCloned) {
|
|
28588
|
+
object.material = object.material.clone();
|
|
28589
|
+
object.userData._behaviorMaterialCloned = true;
|
|
28590
|
+
}
|
|
28584
28591
|
var target = object;
|
|
28585
28592
|
for (var i = 0; i < parts.length - 1; i++) {
|
|
28586
28593
|
if (target == null) {
|
|
@@ -28897,9 +28904,13 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
28897
28904
|
var _this = this;
|
|
28898
28905
|
var connectorChildren = [];
|
|
28899
28906
|
targetMesh.children.forEach(function (child, index) {
|
|
28907
|
+
var _child$userData;
|
|
28900
28908
|
var isConnectorGeometry = child.geometry && (child.geometry.uuid === 'CONNECTOR-GEO' || child.geometry.type === 'SphereGeometry' && child.geometry.parameters);
|
|
28901
28909
|
var isConnectorByName = child.name && child.name.toLowerCase().includes('connector');
|
|
28902
|
-
|
|
28910
|
+
// Also recognise connectors declared via userData (e.g. inline connectors from SAMPLE_1.json
|
|
28911
|
+
// whose geometry may be a fallback BufferGeometry rather than a SphereGeometry).
|
|
28912
|
+
var isConnectorByUserData = ((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'connector';
|
|
28913
|
+
if (isConnectorGeometry && isConnectorByName || isConnectorByUserData) {
|
|
28903
28914
|
// Ensure userData exists and has worldBoundingBox
|
|
28904
28915
|
if (!child.userData) child.userData = {};
|
|
28905
28916
|
if (!child.userData.worldBoundingBox) {
|
|
@@ -29183,8 +29194,8 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
29183
29194
|
requiredModels = new Set();
|
|
29184
29195
|
console.log("\uD83D\uDD0D Checking ".concat(data.scene.children.length, " scene objects for required models..."));
|
|
29185
29196
|
data.scene.children.forEach(function (child) {
|
|
29186
|
-
var _child$
|
|
29187
|
-
var libraryId = (_child$
|
|
29197
|
+
var _child$userData2;
|
|
29198
|
+
var libraryId = (_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.libraryId;
|
|
29188
29199
|
if (libraryId) {
|
|
29189
29200
|
if (componentDictionary[libraryId]) {
|
|
29190
29201
|
var modelKey = componentDictionary[libraryId].modelKey;
|
|
@@ -30239,6 +30250,24 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
30239
30250
|
}
|
|
30240
30251
|
}
|
|
30241
30252
|
});
|
|
30253
|
+
|
|
30254
|
+
// Ensure CONNECTOR_GATEWAY_SPHERE exists even when all connectors are nested inside
|
|
30255
|
+
// component children (e.g. SAMPLE_1.json inline connector definitions). Without
|
|
30256
|
+
// this geometry the connector meshes fall back to empty BufferGeometry, which then
|
|
30257
|
+
// causes _preserveConnectorChildren to drop them during GLB model replacement.
|
|
30258
|
+
if (!geometries['CONNECTOR_GATEWAY_SPHERE']) {
|
|
30259
|
+
var hasNestedConnectors = data.scene.children.some(function (child) {
|
|
30260
|
+
var _child$userData3;
|
|
30261
|
+
return ((_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType) === 'component' && Array.isArray(child.children) && child.children.some(function (nestedChild) {
|
|
30262
|
+
var _nestedChild$userData;
|
|
30263
|
+
return ((_nestedChild$userData = nestedChild.userData) === null || _nestedChild$userData === void 0 ? void 0 : _nestedChild$userData.objectType) === 'connector';
|
|
30264
|
+
});
|
|
30265
|
+
});
|
|
30266
|
+
if (hasNestedConnectors) {
|
|
30267
|
+
geometries['CONNECTOR_GATEWAY_SPHERE'] = new THREE__namespace.SphereGeometry(0.1, 16, 16);
|
|
30268
|
+
console.log('🔮 Created shared sphere geometry for nested inline connectors (radius: 0.1)');
|
|
30269
|
+
}
|
|
30270
|
+
}
|
|
30242
30271
|
return geometries;
|
|
30243
30272
|
}
|
|
30244
30273
|
|
|
@@ -30624,12 +30653,12 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
30624
30653
|
_step;
|
|
30625
30654
|
try {
|
|
30626
30655
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
30627
|
-
var _object$userData, _child$
|
|
30656
|
+
var _object$userData, _child$userData4;
|
|
30628
30657
|
var child = _step.value;
|
|
30629
30658
|
// Enhanced matching logic with hardcoded UUID priority
|
|
30630
30659
|
|
|
30631
30660
|
// Strategy 1: Direct hardcoded UUID match (HIGHEST PRIORITY)
|
|
30632
|
-
if (child.uuid === object.uuid || child.uuid === ((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.originalUuid) || object.uuid === ((_child$
|
|
30661
|
+
if (child.uuid === object.uuid || child.uuid === ((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.originalUuid) || object.uuid === ((_child$userData4 = child.userData) === null || _child$userData4 === void 0 ? void 0 : _child$userData4.originalUuid)) {
|
|
30633
30662
|
return child;
|
|
30634
30663
|
}
|
|
30635
30664
|
|
|
@@ -30888,10 +30917,10 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
30888
30917
|
var componentsProcessed = 0;
|
|
30889
30918
|
var connectorsInjected = 0;
|
|
30890
30919
|
data.scene.children.forEach(function (child) {
|
|
30891
|
-
var _child$
|
|
30892
|
-
var childType = ((_child$
|
|
30920
|
+
var _child$userData5, _child$userData6, _child$userData7;
|
|
30921
|
+
var childType = ((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.objectType) || ((_child$userData6 = child.userData) === null || _child$userData6 === void 0 ? void 0 : _child$userData6.objectType);
|
|
30893
30922
|
// Only process components with libraryId
|
|
30894
|
-
if (childType === 'component' && (_child$
|
|
30923
|
+
if (childType === 'component' && (_child$userData7 = child.userData) !== null && _child$userData7 !== void 0 && _child$userData7.libraryId) {
|
|
30895
30924
|
var libraryId = child.userData.libraryId;
|
|
30896
30925
|
var dictEntry = componentDictionary[libraryId];
|
|
30897
30926
|
|
|
@@ -31048,17 +31077,17 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31048
31077
|
geometries = this.createSceneGeometries(data, componentDictionary); // Create basic objects and track GLB replacements
|
|
31049
31078
|
libraryObjectsToReplace = [];
|
|
31050
31079
|
data.scene.children.forEach(function (child, index) {
|
|
31051
|
-
var _child$
|
|
31080
|
+
var _child$userData8, _child$userData9;
|
|
31052
31081
|
var createdObject = _this4.createSceneObject(child, geometries, materials, componentDictionary);
|
|
31053
31082
|
_this4.sceneViewer.scene.add(createdObject);
|
|
31054
31083
|
|
|
31055
31084
|
// Track objects that need GLB model replacement
|
|
31056
|
-
if ((_child$
|
|
31057
|
-
var _child$
|
|
31085
|
+
if ((_child$userData8 = child.userData) !== null && _child$userData8 !== void 0 && _child$userData8.libraryId && componentDictionary[(_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.libraryId]) {
|
|
31086
|
+
var _child$userData0;
|
|
31058
31087
|
libraryObjectsToReplace.push({
|
|
31059
31088
|
basicObject: createdObject,
|
|
31060
31089
|
jsonData: child,
|
|
31061
|
-
componentData: componentDictionary[(_child$
|
|
31090
|
+
componentData: componentDictionary[(_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.libraryId]
|
|
31062
31091
|
});
|
|
31063
31092
|
}
|
|
31064
31093
|
});
|
|
@@ -31179,6 +31208,19 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31179
31208
|
return b.id;
|
|
31180
31209
|
}));
|
|
31181
31210
|
|
|
31211
|
+
// Build a set of (component::attachment::state) tuples covered by explicit
|
|
31212
|
+
// behaviors. If an expanded default behavior would produce the SAME input
|
|
31213
|
+
// tuple, the explicit behavior is treated as the intentional override and
|
|
31214
|
+
// the default expansion is skipped. This prevents a component's built-in
|
|
31215
|
+
// switch→LED wiring from doubling-up when the user has deliberately authored
|
|
31216
|
+
// cross-component behaviors that re-wire the same switch.
|
|
31217
|
+
var explicitInputTuples = new Set(explicitBehaviors.filter(function (b) {
|
|
31218
|
+
var _b$input, _b$input2, _b$input3;
|
|
31219
|
+
return ((_b$input = b.input) === null || _b$input === void 0 ? void 0 : _b$input.component) && ((_b$input2 = b.input) === null || _b$input2 === void 0 ? void 0 : _b$input2.attachment) && ((_b$input3 = b.input) === null || _b$input3 === void 0 ? void 0 : _b$input3.state);
|
|
31220
|
+
}).map(function (b) {
|
|
31221
|
+
return "".concat(b.input.component, "::").concat(b.input.attachment, "::").concat(b.input.state);
|
|
31222
|
+
}));
|
|
31223
|
+
|
|
31182
31224
|
// Build a set of instanceUuids already covered by behaviorRef entries in
|
|
31183
31225
|
// data.behaviors (written by the exporter for smart component defaults).
|
|
31184
31226
|
// Step B skips these instances to avoid loading the same behaviors twice —
|
|
@@ -31197,8 +31239,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31197
31239
|
var instanceBehaviors = [];
|
|
31198
31240
|
if (Array.isArray(data === null || data === void 0 || (_data$scene3 = data.scene) === null || _data$scene3 === void 0 ? void 0 : _data$scene3.children)) {
|
|
31199
31241
|
data.scene.children.forEach(function (child) {
|
|
31200
|
-
var _child$
|
|
31201
|
-
var libraryId = (_child$
|
|
31242
|
+
var _child$userData1, _compData$defaultBeha;
|
|
31243
|
+
var libraryId = (_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.libraryId;
|
|
31202
31244
|
if (!libraryId) return;
|
|
31203
31245
|
var instanceUuid = child.uuid;
|
|
31204
31246
|
// Skip instances whose defaults were already resolved by Step A
|
|
@@ -31207,10 +31249,20 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31207
31249
|
var compData = componentDictionary[libraryId];
|
|
31208
31250
|
if (!(compData !== null && compData !== void 0 && (_compData$defaultBeha = compData.defaultBehaviors) !== null && _compData$defaultBeha !== void 0 && _compData$defaultBeha.length)) return;
|
|
31209
31251
|
compData.defaultBehaviors.forEach(function (template) {
|
|
31252
|
+
var _expanded$input, _expanded$input2, _expanded$input3;
|
|
31210
31253
|
var expanded = _this5._expandDefaultBehavior(template, instanceUuid, componentDictionary);
|
|
31211
31254
|
if (!expanded) return;
|
|
31212
31255
|
// Skip if an explicit scene behavior already covers this id
|
|
31213
31256
|
if (explicitIds.has(expanded.id)) return;
|
|
31257
|
+
// Skip if an explicit scene behavior already covers the same
|
|
31258
|
+
// (component, attachment, state) input tuple. This prevents a
|
|
31259
|
+
// component's built-in default wiring (e.g. switch → own LED) from
|
|
31260
|
+
// double-firing when the user has authored a cross-component override
|
|
31261
|
+
// that rewires the same switch to a different target.
|
|
31262
|
+
if ((_expanded$input = expanded.input) !== null && _expanded$input !== void 0 && _expanded$input.component && (_expanded$input2 = expanded.input) !== null && _expanded$input2 !== void 0 && _expanded$input2.attachment && (_expanded$input3 = expanded.input) !== null && _expanded$input3 !== void 0 && _expanded$input3.state) {
|
|
31263
|
+
var tuple = "".concat(expanded.input.component, "::").concat(expanded.input.attachment, "::").concat(expanded.input.state);
|
|
31264
|
+
if (explicitInputTuples.has(tuple)) return;
|
|
31265
|
+
}
|
|
31214
31266
|
// All component defaultBehaviors are re-derivable from the component
|
|
31215
31267
|
// asset at export time (via compact behaviorRef), so mark them all.
|
|
31216
31268
|
expanded._isDefaultBehavior = true;
|
|
@@ -31589,8 +31641,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31589
31641
|
// Process children (connectors, etc.) if they exist
|
|
31590
31642
|
if (componentModel.children && componentModel.children.length > 0) {
|
|
31591
31643
|
componentModel.children.forEach(function (child) {
|
|
31592
|
-
var _child$
|
|
31593
|
-
var childType = ((_child$
|
|
31644
|
+
var _child$userData10, _child$userData11;
|
|
31645
|
+
var childType = ((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType) || ((_child$userData11 = child.userData) === null || _child$userData11 === void 0 ? void 0 : _child$userData11.objectType);
|
|
31594
31646
|
if (childType === 'connector') {
|
|
31595
31647
|
var _child$geometry;
|
|
31596
31648
|
var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
|
|
@@ -31675,8 +31727,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31675
31727
|
if (segment.children && segment.children.length > 0) {
|
|
31676
31728
|
var childrenToRemove = _toConsumableArray(segment.children);
|
|
31677
31729
|
childrenToRemove.forEach(function (child) {
|
|
31678
|
-
var _child$
|
|
31679
|
-
if ((_child$
|
|
31730
|
+
var _child$userData12;
|
|
31731
|
+
if ((_child$userData12 = child.userData) !== null && _child$userData12 !== void 0 && _child$userData12.isPipeElbow) {
|
|
31680
31732
|
console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
|
|
31681
31733
|
segment.remove(child);
|
|
31682
31734
|
if (child.geometry) child.geometry.dispose();
|
|
@@ -37181,7 +37233,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
37181
37233
|
* Initialize the CentralPlant manager
|
|
37182
37234
|
*
|
|
37183
37235
|
* @constructor
|
|
37184
|
-
* @version 0.1.
|
|
37236
|
+
* @version 0.1.96
|
|
37185
37237
|
* @updated 2025-10-22
|
|
37186
37238
|
*
|
|
37187
37239
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -19,7 +19,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
19
19
|
* Initialize the CentralPlant manager
|
|
20
20
|
*
|
|
21
21
|
* @constructor
|
|
22
|
-
* @version 0.1.
|
|
22
|
+
* @version 0.1.96
|
|
23
23
|
* @updated 2025-10-22
|
|
24
24
|
*
|
|
25
25
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -344,6 +344,15 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
344
344
|
value: function _applyAction(object, propertyPath, value) {
|
|
345
345
|
if (!object || typeof propertyPath !== 'string') return;
|
|
346
346
|
var parts = propertyPath.split('.');
|
|
347
|
+
|
|
348
|
+
// Clone shared material onto this mesh before mutating any material property.
|
|
349
|
+
// Three.js reuses the same Material instance across all meshes loaded from the
|
|
350
|
+
// same GLB, so without cloning a color/emissive change would bleed to every
|
|
351
|
+
// other component instance that shares the model.
|
|
352
|
+
if (parts[0] === 'material' && object.isMesh && object.material && !object.userData._behaviorMaterialCloned) {
|
|
353
|
+
object.material = object.material.clone();
|
|
354
|
+
object.userData._behaviorMaterialCloned = true;
|
|
355
|
+
}
|
|
347
356
|
var target = object;
|
|
348
357
|
for (var i = 0; i < parts.length - 1; i++) {
|
|
349
358
|
if (target == null) {
|
|
@@ -195,8 +195,8 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
195
195
|
case 0:
|
|
196
196
|
component = this.sceneViewer;
|
|
197
197
|
console.debug('Starting addTexturedGround...');
|
|
198
|
-
groundSize =
|
|
199
|
-
groundGeometry = new THREE__namespace.
|
|
198
|
+
groundSize = 90;
|
|
199
|
+
groundGeometry = new THREE__namespace.CircleGeometry(groundSize / 2, 16);
|
|
200
200
|
groundMaterial = new THREE__namespace.MeshStandardMaterial({
|
|
201
201
|
color: 0x777777,
|
|
202
202
|
metalness: 0.2,
|
|
@@ -384,7 +384,7 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
384
384
|
key: "addHorizonFog",
|
|
385
385
|
value: function addHorizonFog() {
|
|
386
386
|
var component = this.sceneViewer;
|
|
387
|
-
var groundSize =
|
|
387
|
+
var groundSize = 60;
|
|
388
388
|
var fogSize = groundSize * 10;
|
|
389
389
|
var fogMaterial = new THREE__namespace.ShaderMaterial({
|
|
390
390
|
transparent: true,
|
|
@@ -403,7 +403,7 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
403
403
|
var fogGeometry = new THREE__namespace.PlaneGeometry(fogSize, fogSize);
|
|
404
404
|
var fogPlane = new THREE__namespace.Mesh(fogGeometry, fogMaterial);
|
|
405
405
|
fogPlane.rotation.x = 0; // No rotation needed for Z-up coordinate system
|
|
406
|
-
fogPlane.position.z = -
|
|
406
|
+
fogPlane.position.z = -8.0; // Position fog plane below ground level
|
|
407
407
|
fogPlane.name = "fogPlane";
|
|
408
408
|
component.scene.add(fogPlane);
|
|
409
409
|
return fogPlane;
|
|
@@ -426,12 +426,10 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
426
426
|
_context4.n = 2;
|
|
427
427
|
return this.addTexturedGround();
|
|
428
428
|
case 2:
|
|
429
|
-
|
|
430
|
-
return this.addBrickWalls();
|
|
431
|
-
case 3:
|
|
429
|
+
// await this.addBrickWalls()
|
|
432
430
|
this.addHorizonFog();
|
|
433
431
|
console.log('Environment initialization completed');
|
|
434
|
-
case
|
|
432
|
+
case 3:
|
|
435
433
|
return _context4.a(2);
|
|
436
434
|
}
|
|
437
435
|
}, _callee4, this);
|
|
@@ -146,9 +146,13 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
146
146
|
var _this = this;
|
|
147
147
|
var connectorChildren = [];
|
|
148
148
|
targetMesh.children.forEach(function (child, index) {
|
|
149
|
+
var _child$userData;
|
|
149
150
|
var isConnectorGeometry = child.geometry && (child.geometry.uuid === 'CONNECTOR-GEO' || child.geometry.type === 'SphereGeometry' && child.geometry.parameters);
|
|
150
151
|
var isConnectorByName = child.name && child.name.toLowerCase().includes('connector');
|
|
151
|
-
|
|
152
|
+
// Also recognise connectors declared via userData (e.g. inline connectors from SAMPLE_1.json
|
|
153
|
+
// whose geometry may be a fallback BufferGeometry rather than a SphereGeometry).
|
|
154
|
+
var isConnectorByUserData = ((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'connector';
|
|
155
|
+
if (isConnectorGeometry && isConnectorByName || isConnectorByUserData) {
|
|
152
156
|
// Ensure userData exists and has worldBoundingBox
|
|
153
157
|
if (!child.userData) child.userData = {};
|
|
154
158
|
if (!child.userData.worldBoundingBox) {
|
|
@@ -432,8 +436,8 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
432
436
|
requiredModels = new Set();
|
|
433
437
|
console.log("\uD83D\uDD0D Checking ".concat(data.scene.children.length, " scene objects for required models..."));
|
|
434
438
|
data.scene.children.forEach(function (child) {
|
|
435
|
-
var _child$
|
|
436
|
-
var libraryId = (_child$
|
|
439
|
+
var _child$userData2;
|
|
440
|
+
var libraryId = (_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.libraryId;
|
|
437
441
|
if (libraryId) {
|
|
438
442
|
if (componentDictionary[libraryId]) {
|
|
439
443
|
var modelKey = componentDictionary[libraryId].modelKey;
|
|
@@ -261,6 +261,24 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
});
|
|
264
|
+
|
|
265
|
+
// Ensure CONNECTOR_GATEWAY_SPHERE exists even when all connectors are nested inside
|
|
266
|
+
// component children (e.g. SAMPLE_1.json inline connector definitions). Without
|
|
267
|
+
// this geometry the connector meshes fall back to empty BufferGeometry, which then
|
|
268
|
+
// causes _preserveConnectorChildren to drop them during GLB model replacement.
|
|
269
|
+
if (!geometries['CONNECTOR_GATEWAY_SPHERE']) {
|
|
270
|
+
var hasNestedConnectors = data.scene.children.some(function (child) {
|
|
271
|
+
var _child$userData3;
|
|
272
|
+
return ((_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType) === 'component' && Array.isArray(child.children) && child.children.some(function (nestedChild) {
|
|
273
|
+
var _nestedChild$userData;
|
|
274
|
+
return ((_nestedChild$userData = nestedChild.userData) === null || _nestedChild$userData === void 0 ? void 0 : _nestedChild$userData.objectType) === 'connector';
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
if (hasNestedConnectors) {
|
|
278
|
+
geometries['CONNECTOR_GATEWAY_SPHERE'] = new THREE__namespace.SphereGeometry(0.1, 16, 16);
|
|
279
|
+
console.log('🔮 Created shared sphere geometry for nested inline connectors (radius: 0.1)');
|
|
280
|
+
}
|
|
281
|
+
}
|
|
264
282
|
return geometries;
|
|
265
283
|
}
|
|
266
284
|
|
|
@@ -646,12 +664,12 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
646
664
|
_step;
|
|
647
665
|
try {
|
|
648
666
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
649
|
-
var _object$userData, _child$
|
|
667
|
+
var _object$userData, _child$userData4;
|
|
650
668
|
var child = _step.value;
|
|
651
669
|
// Enhanced matching logic with hardcoded UUID priority
|
|
652
670
|
|
|
653
671
|
// Strategy 1: Direct hardcoded UUID match (HIGHEST PRIORITY)
|
|
654
|
-
if (child.uuid === object.uuid || child.uuid === ((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.originalUuid) || object.uuid === ((_child$
|
|
672
|
+
if (child.uuid === object.uuid || child.uuid === ((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.originalUuid) || object.uuid === ((_child$userData4 = child.userData) === null || _child$userData4 === void 0 ? void 0 : _child$userData4.originalUuid)) {
|
|
655
673
|
return child;
|
|
656
674
|
}
|
|
657
675
|
|
|
@@ -910,10 +928,10 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
910
928
|
var componentsProcessed = 0;
|
|
911
929
|
var connectorsInjected = 0;
|
|
912
930
|
data.scene.children.forEach(function (child) {
|
|
913
|
-
var _child$
|
|
914
|
-
var childType = ((_child$
|
|
931
|
+
var _child$userData5, _child$userData6, _child$userData7;
|
|
932
|
+
var childType = ((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.objectType) || ((_child$userData6 = child.userData) === null || _child$userData6 === void 0 ? void 0 : _child$userData6.objectType);
|
|
915
933
|
// Only process components with libraryId
|
|
916
|
-
if (childType === 'component' && (_child$
|
|
934
|
+
if (childType === 'component' && (_child$userData7 = child.userData) !== null && _child$userData7 !== void 0 && _child$userData7.libraryId) {
|
|
917
935
|
var libraryId = child.userData.libraryId;
|
|
918
936
|
var dictEntry = componentDictionary[libraryId];
|
|
919
937
|
|
|
@@ -1070,17 +1088,17 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1070
1088
|
geometries = this.createSceneGeometries(data, componentDictionary); // Create basic objects and track GLB replacements
|
|
1071
1089
|
libraryObjectsToReplace = [];
|
|
1072
1090
|
data.scene.children.forEach(function (child, index) {
|
|
1073
|
-
var _child$
|
|
1091
|
+
var _child$userData8, _child$userData9;
|
|
1074
1092
|
var createdObject = _this4.createSceneObject(child, geometries, materials, componentDictionary);
|
|
1075
1093
|
_this4.sceneViewer.scene.add(createdObject);
|
|
1076
1094
|
|
|
1077
1095
|
// Track objects that need GLB model replacement
|
|
1078
|
-
if ((_child$
|
|
1079
|
-
var _child$
|
|
1096
|
+
if ((_child$userData8 = child.userData) !== null && _child$userData8 !== void 0 && _child$userData8.libraryId && componentDictionary[(_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.libraryId]) {
|
|
1097
|
+
var _child$userData0;
|
|
1080
1098
|
libraryObjectsToReplace.push({
|
|
1081
1099
|
basicObject: createdObject,
|
|
1082
1100
|
jsonData: child,
|
|
1083
|
-
componentData: componentDictionary[(_child$
|
|
1101
|
+
componentData: componentDictionary[(_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.libraryId]
|
|
1084
1102
|
});
|
|
1085
1103
|
}
|
|
1086
1104
|
});
|
|
@@ -1201,6 +1219,19 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1201
1219
|
return b.id;
|
|
1202
1220
|
}));
|
|
1203
1221
|
|
|
1222
|
+
// Build a set of (component::attachment::state) tuples covered by explicit
|
|
1223
|
+
// behaviors. If an expanded default behavior would produce the SAME input
|
|
1224
|
+
// tuple, the explicit behavior is treated as the intentional override and
|
|
1225
|
+
// the default expansion is skipped. This prevents a component's built-in
|
|
1226
|
+
// switch→LED wiring from doubling-up when the user has deliberately authored
|
|
1227
|
+
// cross-component behaviors that re-wire the same switch.
|
|
1228
|
+
var explicitInputTuples = new Set(explicitBehaviors.filter(function (b) {
|
|
1229
|
+
var _b$input, _b$input2, _b$input3;
|
|
1230
|
+
return ((_b$input = b.input) === null || _b$input === void 0 ? void 0 : _b$input.component) && ((_b$input2 = b.input) === null || _b$input2 === void 0 ? void 0 : _b$input2.attachment) && ((_b$input3 = b.input) === null || _b$input3 === void 0 ? void 0 : _b$input3.state);
|
|
1231
|
+
}).map(function (b) {
|
|
1232
|
+
return "".concat(b.input.component, "::").concat(b.input.attachment, "::").concat(b.input.state);
|
|
1233
|
+
}));
|
|
1234
|
+
|
|
1204
1235
|
// Build a set of instanceUuids already covered by behaviorRef entries in
|
|
1205
1236
|
// data.behaviors (written by the exporter for smart component defaults).
|
|
1206
1237
|
// Step B skips these instances to avoid loading the same behaviors twice —
|
|
@@ -1219,8 +1250,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1219
1250
|
var instanceBehaviors = [];
|
|
1220
1251
|
if (Array.isArray(data === null || data === void 0 || (_data$scene3 = data.scene) === null || _data$scene3 === void 0 ? void 0 : _data$scene3.children)) {
|
|
1221
1252
|
data.scene.children.forEach(function (child) {
|
|
1222
|
-
var _child$
|
|
1223
|
-
var libraryId = (_child$
|
|
1253
|
+
var _child$userData1, _compData$defaultBeha;
|
|
1254
|
+
var libraryId = (_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.libraryId;
|
|
1224
1255
|
if (!libraryId) return;
|
|
1225
1256
|
var instanceUuid = child.uuid;
|
|
1226
1257
|
// Skip instances whose defaults were already resolved by Step A
|
|
@@ -1229,10 +1260,20 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1229
1260
|
var compData = componentDictionary[libraryId];
|
|
1230
1261
|
if (!(compData !== null && compData !== void 0 && (_compData$defaultBeha = compData.defaultBehaviors) !== null && _compData$defaultBeha !== void 0 && _compData$defaultBeha.length)) return;
|
|
1231
1262
|
compData.defaultBehaviors.forEach(function (template) {
|
|
1263
|
+
var _expanded$input, _expanded$input2, _expanded$input3;
|
|
1232
1264
|
var expanded = _this5._expandDefaultBehavior(template, instanceUuid, componentDictionary);
|
|
1233
1265
|
if (!expanded) return;
|
|
1234
1266
|
// Skip if an explicit scene behavior already covers this id
|
|
1235
1267
|
if (explicitIds.has(expanded.id)) return;
|
|
1268
|
+
// Skip if an explicit scene behavior already covers the same
|
|
1269
|
+
// (component, attachment, state) input tuple. This prevents a
|
|
1270
|
+
// component's built-in default wiring (e.g. switch → own LED) from
|
|
1271
|
+
// double-firing when the user has authored a cross-component override
|
|
1272
|
+
// that rewires the same switch to a different target.
|
|
1273
|
+
if ((_expanded$input = expanded.input) !== null && _expanded$input !== void 0 && _expanded$input.component && (_expanded$input2 = expanded.input) !== null && _expanded$input2 !== void 0 && _expanded$input2.attachment && (_expanded$input3 = expanded.input) !== null && _expanded$input3 !== void 0 && _expanded$input3.state) {
|
|
1274
|
+
var tuple = "".concat(expanded.input.component, "::").concat(expanded.input.attachment, "::").concat(expanded.input.state);
|
|
1275
|
+
if (explicitInputTuples.has(tuple)) return;
|
|
1276
|
+
}
|
|
1236
1277
|
// All component defaultBehaviors are re-derivable from the component
|
|
1237
1278
|
// asset at export time (via compact behaviorRef), so mark them all.
|
|
1238
1279
|
expanded._isDefaultBehavior = true;
|
|
@@ -1611,8 +1652,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1611
1652
|
// Process children (connectors, etc.) if they exist
|
|
1612
1653
|
if (componentModel.children && componentModel.children.length > 0) {
|
|
1613
1654
|
componentModel.children.forEach(function (child) {
|
|
1614
|
-
var _child$
|
|
1615
|
-
var childType = ((_child$
|
|
1655
|
+
var _child$userData10, _child$userData11;
|
|
1656
|
+
var childType = ((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType) || ((_child$userData11 = child.userData) === null || _child$userData11 === void 0 ? void 0 : _child$userData11.objectType);
|
|
1616
1657
|
if (childType === 'connector') {
|
|
1617
1658
|
var _child$geometry;
|
|
1618
1659
|
var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
|
|
@@ -1697,8 +1738,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1697
1738
|
if (segment.children && segment.children.length > 0) {
|
|
1698
1739
|
var childrenToRemove = _rollupPluginBabelHelpers.toConsumableArray(segment.children);
|
|
1699
1740
|
childrenToRemove.forEach(function (child) {
|
|
1700
|
-
var _child$
|
|
1701
|
-
if ((_child$
|
|
1741
|
+
var _child$userData12;
|
|
1742
|
+
if ((_child$userData12 = child.userData) !== null && _child$userData12 !== void 0 && _child$userData12.isPipeElbow) {
|
|
1702
1743
|
console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
|
|
1703
1744
|
segment.remove(child);
|
|
1704
1745
|
if (child.geometry) child.geometry.dispose();
|
|
@@ -15,7 +15,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
15
15
|
* Initialize the CentralPlant manager
|
|
16
16
|
*
|
|
17
17
|
* @constructor
|
|
18
|
-
* @version 0.1.
|
|
18
|
+
* @version 0.1.96
|
|
19
19
|
* @updated 2025-10-22
|
|
20
20
|
*
|
|
21
21
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -340,6 +340,15 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
340
340
|
value: function _applyAction(object, propertyPath, value) {
|
|
341
341
|
if (!object || typeof propertyPath !== 'string') return;
|
|
342
342
|
var parts = propertyPath.split('.');
|
|
343
|
+
|
|
344
|
+
// Clone shared material onto this mesh before mutating any material property.
|
|
345
|
+
// Three.js reuses the same Material instance across all meshes loaded from the
|
|
346
|
+
// same GLB, so without cloning a color/emissive change would bleed to every
|
|
347
|
+
// other component instance that shares the model.
|
|
348
|
+
if (parts[0] === 'material' && object.isMesh && object.material && !object.userData._behaviorMaterialCloned) {
|
|
349
|
+
object.material = object.material.clone();
|
|
350
|
+
object.userData._behaviorMaterialCloned = true;
|
|
351
|
+
}
|
|
343
352
|
var target = object;
|
|
344
353
|
for (var i = 0; i < parts.length - 1; i++) {
|
|
345
354
|
if (target == null) {
|
|
@@ -171,8 +171,8 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
171
171
|
case 0:
|
|
172
172
|
component = this.sceneViewer;
|
|
173
173
|
console.debug('Starting addTexturedGround...');
|
|
174
|
-
groundSize =
|
|
175
|
-
groundGeometry = new THREE.
|
|
174
|
+
groundSize = 90;
|
|
175
|
+
groundGeometry = new THREE.CircleGeometry(groundSize / 2, 16);
|
|
176
176
|
groundMaterial = new THREE.MeshStandardMaterial({
|
|
177
177
|
color: 0x777777,
|
|
178
178
|
metalness: 0.2,
|
|
@@ -360,7 +360,7 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
360
360
|
key: "addHorizonFog",
|
|
361
361
|
value: function addHorizonFog() {
|
|
362
362
|
var component = this.sceneViewer;
|
|
363
|
-
var groundSize =
|
|
363
|
+
var groundSize = 60;
|
|
364
364
|
var fogSize = groundSize * 10;
|
|
365
365
|
var fogMaterial = new THREE.ShaderMaterial({
|
|
366
366
|
transparent: true,
|
|
@@ -379,7 +379,7 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
379
379
|
var fogGeometry = new THREE.PlaneGeometry(fogSize, fogSize);
|
|
380
380
|
var fogPlane = new THREE.Mesh(fogGeometry, fogMaterial);
|
|
381
381
|
fogPlane.rotation.x = 0; // No rotation needed for Z-up coordinate system
|
|
382
|
-
fogPlane.position.z = -
|
|
382
|
+
fogPlane.position.z = -8.0; // Position fog plane below ground level
|
|
383
383
|
fogPlane.name = "fogPlane";
|
|
384
384
|
component.scene.add(fogPlane);
|
|
385
385
|
return fogPlane;
|
|
@@ -402,12 +402,10 @@ var EnvironmentManager = /*#__PURE__*/function () {
|
|
|
402
402
|
_context4.n = 2;
|
|
403
403
|
return this.addTexturedGround();
|
|
404
404
|
case 2:
|
|
405
|
-
|
|
406
|
-
return this.addBrickWalls();
|
|
407
|
-
case 3:
|
|
405
|
+
// await this.addBrickWalls()
|
|
408
406
|
this.addHorizonFog();
|
|
409
407
|
console.log('Environment initialization completed');
|
|
410
|
-
case
|
|
408
|
+
case 3:
|
|
411
409
|
return _context4.a(2);
|
|
412
410
|
}
|
|
413
411
|
}, _callee4, this);
|
|
@@ -122,9 +122,13 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
122
122
|
var _this = this;
|
|
123
123
|
var connectorChildren = [];
|
|
124
124
|
targetMesh.children.forEach(function (child, index) {
|
|
125
|
+
var _child$userData;
|
|
125
126
|
var isConnectorGeometry = child.geometry && (child.geometry.uuid === 'CONNECTOR-GEO' || child.geometry.type === 'SphereGeometry' && child.geometry.parameters);
|
|
126
127
|
var isConnectorByName = child.name && child.name.toLowerCase().includes('connector');
|
|
127
|
-
|
|
128
|
+
// Also recognise connectors declared via userData (e.g. inline connectors from SAMPLE_1.json
|
|
129
|
+
// whose geometry may be a fallback BufferGeometry rather than a SphereGeometry).
|
|
130
|
+
var isConnectorByUserData = ((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'connector';
|
|
131
|
+
if (isConnectorGeometry && isConnectorByName || isConnectorByUserData) {
|
|
128
132
|
// Ensure userData exists and has worldBoundingBox
|
|
129
133
|
if (!child.userData) child.userData = {};
|
|
130
134
|
if (!child.userData.worldBoundingBox) {
|
|
@@ -408,8 +412,8 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
408
412
|
requiredModels = new Set();
|
|
409
413
|
console.log("\uD83D\uDD0D Checking ".concat(data.scene.children.length, " scene objects for required models..."));
|
|
410
414
|
data.scene.children.forEach(function (child) {
|
|
411
|
-
var _child$
|
|
412
|
-
var libraryId = (_child$
|
|
415
|
+
var _child$userData2;
|
|
416
|
+
var libraryId = (_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.libraryId;
|
|
413
417
|
if (libraryId) {
|
|
414
418
|
if (componentDictionary[libraryId]) {
|
|
415
419
|
var modelKey = componentDictionary[libraryId].modelKey;
|
|
@@ -237,6 +237,24 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
});
|
|
240
|
+
|
|
241
|
+
// Ensure CONNECTOR_GATEWAY_SPHERE exists even when all connectors are nested inside
|
|
242
|
+
// component children (e.g. SAMPLE_1.json inline connector definitions). Without
|
|
243
|
+
// this geometry the connector meshes fall back to empty BufferGeometry, which then
|
|
244
|
+
// causes _preserveConnectorChildren to drop them during GLB model replacement.
|
|
245
|
+
if (!geometries['CONNECTOR_GATEWAY_SPHERE']) {
|
|
246
|
+
var hasNestedConnectors = data.scene.children.some(function (child) {
|
|
247
|
+
var _child$userData3;
|
|
248
|
+
return ((_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType) === 'component' && Array.isArray(child.children) && child.children.some(function (nestedChild) {
|
|
249
|
+
var _nestedChild$userData;
|
|
250
|
+
return ((_nestedChild$userData = nestedChild.userData) === null || _nestedChild$userData === void 0 ? void 0 : _nestedChild$userData.objectType) === 'connector';
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
if (hasNestedConnectors) {
|
|
254
|
+
geometries['CONNECTOR_GATEWAY_SPHERE'] = new THREE.SphereGeometry(0.1, 16, 16);
|
|
255
|
+
console.log('🔮 Created shared sphere geometry for nested inline connectors (radius: 0.1)');
|
|
256
|
+
}
|
|
257
|
+
}
|
|
240
258
|
return geometries;
|
|
241
259
|
}
|
|
242
260
|
|
|
@@ -622,12 +640,12 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
622
640
|
_step;
|
|
623
641
|
try {
|
|
624
642
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
625
|
-
var _object$userData, _child$
|
|
643
|
+
var _object$userData, _child$userData4;
|
|
626
644
|
var child = _step.value;
|
|
627
645
|
// Enhanced matching logic with hardcoded UUID priority
|
|
628
646
|
|
|
629
647
|
// Strategy 1: Direct hardcoded UUID match (HIGHEST PRIORITY)
|
|
630
|
-
if (child.uuid === object.uuid || child.uuid === ((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.originalUuid) || object.uuid === ((_child$
|
|
648
|
+
if (child.uuid === object.uuid || child.uuid === ((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.originalUuid) || object.uuid === ((_child$userData4 = child.userData) === null || _child$userData4 === void 0 ? void 0 : _child$userData4.originalUuid)) {
|
|
631
649
|
return child;
|
|
632
650
|
}
|
|
633
651
|
|
|
@@ -886,10 +904,10 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
886
904
|
var componentsProcessed = 0;
|
|
887
905
|
var connectorsInjected = 0;
|
|
888
906
|
data.scene.children.forEach(function (child) {
|
|
889
|
-
var _child$
|
|
890
|
-
var childType = ((_child$
|
|
907
|
+
var _child$userData5, _child$userData6, _child$userData7;
|
|
908
|
+
var childType = ((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.objectType) || ((_child$userData6 = child.userData) === null || _child$userData6 === void 0 ? void 0 : _child$userData6.objectType);
|
|
891
909
|
// Only process components with libraryId
|
|
892
|
-
if (childType === 'component' && (_child$
|
|
910
|
+
if (childType === 'component' && (_child$userData7 = child.userData) !== null && _child$userData7 !== void 0 && _child$userData7.libraryId) {
|
|
893
911
|
var libraryId = child.userData.libraryId;
|
|
894
912
|
var dictEntry = componentDictionary[libraryId];
|
|
895
913
|
|
|
@@ -1046,17 +1064,17 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1046
1064
|
geometries = this.createSceneGeometries(data, componentDictionary); // Create basic objects and track GLB replacements
|
|
1047
1065
|
libraryObjectsToReplace = [];
|
|
1048
1066
|
data.scene.children.forEach(function (child, index) {
|
|
1049
|
-
var _child$
|
|
1067
|
+
var _child$userData8, _child$userData9;
|
|
1050
1068
|
var createdObject = _this4.createSceneObject(child, geometries, materials, componentDictionary);
|
|
1051
1069
|
_this4.sceneViewer.scene.add(createdObject);
|
|
1052
1070
|
|
|
1053
1071
|
// Track objects that need GLB model replacement
|
|
1054
|
-
if ((_child$
|
|
1055
|
-
var _child$
|
|
1072
|
+
if ((_child$userData8 = child.userData) !== null && _child$userData8 !== void 0 && _child$userData8.libraryId && componentDictionary[(_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.libraryId]) {
|
|
1073
|
+
var _child$userData0;
|
|
1056
1074
|
libraryObjectsToReplace.push({
|
|
1057
1075
|
basicObject: createdObject,
|
|
1058
1076
|
jsonData: child,
|
|
1059
|
-
componentData: componentDictionary[(_child$
|
|
1077
|
+
componentData: componentDictionary[(_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.libraryId]
|
|
1060
1078
|
});
|
|
1061
1079
|
}
|
|
1062
1080
|
});
|
|
@@ -1177,6 +1195,19 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1177
1195
|
return b.id;
|
|
1178
1196
|
}));
|
|
1179
1197
|
|
|
1198
|
+
// Build a set of (component::attachment::state) tuples covered by explicit
|
|
1199
|
+
// behaviors. If an expanded default behavior would produce the SAME input
|
|
1200
|
+
// tuple, the explicit behavior is treated as the intentional override and
|
|
1201
|
+
// the default expansion is skipped. This prevents a component's built-in
|
|
1202
|
+
// switch→LED wiring from doubling-up when the user has deliberately authored
|
|
1203
|
+
// cross-component behaviors that re-wire the same switch.
|
|
1204
|
+
var explicitInputTuples = new Set(explicitBehaviors.filter(function (b) {
|
|
1205
|
+
var _b$input, _b$input2, _b$input3;
|
|
1206
|
+
return ((_b$input = b.input) === null || _b$input === void 0 ? void 0 : _b$input.component) && ((_b$input2 = b.input) === null || _b$input2 === void 0 ? void 0 : _b$input2.attachment) && ((_b$input3 = b.input) === null || _b$input3 === void 0 ? void 0 : _b$input3.state);
|
|
1207
|
+
}).map(function (b) {
|
|
1208
|
+
return "".concat(b.input.component, "::").concat(b.input.attachment, "::").concat(b.input.state);
|
|
1209
|
+
}));
|
|
1210
|
+
|
|
1180
1211
|
// Build a set of instanceUuids already covered by behaviorRef entries in
|
|
1181
1212
|
// data.behaviors (written by the exporter for smart component defaults).
|
|
1182
1213
|
// Step B skips these instances to avoid loading the same behaviors twice —
|
|
@@ -1195,8 +1226,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1195
1226
|
var instanceBehaviors = [];
|
|
1196
1227
|
if (Array.isArray(data === null || data === void 0 || (_data$scene3 = data.scene) === null || _data$scene3 === void 0 ? void 0 : _data$scene3.children)) {
|
|
1197
1228
|
data.scene.children.forEach(function (child) {
|
|
1198
|
-
var _child$
|
|
1199
|
-
var libraryId = (_child$
|
|
1229
|
+
var _child$userData1, _compData$defaultBeha;
|
|
1230
|
+
var libraryId = (_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.libraryId;
|
|
1200
1231
|
if (!libraryId) return;
|
|
1201
1232
|
var instanceUuid = child.uuid;
|
|
1202
1233
|
// Skip instances whose defaults were already resolved by Step A
|
|
@@ -1205,10 +1236,20 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1205
1236
|
var compData = componentDictionary[libraryId];
|
|
1206
1237
|
if (!(compData !== null && compData !== void 0 && (_compData$defaultBeha = compData.defaultBehaviors) !== null && _compData$defaultBeha !== void 0 && _compData$defaultBeha.length)) return;
|
|
1207
1238
|
compData.defaultBehaviors.forEach(function (template) {
|
|
1239
|
+
var _expanded$input, _expanded$input2, _expanded$input3;
|
|
1208
1240
|
var expanded = _this5._expandDefaultBehavior(template, instanceUuid, componentDictionary);
|
|
1209
1241
|
if (!expanded) return;
|
|
1210
1242
|
// Skip if an explicit scene behavior already covers this id
|
|
1211
1243
|
if (explicitIds.has(expanded.id)) return;
|
|
1244
|
+
// Skip if an explicit scene behavior already covers the same
|
|
1245
|
+
// (component, attachment, state) input tuple. This prevents a
|
|
1246
|
+
// component's built-in default wiring (e.g. switch → own LED) from
|
|
1247
|
+
// double-firing when the user has authored a cross-component override
|
|
1248
|
+
// that rewires the same switch to a different target.
|
|
1249
|
+
if ((_expanded$input = expanded.input) !== null && _expanded$input !== void 0 && _expanded$input.component && (_expanded$input2 = expanded.input) !== null && _expanded$input2 !== void 0 && _expanded$input2.attachment && (_expanded$input3 = expanded.input) !== null && _expanded$input3 !== void 0 && _expanded$input3.state) {
|
|
1250
|
+
var tuple = "".concat(expanded.input.component, "::").concat(expanded.input.attachment, "::").concat(expanded.input.state);
|
|
1251
|
+
if (explicitInputTuples.has(tuple)) return;
|
|
1252
|
+
}
|
|
1212
1253
|
// All component defaultBehaviors are re-derivable from the component
|
|
1213
1254
|
// asset at export time (via compact behaviorRef), so mark them all.
|
|
1214
1255
|
expanded._isDefaultBehavior = true;
|
|
@@ -1587,8 +1628,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1587
1628
|
// Process children (connectors, etc.) if they exist
|
|
1588
1629
|
if (componentModel.children && componentModel.children.length > 0) {
|
|
1589
1630
|
componentModel.children.forEach(function (child) {
|
|
1590
|
-
var _child$
|
|
1591
|
-
var childType = ((_child$
|
|
1631
|
+
var _child$userData10, _child$userData11;
|
|
1632
|
+
var childType = ((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType) || ((_child$userData11 = child.userData) === null || _child$userData11 === void 0 ? void 0 : _child$userData11.objectType);
|
|
1592
1633
|
if (childType === 'connector') {
|
|
1593
1634
|
var _child$geometry;
|
|
1594
1635
|
var childBoundingBox = new THREE.Box3().setFromObject(child);
|
|
@@ -1673,8 +1714,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1673
1714
|
if (segment.children && segment.children.length > 0) {
|
|
1674
1715
|
var childrenToRemove = _toConsumableArray(segment.children);
|
|
1675
1716
|
childrenToRemove.forEach(function (child) {
|
|
1676
|
-
var _child$
|
|
1677
|
-
if ((_child$
|
|
1717
|
+
var _child$userData12;
|
|
1718
|
+
if ((_child$userData12 = child.userData) !== null && _child$userData12 !== void 0 && _child$userData12.isPipeElbow) {
|
|
1678
1719
|
console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
|
|
1679
1720
|
segment.remove(child);
|
|
1680
1721
|
if (child.geometry) child.geometry.dispose();
|