@fps-games/editor 0.1.5-beta.5 → 0.1.6-beta.1
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/build-info.json +16 -16
- package/dist/local-editor-agent-actions.d.ts +8 -1
- package/dist/local-editor-agent-actions.d.ts.map +1 -1
- package/dist/local-editor-agent-actions.js +171 -12
- package/dist/local-editor-agent-actions.js.map +1 -1
- package/dist/local-editor-agent-context.d.ts +29 -1
- package/dist/local-editor-agent-context.d.ts.map +1 -1
- package/dist/local-editor-agent-context.js +403 -0
- package/dist/local-editor-agent-context.js.map +1 -1
- package/dist/local-editor-harness.d.ts +103 -5
- package/dist/local-editor-harness.d.ts.map +1 -1
- package/dist/local-editor-harness.js +1982 -101
- package/dist/local-editor-harness.js.map +1 -1
- package/dist/local-editor-marker-graph.d.ts +92 -0
- package/dist/local-editor-marker-graph.d.ts.map +1 -0
- package/dist/local-editor-marker-graph.js +1432 -0
- package/dist/local-editor-marker-graph.js.map +1 -0
- package/dist/local-editor-performance-stats.js +1 -1
- package/dist/local-editor-performance-stats.js.map +1 -1
- package/dist/playable-babylon-facade.d.ts +2 -2
- package/dist/playable-babylon-facade.d.ts.map +1 -1
- package/dist/playable-babylon-facade.js +1 -1
- package/dist/playable-babylon-facade.js.map +1 -1
- package/dist/playable-local-editor-host.d.ts +52 -7
- package/dist/playable-local-editor-host.d.ts.map +1 -1
- package/dist/playable-local-editor-host.js +23 -1
- package/dist/playable-local-editor-host.js.map +1 -1
- package/dist/playable-sdk.d.ts +4 -2
- package/dist/playable-sdk.d.ts.map +1 -1
- package/dist/playable-sdk.js +2 -1
- package/dist/playable-sdk.js.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/package.json +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/camera-controller.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js +11 -0
- package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-sky.d.ts +3 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-sky.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-sky.js +114 -18
- package/node_modules/@fps-games/editor-babylon/dist/editor-sky.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-world.js +3 -0
- package/node_modules/@fps-games/editor-babylon/dist/editor-world.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/index.d.ts +3 -0
- package/node_modules/@fps-games/editor-babylon/dist/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/index.js +3 -0
- package/node_modules/@fps-games/editor-babylon/dist/index.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.d.ts +52 -0
- package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js +1395 -0
- package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js +4 -65
- package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.d.ts +28 -0
- package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js +235 -0
- package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts +37 -0
- package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js +451 -0
- package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js +14 -3
- package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js +20 -4
- package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.d.ts +3 -6
- package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.js +4 -37
- package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts +44 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection.js +295 -41
- package/node_modules/@fps-games/editor-babylon/dist/projection.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/package.json +5 -5
- package/node_modules/@fps-games/editor-browser/dist/index.d.ts +5 -2
- package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/index.js +2 -0
- package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts +5 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js +23 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js.map +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js +69 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts +2 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js +38 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js +8 -2
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js +7 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts +4 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +1471 -29
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts +52 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js +131 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js.map +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js +9 -2
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +234 -3
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts +10 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js +3 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +4 -3
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +1274 -55
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/package.json +3 -3
- package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts +1 -1
- package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts +2 -0
- package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-core/dist/viewport-tools.js +1 -0
- package/node_modules/@fps-games/editor-core/dist/viewport-tools.js.map +1 -1
- package/node_modules/@fps-games/editor-core/package.json +2 -2
- package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js +17 -3
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js +2 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/types.d.ts +3 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts +1 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js +68 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts +56 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js +531 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts +103 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js +9 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts +1 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js +3 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js +3 -7
- package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.js +6 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/types.d.ts +2 -10
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js +8 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js +66 -31
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts +2 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js +40 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts +1 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js +20 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js +68 -27
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js +7 -4
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.js +2 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/package.json +3 -3
- package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts +57 -3
- package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-protocol/dist/agent.js.map +1 -1
- package/node_modules/@fps-games/editor-protocol/dist/index.d.ts +19 -0
- package/node_modules/@fps-games/editor-protocol/dist/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-protocol/dist/index.js +1 -0
- package/node_modules/@fps-games/editor-protocol/dist/index.js.map +1 -1
- package/node_modules/@fps-games/editor-protocol/dist/marker-graph.d.ts +128 -0
- package/node_modules/@fps-games/editor-protocol/dist/marker-graph.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-protocol/dist/marker-graph.js +2 -0
- package/node_modules/@fps-games/editor-protocol/dist/marker-graph.js.map +1 -0
- package/node_modules/@fps-games/editor-protocol/package.json +1 -1
- package/package.json +8 -8
|
@@ -3,6 +3,7 @@ import { applyBabylonDefaultOutline } from '@fps-games/babylon-renderer';
|
|
|
3
3
|
import { applyArtistMaterialProfileToRuntimeMaterial } from './material-property-adapter.js';
|
|
4
4
|
import { pickBabylonProjectionNodeIdAt, resolveBabylonPickSelectionNodeId, resolveBabylonProjectionNodeId, } from './projection-pick-resolver.js';
|
|
5
5
|
import { normalizeProjectionOwnerNodePath, readProjectionSourceNodeSegment, } from './projection-source-owner-path.js';
|
|
6
|
+
import { createMaterialSlotOwnerPathMatchKey, isMaterialSlotOwnerPathMatch, } from './material-slot-source-resolver.js';
|
|
6
7
|
const LARGE_SELECTION_EDGE_LIMIT = 200;
|
|
7
8
|
const PROJECTION_LOCAL_MATRIX_METADATA_KEY = 'editorLocalTransformMatrix';
|
|
8
9
|
const ASSET_MESH_SELECTION_SEPARATOR = '::assetMesh::';
|
|
@@ -124,6 +125,7 @@ export function createBabylonEditorProjection(options) {
|
|
|
124
125
|
const disposeProjectedNode = (projection) => {
|
|
125
126
|
projection.selectionEdgesPrewarmCancel?.();
|
|
126
127
|
projection.selectionEdgesPrewarmCancel = null;
|
|
128
|
+
projection.importStructure = null;
|
|
127
129
|
for (const animationGroup of projection.animationGroups) {
|
|
128
130
|
animationGroup.dispose?.();
|
|
129
131
|
}
|
|
@@ -262,6 +264,9 @@ export function createBabylonEditorProjection(options) {
|
|
|
262
264
|
}
|
|
263
265
|
return transforms;
|
|
264
266
|
},
|
|
267
|
+
readNodeImportStructure(nodeId) {
|
|
268
|
+
return cloneProjectionImportStructureSnapshot(projections.get(nodeId)?.importStructure ?? null);
|
|
269
|
+
},
|
|
265
270
|
setNodeTransformPreview(nodeId, transform) {
|
|
266
271
|
const projection = projections.get(nodeId);
|
|
267
272
|
if (!projection?.root)
|
|
@@ -581,12 +586,215 @@ function attachImportedProjectionResult(options, node, asset, projection, result
|
|
|
581
586
|
}
|
|
582
587
|
projection.animationGroups = result.animationGroups ?? [];
|
|
583
588
|
projection.outlineMeshes = (result.meshes ?? []).filter((mesh) => mesh.getTotalVertices?.() > 0);
|
|
589
|
+
projection.importStructure = createProjectionImportStructureSnapshot(node, asset, modelRoot, result);
|
|
584
590
|
}
|
|
585
591
|
catch (error) {
|
|
586
592
|
disposeImportedProjectionResult(result);
|
|
587
593
|
throw error;
|
|
588
594
|
}
|
|
589
595
|
}
|
|
596
|
+
function createProjectionImportStructureSnapshot(node, asset, modelRoot, result) {
|
|
597
|
+
const runtimeNodes = collectProjectionImportRuntimeNodes(modelRoot, result);
|
|
598
|
+
const nodeIdByRuntimeNode = new Map();
|
|
599
|
+
const materialIdByRuntimeMaterial = new Map();
|
|
600
|
+
const textureIdByRuntimeTexture = new Map();
|
|
601
|
+
const materialNodeIds = new Map();
|
|
602
|
+
const materialTextureIds = new Map();
|
|
603
|
+
const rootSnapshotId = 'root';
|
|
604
|
+
const snapshots = [{
|
|
605
|
+
id: rootSnapshotId,
|
|
606
|
+
parentId: null,
|
|
607
|
+
name: readProjectionRuntimeName(modelRoot, node.name ?? node.id),
|
|
608
|
+
kind: 'root',
|
|
609
|
+
}];
|
|
610
|
+
for (const runtimeNode of runtimeNodes) {
|
|
611
|
+
const snapshotId = createProjectionImportRuntimeNodeId(runtimeNode, nodeIdByRuntimeNode.size);
|
|
612
|
+
nodeIdByRuntimeNode.set(runtimeNode, snapshotId);
|
|
613
|
+
}
|
|
614
|
+
for (const runtimeNode of runtimeNodes) {
|
|
615
|
+
const snapshotId = nodeIdByRuntimeNode.get(runtimeNode);
|
|
616
|
+
if (!snapshotId)
|
|
617
|
+
continue;
|
|
618
|
+
const materialIds = readProjectionRuntimeNodeMaterials(runtimeNode)
|
|
619
|
+
.map(runtimeMaterial => getProjectionImportMaterialSnapshotId(runtimeMaterial, materialIdByRuntimeMaterial))
|
|
620
|
+
.filter((materialId) => !!materialId);
|
|
621
|
+
for (const materialId of materialIds) {
|
|
622
|
+
const nodeIds = materialNodeIds.get(materialId) ?? new Set();
|
|
623
|
+
nodeIds.add(snapshotId);
|
|
624
|
+
materialNodeIds.set(materialId, nodeIds);
|
|
625
|
+
const textureIds = readProjectionRuntimeMaterialTextures(readProjectionRuntimeNodeMaterialById(runtimeNode, runtimeNode, materialId, materialIdByRuntimeMaterial))
|
|
626
|
+
.map(runtimeTexture => getProjectionImportTextureSnapshotId(runtimeTexture, textureIdByRuntimeTexture))
|
|
627
|
+
.filter((textureId) => !!textureId);
|
|
628
|
+
const materialTextures = materialTextureIds.get(materialId) ?? new Set();
|
|
629
|
+
for (const textureId of textureIds)
|
|
630
|
+
materialTextures.add(textureId);
|
|
631
|
+
materialTextureIds.set(materialId, materialTextures);
|
|
632
|
+
}
|
|
633
|
+
snapshots.push({
|
|
634
|
+
id: snapshotId,
|
|
635
|
+
parentId: resolveProjectionImportRuntimeParentId(runtimeNode, modelRoot, nodeIdByRuntimeNode, rootSnapshotId),
|
|
636
|
+
name: readProjectionRuntimeName(runtimeNode, snapshotId),
|
|
637
|
+
kind: isProjectionRuntimeMeshLike(runtimeNode) ? 'mesh' : 'transform',
|
|
638
|
+
...readProjectionRuntimeSourceName(runtimeNode),
|
|
639
|
+
...readProjectionRuntimeOwnerNodePath(runtimeNode),
|
|
640
|
+
...(materialIds.length > 0 ? { materialIds } : {}),
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
const materials = [...materialIdByRuntimeMaterial.entries()].map(([runtimeMaterial, id]) => ({
|
|
644
|
+
id,
|
|
645
|
+
name: readProjectionRuntimeName(runtimeMaterial, id),
|
|
646
|
+
...readProjectionRuntimeKind(runtimeMaterial),
|
|
647
|
+
nodeIds: [...(materialNodeIds.get(id) ?? [])],
|
|
648
|
+
textureIds: [...(materialTextureIds.get(id) ?? [])],
|
|
649
|
+
}));
|
|
650
|
+
const textures = [...textureIdByRuntimeTexture.entries()].map(([runtimeTexture, id]) => ({
|
|
651
|
+
id,
|
|
652
|
+
name: readProjectionRuntimeName(runtimeTexture, id),
|
|
653
|
+
...readProjectionRuntimeKind(runtimeTexture),
|
|
654
|
+
...readProjectionRuntimeTextureUrl(runtimeTexture),
|
|
655
|
+
}));
|
|
656
|
+
const animations = createProjectionImportAnimationSnapshots(result.animationGroups ?? []);
|
|
657
|
+
return {
|
|
658
|
+
projectionNodeId: node.id,
|
|
659
|
+
...(asset.id ? { assetId: asset.id } : {}),
|
|
660
|
+
...(asset.sourceId ? { sourceId: asset.sourceId } : {}),
|
|
661
|
+
nodes: snapshots,
|
|
662
|
+
materials,
|
|
663
|
+
textures,
|
|
664
|
+
animations,
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
function collectProjectionImportRuntimeNodes(modelRoot, result) {
|
|
668
|
+
const known = new Set([
|
|
669
|
+
...(result.transformNodes ?? []),
|
|
670
|
+
...(result.meshes ?? []),
|
|
671
|
+
].filter(Boolean));
|
|
672
|
+
const ordered = [];
|
|
673
|
+
const visit = (runtimeNode) => {
|
|
674
|
+
for (const child of readProjectionRuntimeChildren(runtimeNode)) {
|
|
675
|
+
if (!known.has(child) || ordered.includes(child))
|
|
676
|
+
continue;
|
|
677
|
+
ordered.push(child);
|
|
678
|
+
visit(child);
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
visit(modelRoot);
|
|
682
|
+
for (const runtimeNode of known) {
|
|
683
|
+
if (!ordered.includes(runtimeNode))
|
|
684
|
+
ordered.push(runtimeNode);
|
|
685
|
+
}
|
|
686
|
+
return ordered;
|
|
687
|
+
}
|
|
688
|
+
function readProjectionRuntimeChildren(runtimeNode) {
|
|
689
|
+
const children = runtimeNode?.getChildren?.();
|
|
690
|
+
return Array.isArray(children) ? children : [];
|
|
691
|
+
}
|
|
692
|
+
function createProjectionImportRuntimeNodeId(runtimeNode, index) {
|
|
693
|
+
const sourceName = readProjectionSourceNodeSegment(runtimeNode);
|
|
694
|
+
const rawName = sourceName || runtimeNode?.name || runtimeNode?.id || `node-${index + 1}`;
|
|
695
|
+
return `${isProjectionRuntimeMeshLike(runtimeNode) ? 'mesh' : 'node'}:${sanitizeProjectionImportSnapshotId(rawName)}:${index + 1}`;
|
|
696
|
+
}
|
|
697
|
+
function resolveProjectionImportRuntimeParentId(runtimeNode, modelRoot, nodeIdByRuntimeNode, rootSnapshotId) {
|
|
698
|
+
const parent = runtimeNode?.parent ?? null;
|
|
699
|
+
if (!parent || parent === modelRoot)
|
|
700
|
+
return rootSnapshotId;
|
|
701
|
+
return nodeIdByRuntimeNode.get(parent) ?? rootSnapshotId;
|
|
702
|
+
}
|
|
703
|
+
function isProjectionRuntimeMeshLike(runtimeNode) {
|
|
704
|
+
return typeof runtimeNode?.getTotalVertices === 'function';
|
|
705
|
+
}
|
|
706
|
+
function readProjectionRuntimeNodeMaterials(runtimeNode) {
|
|
707
|
+
const material = runtimeNode?.material;
|
|
708
|
+
if (!material)
|
|
709
|
+
return [];
|
|
710
|
+
const subMaterials = material.subMaterials;
|
|
711
|
+
if (Array.isArray(subMaterials) && subMaterials.length > 0) {
|
|
712
|
+
return subMaterials.filter(Boolean);
|
|
713
|
+
}
|
|
714
|
+
return [material];
|
|
715
|
+
}
|
|
716
|
+
function readProjectionRuntimeNodeMaterialById(runtimeNode, _fallbackNode, materialId, materialIdByRuntimeMaterial) {
|
|
717
|
+
for (const material of readProjectionRuntimeNodeMaterials(runtimeNode)) {
|
|
718
|
+
if (materialIdByRuntimeMaterial.get(material) === materialId)
|
|
719
|
+
return material;
|
|
720
|
+
}
|
|
721
|
+
return null;
|
|
722
|
+
}
|
|
723
|
+
function getProjectionImportMaterialSnapshotId(runtimeMaterial, materialIdByRuntimeMaterial) {
|
|
724
|
+
if (!runtimeMaterial)
|
|
725
|
+
return null;
|
|
726
|
+
const existing = materialIdByRuntimeMaterial.get(runtimeMaterial);
|
|
727
|
+
if (existing)
|
|
728
|
+
return existing;
|
|
729
|
+
const id = `material:${sanitizeProjectionImportSnapshotId(readProjectionRuntimeName(runtimeMaterial, 'material'))}:${materialIdByRuntimeMaterial.size + 1}`;
|
|
730
|
+
materialIdByRuntimeMaterial.set(runtimeMaterial, id);
|
|
731
|
+
return id;
|
|
732
|
+
}
|
|
733
|
+
function readProjectionRuntimeMaterialTextures(runtimeMaterial) {
|
|
734
|
+
if (!runtimeMaterial)
|
|
735
|
+
return [];
|
|
736
|
+
const textures = runtimeMaterial.getActiveTextures?.();
|
|
737
|
+
return Array.isArray(textures) ? textures.filter(Boolean) : [];
|
|
738
|
+
}
|
|
739
|
+
function getProjectionImportTextureSnapshotId(runtimeTexture, textureIdByRuntimeTexture) {
|
|
740
|
+
if (!runtimeTexture)
|
|
741
|
+
return null;
|
|
742
|
+
const existing = textureIdByRuntimeTexture.get(runtimeTexture);
|
|
743
|
+
if (existing)
|
|
744
|
+
return existing;
|
|
745
|
+
const name = readProjectionRuntimeTextureUrl(runtimeTexture).url
|
|
746
|
+
?? readProjectionRuntimeName(runtimeTexture, 'texture');
|
|
747
|
+
const id = `texture:${sanitizeProjectionImportSnapshotId(name)}:${textureIdByRuntimeTexture.size + 1}`;
|
|
748
|
+
textureIdByRuntimeTexture.set(runtimeTexture, id);
|
|
749
|
+
return id;
|
|
750
|
+
}
|
|
751
|
+
function createProjectionImportAnimationSnapshots(animationGroups) {
|
|
752
|
+
return animationGroups.filter(Boolean).map((animationGroup, index) => ({
|
|
753
|
+
id: `animation:${sanitizeProjectionImportSnapshotId(readProjectionRuntimeName(animationGroup, 'animation'))}:${index + 1}`,
|
|
754
|
+
name: readProjectionRuntimeName(animationGroup, `Animation ${index + 1}`),
|
|
755
|
+
}));
|
|
756
|
+
}
|
|
757
|
+
function readProjectionRuntimeName(runtimeObject, fallback) {
|
|
758
|
+
const name = runtimeObject?.name ?? runtimeObject?.id;
|
|
759
|
+
return typeof name === 'string' && name.trim() ? name.trim() : fallback;
|
|
760
|
+
}
|
|
761
|
+
function readProjectionRuntimeKind(runtimeObject) {
|
|
762
|
+
const kind = runtimeObject?.getClassName?.();
|
|
763
|
+
return typeof kind === 'string' && kind.trim() ? { kind: kind.trim() } : {};
|
|
764
|
+
}
|
|
765
|
+
function readProjectionRuntimeTextureUrl(runtimeTexture) {
|
|
766
|
+
const url = runtimeTexture?.url ?? runtimeTexture?.name;
|
|
767
|
+
return typeof url === 'string' && url.trim() ? { url: url.trim() } : {};
|
|
768
|
+
}
|
|
769
|
+
function readProjectionRuntimeSourceName(runtimeNode) {
|
|
770
|
+
const sourceName = readProjectionSourceNodeSegment(runtimeNode);
|
|
771
|
+
return sourceName ? { sourceName } : {};
|
|
772
|
+
}
|
|
773
|
+
function readProjectionRuntimeOwnerNodePath(runtimeNode) {
|
|
774
|
+
const ownerNodePath = runtimeNode?.metadata?.editorProjection?.ownerNodePath;
|
|
775
|
+
return typeof ownerNodePath === 'string' && ownerNodePath.trim() ? { ownerNodePath: ownerNodePath.trim() } : {};
|
|
776
|
+
}
|
|
777
|
+
function sanitizeProjectionImportSnapshotId(value) {
|
|
778
|
+
return value.trim().toLowerCase().replace(/[^a-z0-9_.:-]+/gi, '-').replace(/^-+|-+$/g, '') || 'item';
|
|
779
|
+
}
|
|
780
|
+
function cloneProjectionImportStructureSnapshot(snapshot) {
|
|
781
|
+
if (!snapshot)
|
|
782
|
+
return null;
|
|
783
|
+
return {
|
|
784
|
+
...snapshot,
|
|
785
|
+
nodes: snapshot.nodes.map(item => ({
|
|
786
|
+
...item,
|
|
787
|
+
...(item.materialIds ? { materialIds: [...item.materialIds] } : {}),
|
|
788
|
+
})),
|
|
789
|
+
materials: snapshot.materials.map(item => ({
|
|
790
|
+
...item,
|
|
791
|
+
nodeIds: [...item.nodeIds],
|
|
792
|
+
textureIds: [...item.textureIds],
|
|
793
|
+
})),
|
|
794
|
+
textures: snapshot.textures.map(item => ({ ...item })),
|
|
795
|
+
animations: snapshot.animations.map(item => ({ ...item })),
|
|
796
|
+
};
|
|
797
|
+
}
|
|
590
798
|
function disposeImportedProjectionResult(result) {
|
|
591
799
|
for (const animationGroup of result.animationGroups ?? []) {
|
|
592
800
|
animationGroup.dispose?.();
|
|
@@ -655,6 +863,8 @@ function attachDirectionalLightProjection(babylon, scene, node, projection) {
|
|
|
655
863
|
light.setEnabled?.(node.active !== false);
|
|
656
864
|
projection.runtimeObjects.push(light);
|
|
657
865
|
}
|
|
866
|
+
if (!settings.helperVisible)
|
|
867
|
+
return;
|
|
658
868
|
const helper = MeshBuilder.CreateBox(`${node.id}.lightHelper`, {
|
|
659
869
|
size: 0.28,
|
|
660
870
|
}, scene);
|
|
@@ -760,9 +970,9 @@ function createPrimitiveProjectionMesh(babylon, scene, node, options) {
|
|
|
760
970
|
return mesh;
|
|
761
971
|
}
|
|
762
972
|
function applyProjectionArtistMaterialProfilesToMeshes(options, node, modelRoot, meshes) {
|
|
763
|
-
const
|
|
973
|
+
const slotBindings = createProjectionMaterialSlotBindings(node);
|
|
764
974
|
const hasRootProfile = !!node.artistMaterialProfile;
|
|
765
|
-
const hasSlotProfiles =
|
|
975
|
+
const hasSlotProfiles = slotBindings.length > 0;
|
|
766
976
|
if (!hasRootProfile && !hasSlotProfiles)
|
|
767
977
|
return [];
|
|
768
978
|
const clonedMaterials = [];
|
|
@@ -785,15 +995,15 @@ function applyProjectionArtistMaterialProfilesToMeshes(options, node, modelRoot,
|
|
|
785
995
|
if (!material)
|
|
786
996
|
continue;
|
|
787
997
|
const ownerNodePath = buildProjectionOwnerNodePath(mesh, modelRoot, node.id);
|
|
788
|
-
const
|
|
789
|
-
if (!
|
|
998
|
+
const slotBinding = resolveProjectionSlotBinding(slotBindings, ownerNodePath, node.id);
|
|
999
|
+
if (!slotBinding)
|
|
790
1000
|
continue;
|
|
791
1001
|
const slotMaterial = detachProjectionSlotMaterial(mesh, materialCounts, ownerNodePath);
|
|
792
1002
|
if (!slotMaterial)
|
|
793
1003
|
continue;
|
|
794
1004
|
if (slotMaterial !== material)
|
|
795
1005
|
clonedMaterials.push(slotMaterial);
|
|
796
|
-
applyProjectionArtistMaterialProfile(options, slotMaterial,
|
|
1006
|
+
applyProjectionArtistMaterialProfile(options, slotMaterial, slotBinding.profile);
|
|
797
1007
|
}
|
|
798
1008
|
return clonedMaterials;
|
|
799
1009
|
}
|
|
@@ -805,27 +1015,85 @@ function applyProjectionArtistMaterialProfile(options, material, profile) {
|
|
|
805
1015
|
resolveTextureUrl: options.resolveTextureUrl,
|
|
806
1016
|
});
|
|
807
1017
|
}
|
|
808
|
-
function
|
|
1018
|
+
function createProjectionMaterialSlotBindings(node) {
|
|
1019
|
+
const bindings = [];
|
|
1020
|
+
const occupiedOwnerPaths = new Set();
|
|
1021
|
+
for (const binding of node.artistMaterialSlotBindings ?? []) {
|
|
1022
|
+
const profile = binding?.profile;
|
|
1023
|
+
const slot = createProjectionMaterialSlotDescriptor(binding?.slot, node.id);
|
|
1024
|
+
if (!profile || !slot)
|
|
1025
|
+
continue;
|
|
1026
|
+
bindings.push({ slot, profile });
|
|
1027
|
+
occupiedOwnerPaths.add(slot.matchKey);
|
|
1028
|
+
}
|
|
1029
|
+
for (const [ownerNodePath, profile] of Object.entries(node.artistMaterialSlotProfiles ?? {})) {
|
|
1030
|
+
const slot = createProjectionMaterialSlotDescriptor({ ownerNodePath }, node.id);
|
|
1031
|
+
if (!profile || !slot || occupiedOwnerPaths.has(slot.matchKey))
|
|
1032
|
+
continue;
|
|
1033
|
+
bindings.push({ slot, profile });
|
|
1034
|
+
occupiedOwnerPaths.add(slot.matchKey);
|
|
1035
|
+
}
|
|
1036
|
+
return bindings;
|
|
1037
|
+
}
|
|
1038
|
+
function createProjectionMaterialSlotDescriptor(value, projectionNodeId) {
|
|
1039
|
+
if (!value || typeof value !== 'object')
|
|
1040
|
+
return null;
|
|
1041
|
+
const ownerNodePath = typeof value.ownerNodePath === 'string'
|
|
1042
|
+
? normalizeProjectionOwnerNodePath(value.ownerNodePath, { projectionNodeId })
|
|
1043
|
+
: '';
|
|
1044
|
+
if (!ownerNodePath)
|
|
1045
|
+
return null;
|
|
1046
|
+
const slotId = typeof value.slotId === 'string' && value.slotId.trim() ? value.slotId.trim() : '';
|
|
1047
|
+
const label = typeof value.label === 'string' && value.label.trim() ? value.label.trim() : '';
|
|
1048
|
+
const nodeIndex = Number.isInteger(value.nodeIndex) ? value.nodeIndex : undefined;
|
|
1049
|
+
const nodeIndexPath = Array.isArray(value.nodeIndexPath)
|
|
1050
|
+
? value.nodeIndexPath.filter((item) => Number.isInteger(item))
|
|
1051
|
+
: undefined;
|
|
1052
|
+
const meshIndex = Number.isInteger(value.meshIndex) ? value.meshIndex : undefined;
|
|
1053
|
+
const primitiveIndex = Number.isInteger(value.primitiveIndex) ? value.primitiveIndex : undefined;
|
|
1054
|
+
const sourceMaterialIndex = Number.isInteger(value.sourceMaterialIndex) ? value.sourceMaterialIndex : undefined;
|
|
1055
|
+
const sourceMaterialIndices = Array.isArray(value.sourceMaterialIndices)
|
|
1056
|
+
? value.sourceMaterialIndices.filter((item) => Number.isInteger(item))
|
|
1057
|
+
: undefined;
|
|
1058
|
+
const materialName = typeof value.materialName === 'string' && value.materialName.trim() ? value.materialName.trim() : '';
|
|
1059
|
+
const materialNames = Array.isArray(value.materialNames)
|
|
1060
|
+
? value.materialNames.filter((item) => typeof item === 'string' && !!item.trim()).map(item => item.trim())
|
|
1061
|
+
: undefined;
|
|
1062
|
+
return {
|
|
1063
|
+
...(slotId ? { slotId } : {}),
|
|
1064
|
+
ownerNodePath,
|
|
1065
|
+
...(label ? { label } : {}),
|
|
1066
|
+
...(nodeIndex != null ? { nodeIndex } : {}),
|
|
1067
|
+
...(nodeIndexPath && nodeIndexPath.length > 0 ? { nodeIndexPath } : {}),
|
|
1068
|
+
...(meshIndex != null ? { meshIndex } : {}),
|
|
1069
|
+
...(primitiveIndex != null ? { primitiveIndex } : {}),
|
|
1070
|
+
...(sourceMaterialIndex != null ? { sourceMaterialIndex } : {}),
|
|
1071
|
+
...(sourceMaterialIndices && sourceMaterialIndices.length > 0
|
|
1072
|
+
? { sourceMaterialIndices }
|
|
1073
|
+
: {}),
|
|
1074
|
+
...(materialName ? { materialName } : {}),
|
|
1075
|
+
...(materialNames && materialNames.length > 0 ? { materialNames } : {}),
|
|
1076
|
+
key: slotId || ownerNodePath,
|
|
1077
|
+
normalizedOwnerNodePath: ownerNodePath,
|
|
1078
|
+
matchKey: createMaterialSlotOwnerPathMatchKey(ownerNodePath, { projectionNodeId }),
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
function resolveProjectionSlotBinding(slotBindings, ownerNodePath, projectionNodeId) {
|
|
809
1082
|
if (ownerNodePath == null)
|
|
810
1083
|
return null;
|
|
811
|
-
const direct = slotProfiles[ownerNodePath];
|
|
812
|
-
if (direct)
|
|
813
|
-
return direct;
|
|
814
1084
|
const normalized = normalizeProjectionOwnerNodePath(ownerNodePath, { projectionNodeId });
|
|
815
|
-
|
|
816
|
-
return slotProfiles[normalized];
|
|
1085
|
+
const normalizedMatchKey = createMaterialSlotOwnerPathMatchKey(normalized, { projectionNodeId });
|
|
817
1086
|
let descendantMatch = null;
|
|
818
|
-
for (const
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
descendantMatch = { path: normalizedCandidate, profile };
|
|
1087
|
+
for (const binding of slotBindings) {
|
|
1088
|
+
if (binding.slot.matchKey === normalizedMatchKey)
|
|
1089
|
+
return binding;
|
|
1090
|
+
if (isMaterialSlotOwnerPathMatch(normalized, binding.slot.normalizedOwnerNodePath, { projectionNodeId })) {
|
|
1091
|
+
if (!descendantMatch || binding.slot.matchKey.length > descendantMatch.slot.matchKey.length) {
|
|
1092
|
+
descendantMatch = binding;
|
|
825
1093
|
}
|
|
826
1094
|
}
|
|
827
1095
|
}
|
|
828
|
-
return descendantMatch
|
|
1096
|
+
return descendantMatch;
|
|
829
1097
|
}
|
|
830
1098
|
function buildProjectionOwnerNodePath(node, rootNode, projectionNodeId) {
|
|
831
1099
|
if (!node || !rootNode || node === rootNode)
|
|
@@ -857,11 +1125,6 @@ function stableProjectionNodeSegment(node) {
|
|
|
857
1125
|
}
|
|
858
1126
|
return null;
|
|
859
1127
|
}
|
|
860
|
-
function isProjectionOwnerPathDescendant(ownerNodePath, candidateAncestorPath) {
|
|
861
|
-
if (!ownerNodePath || !candidateAncestorPath)
|
|
862
|
-
return false;
|
|
863
|
-
return ownerNodePath.startsWith(`${candidateAncestorPath}/`);
|
|
864
|
-
}
|
|
865
1128
|
function createAssetMeshProjectionNodeId(rootNodeId, ownerNodePath) {
|
|
866
1129
|
return `${rootNodeId}${ASSET_MESH_SELECTION_SEPARATOR}${encodeURIComponent(ownerNodePath)}`;
|
|
867
1130
|
}
|
|
@@ -869,9 +1132,9 @@ function resolveProjectionAssetMeshSelectionKey(asset, ownerNodePath, projection
|
|
|
869
1132
|
const normalizedOwnerPath = normalizeProjectionOwnerNodePath(ownerNodePath, { projectionNodeId });
|
|
870
1133
|
let bestSlot = null;
|
|
871
1134
|
for (const slot of readProjectionAssetMaterialSlots(asset, projectionNodeId)) {
|
|
872
|
-
if (!
|
|
1135
|
+
if (!isMaterialSlotOwnerPathMatch(normalizedOwnerPath, slot.normalizedOwnerNodePath, { projectionNodeId }))
|
|
873
1136
|
continue;
|
|
874
|
-
if (!bestSlot || slot.
|
|
1137
|
+
if (!bestSlot || slot.matchKey.length > bestSlot.matchKey.length) {
|
|
875
1138
|
bestSlot = slot;
|
|
876
1139
|
}
|
|
877
1140
|
}
|
|
@@ -891,8 +1154,7 @@ function readProjectionAssetMaterialSlots(asset, projectionNodeId) {
|
|
|
891
1154
|
}
|
|
892
1155
|
function readProjectionAssetMaterialSlot(value, projectionNodeId) {
|
|
893
1156
|
if (typeof value === 'string') {
|
|
894
|
-
|
|
895
|
-
return path ? { key: path, path } : null;
|
|
1157
|
+
return createProjectionMaterialSlotDescriptor({ ownerNodePath: value }, projectionNodeId);
|
|
896
1158
|
}
|
|
897
1159
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
898
1160
|
return null;
|
|
@@ -900,23 +1162,11 @@ function readProjectionAssetMaterialSlot(value, projectionNodeId) {
|
|
|
900
1162
|
const rawOwnerPath = readProjectionAssetMaterialSlotString(record.ownerNodePath)
|
|
901
1163
|
|| readProjectionAssetMaterialSlotString(record.path)
|
|
902
1164
|
|| readProjectionAssetMaterialSlotString(record.name);
|
|
903
|
-
|
|
904
|
-
if (!path)
|
|
905
|
-
return null;
|
|
906
|
-
const slotId = readProjectionAssetMaterialSlotString(record.slotId);
|
|
907
|
-
return {
|
|
908
|
-
key: slotId || path,
|
|
909
|
-
path,
|
|
910
|
-
};
|
|
1165
|
+
return createProjectionMaterialSlotDescriptor({ ...record, ownerNodePath: rawOwnerPath }, projectionNodeId);
|
|
911
1166
|
}
|
|
912
1167
|
function readProjectionAssetMaterialSlotString(value) {
|
|
913
1168
|
return typeof value === 'string' ? value.trim() : '';
|
|
914
1169
|
}
|
|
915
|
-
function isProjectionOwnerPathSlotMatch(ownerNodePath, slotOwnerPath) {
|
|
916
|
-
if (!ownerNodePath || !slotOwnerPath)
|
|
917
|
-
return false;
|
|
918
|
-
return ownerNodePath === slotOwnerPath || isProjectionOwnerPathDescendant(ownerNodePath, slotOwnerPath);
|
|
919
|
-
}
|
|
920
1170
|
function countProjectionMeshMaterials(meshes) {
|
|
921
1171
|
const counts = new Map();
|
|
922
1172
|
for (const mesh of meshes) {
|
|
@@ -1112,6 +1362,8 @@ function attachHemisphericLightProjection(babylon, scene, node, projection) {
|
|
|
1112
1362
|
light.setEnabled?.(node.active !== false);
|
|
1113
1363
|
projection.runtimeObjects.push(light);
|
|
1114
1364
|
}
|
|
1365
|
+
if (!settings.helperVisible)
|
|
1366
|
+
return;
|
|
1115
1367
|
const helper = MeshBuilder.CreateSphere?.(`${node.id}.hemisphericLightHelper`, {
|
|
1116
1368
|
diameter: 0.32,
|
|
1117
1369
|
segments: 18,
|
|
@@ -1258,6 +1510,7 @@ function readProjectionDirectionalLightSettings(settings) {
|
|
|
1258
1510
|
intensity: Math.max(0, readFiniteNumber(settings?.intensity, 2)),
|
|
1259
1511
|
direction: readVector3(settings?.direction, { x: -0.3, y: -1, z: -0.2 }),
|
|
1260
1512
|
diffuseColor: readProjectionColor(settings?.diffuseColor, { r: 1, g: 1, b: 1 }),
|
|
1513
|
+
helperVisible: settings?.helperVisible !== false,
|
|
1261
1514
|
};
|
|
1262
1515
|
}
|
|
1263
1516
|
function readProjectionHemisphericLightSettings(settings) {
|
|
@@ -1266,6 +1519,7 @@ function readProjectionHemisphericLightSettings(settings) {
|
|
|
1266
1519
|
intensity: Math.max(0, readFiniteNumber(settings?.intensity, 0.8)),
|
|
1267
1520
|
diffuseColor: readProjectionColor(settings?.diffuseColor, { r: 1, g: 1, b: 1 }),
|
|
1268
1521
|
groundColor: readProjectionColor(settings?.groundColor, { r: 0.48, g: 0.52, b: 0.62 }),
|
|
1522
|
+
helperVisible: settings?.helperVisible !== false,
|
|
1269
1523
|
};
|
|
1270
1524
|
}
|
|
1271
1525
|
function readProjectionColor(value, fallback) {
|