@babylonjs/loaders 9.20.0 → 9.20.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.
Files changed (50) hide show
  1. package/SPLAT/gaussianSplattingStream.d.ts +170 -1
  2. package/SPLAT/gaussianSplattingStream.js +516 -40
  3. package/SPLAT/gaussianSplattingStream.js.map +1 -1
  4. package/SPLAT/gaussianSplattingWorkBuffer.d.ts +163 -4
  5. package/SPLAT/gaussianSplattingWorkBuffer.js +683 -35
  6. package/SPLAT/gaussianSplattingWorkBuffer.js.map +1 -1
  7. package/SPLAT/gaussianSplattingWorkBufferShaders.d.ts +70 -2
  8. package/SPLAT/gaussianSplattingWorkBufferShaders.js +465 -4
  9. package/SPLAT/gaussianSplattingWorkBufferShaders.js.map +1 -1
  10. package/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.d.ts +16 -1
  11. package/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.js +232 -25
  12. package/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.js.map +1 -1
  13. package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.d.ts +52 -2
  14. package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.js +108 -7
  15. package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.js.map +1 -1
  16. package/glTF/2.0/Extensions/KHR_interactivity/interactivityHostResolver.d.ts +37 -0
  17. package/glTF/2.0/Extensions/KHR_interactivity/interactivityHostResolver.js +69 -0
  18. package/glTF/2.0/Extensions/KHR_interactivity/interactivityHostResolver.js.map +1 -0
  19. package/glTF/2.0/Extensions/KHR_interactivity/interactivityReferences.d.ts +44 -0
  20. package/glTF/2.0/Extensions/KHR_interactivity/interactivityReferences.js +51 -0
  21. package/glTF/2.0/Extensions/KHR_interactivity/interactivityReferences.js.map +1 -0
  22. package/glTF/2.0/Extensions/KHR_interactivity.pure.d.ts +1 -0
  23. package/glTF/2.0/Extensions/KHR_interactivity.pure.js +143 -12
  24. package/glTF/2.0/Extensions/KHR_interactivity.pure.js.map +1 -1
  25. package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js +6 -0
  26. package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js.map +1 -1
  27. package/glTF/2.0/Extensions/KHR_node_selectability.pure.js +4 -0
  28. package/glTF/2.0/Extensions/KHR_node_selectability.pure.js.map +1 -1
  29. package/glTF/2.0/Extensions/KHR_node_visibility.pure.js +11 -0
  30. package/glTF/2.0/Extensions/KHR_node_visibility.pure.js.map +1 -1
  31. package/glTF/2.0/Extensions/babylonScenePathToObjectConverter.d.ts +126 -0
  32. package/glTF/2.0/Extensions/babylonScenePathToObjectConverter.js +251 -0
  33. package/glTF/2.0/Extensions/babylonScenePathToObjectConverter.js.map +1 -0
  34. package/glTF/2.0/Extensions/compositePathToObjectConverter.d.ts +51 -0
  35. package/glTF/2.0/Extensions/compositePathToObjectConverter.js +51 -0
  36. package/glTF/2.0/Extensions/compositePathToObjectConverter.js.map +1 -0
  37. package/glTF/2.0/Extensions/gltfPathToObjectConverter.js +69 -7
  38. package/glTF/2.0/Extensions/gltfPathToObjectConverter.js.map +1 -1
  39. package/glTF/2.0/Extensions/interactivityAssetPathToObjectConverter.d.ts +41 -0
  40. package/glTF/2.0/Extensions/interactivityAssetPathToObjectConverter.js +108 -0
  41. package/glTF/2.0/Extensions/interactivityAssetPathToObjectConverter.js.map +1 -0
  42. package/glTF/2.0/Extensions/interactivityRefPathToObjectConverter.d.ts +28 -0
  43. package/glTF/2.0/Extensions/interactivityRefPathToObjectConverter.js +71 -0
  44. package/glTF/2.0/Extensions/interactivityRefPathToObjectConverter.js.map +1 -0
  45. package/glTF/2.0/Extensions/objectModelMapping.d.ts +118 -30
  46. package/glTF/2.0/Extensions/objectModelMapping.js +472 -70
  47. package/glTF/2.0/Extensions/objectModelMapping.js.map +1 -1
  48. package/glTF/2.0/glTFLoader.pure.js +2 -1
  49. package/glTF/2.0/glTFLoader.pure.js.map +1 -1
  50. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"KHR_node_visibility.pure.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/KHR_node_visibility.pure.ts"],"names":[],"mappings":"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","sourcesContent":["import { type GLTFLoader } from \"../glTFLoader.pure\";\r\nimport { type IGLTFLoaderExtension } from \"../glTFLoaderExtension\";\r\nimport { registerGLTFExtension, unregisterGLTFExtension } from \"../glTFLoaderExtensionRegistry\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { type INode } from \"../glTFLoaderInterfaces\";\r\nimport { AddObjectAccessorToKey } from \"./objectModelMapping\";\r\n\r\nconst NAME = \"KHR_node_visibility\";\r\n\r\n// object model extension for visibility\r\n\r\n/**\r\n * Loader extension for KHR_node_visibility\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_node_visibility implements IGLTFLoaderExtension {\r\n /**\r\n * The name of this extension.\r\n */\r\n public readonly name = NAME;\r\n\r\n /**\r\n * Defines whether this extension is enabled.\r\n */\r\n public enabled: boolean;\r\n\r\n private _loader?: GLTFLoader;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(loader: GLTFLoader) {\r\n this._loader = loader;\r\n this.enabled = loader.isExtensionUsed(NAME);\r\n }\r\n\r\n public onReady(): void {\r\n if (!this._loader) {\r\n return;\r\n }\r\n\r\n const nodes = this._loader.gltf.nodes;\r\n if (nodes) {\r\n for (const node of nodes) {\r\n const babylonTransformNode = node._babylonTransformNode;\r\n if (babylonTransformNode) {\r\n babylonTransformNode.inheritVisibility = true;\r\n if (node.extensions && node.extensions.KHR_node_visibility && node.extensions.KHR_node_visibility.visible === false) {\r\n babylonTransformNode.isVisible = false;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public dispose() {\r\n delete this._loader;\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Registers the KHR_node_visibility glTF loader extension.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function RegisterKHR_node_visibility(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n AddObjectAccessorToKey(\"/nodes/{}/extensions/KHR_node_visibility/visible\", {\r\n get: (node: INode) => {\r\n const tn = node._babylonTransformNode as any;\r\n if (tn && tn.isVisible !== undefined) {\r\n return tn.isVisible;\r\n }\r\n return true;\r\n },\r\n set: (value: boolean, node: INode) => {\r\n node._primitiveBabylonMeshes?.forEach((mesh) => {\r\n mesh.inheritVisibility = true;\r\n });\r\n if (node._babylonTransformNode) {\r\n (node._babylonTransformNode as AbstractMesh).isVisible = value;\r\n }\r\n node._primitiveBabylonMeshes?.forEach((mesh) => {\r\n mesh.isVisible = value;\r\n });\r\n },\r\n getTarget: (node: INode) => node._babylonTransformNode,\r\n getPropertyName: [() => \"isVisible\"],\r\n type: \"boolean\",\r\n });\r\n\r\n unregisterGLTFExtension(NAME);\r\n\r\n registerGLTFExtension(NAME, true, (loader) => new KHR_node_visibility(loader));\r\n}\r\n"]}
1
+ {"version":3,"file":"KHR_node_visibility.pure.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/KHR_node_visibility.pure.ts"],"names":[],"mappings":"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","sourcesContent":["import { type GLTFLoader } from \"../glTFLoader.pure\";\r\nimport { type IGLTFLoaderExtension } from \"../glTFLoaderExtension\";\r\nimport { registerGLTFExtension, unregisterGLTFExtension } from \"../glTFLoaderExtensionRegistry\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { type INode } from \"../glTFLoaderInterfaces\";\r\nimport { AddObjectAccessorToKey } from \"./objectModelMapping\";\r\n\r\nconst NAME = \"KHR_node_visibility\";\r\n\r\n// object model extension for visibility\r\n\r\n/**\r\n * Loader extension for KHR_node_visibility\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_node_visibility implements IGLTFLoaderExtension {\r\n /**\r\n * The name of this extension.\r\n */\r\n public readonly name = NAME;\r\n\r\n /**\r\n * Defines whether this extension is enabled.\r\n */\r\n public enabled: boolean;\r\n\r\n private _loader?: GLTFLoader;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(loader: GLTFLoader) {\r\n this._loader = loader;\r\n this.enabled = loader.isExtensionUsed(NAME);\r\n }\r\n\r\n public onReady(): void {\r\n if (!this._loader) {\r\n return;\r\n }\r\n\r\n const nodes = this._loader.gltf.nodes;\r\n if (nodes) {\r\n for (const node of nodes) {\r\n const babylonTransformNode = node._babylonTransformNode;\r\n if (babylonTransformNode) {\r\n babylonTransformNode.inheritVisibility = true;\r\n if (node.extensions && node.extensions.KHR_node_visibility && node.extensions.KHR_node_visibility.visible === false) {\r\n // Apply ``visible: false`` to the same set of meshes the\r\n // runtime ``pointer/set`` accessor writes to. The wrapping\r\n // ``babylonTransformNode`` is often a non-rendering\r\n // ``TransformNode``, so setting ``isVisible`` only there\r\n // leaves the primitive child meshes visible. Mirror the\r\n // accessor below so assets that author hidden defaults\r\n // (e.g. MagicBall.glb's FortuneWords) start hidden as intended.\r\n (babylonTransformNode as AbstractMesh).isVisible = false;\r\n node._primitiveBabylonMeshes?.forEach((mesh) => {\r\n mesh.inheritVisibility = true;\r\n mesh.isVisible = false;\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public dispose() {\r\n delete this._loader;\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Registers the KHR_node_visibility glTF loader extension.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function RegisterKHR_node_visibility(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n AddObjectAccessorToKey(\"/nodes/{}/extensions/KHR_node_visibility/visible\", {\r\n get: (node: INode) => {\r\n const tn = node._babylonTransformNode as any;\r\n if (tn && tn.isVisible !== undefined) {\r\n return tn.isVisible;\r\n }\r\n return true;\r\n },\r\n set: (value: boolean, node: INode) => {\r\n node._primitiveBabylonMeshes?.forEach((mesh) => {\r\n mesh.inheritVisibility = true;\r\n });\r\n if (node._babylonTransformNode) {\r\n (node._babylonTransformNode as AbstractMesh).isVisible = value;\r\n }\r\n node._primitiveBabylonMeshes?.forEach((mesh) => {\r\n mesh.isVisible = value;\r\n });\r\n },\r\n getTarget: (node: INode) => node._babylonTransformNode,\r\n getPropertyName: [() => \"isVisible\"],\r\n type: \"boolean\",\r\n });\r\n\r\n unregisterGLTFExtension(NAME);\r\n\r\n registerGLTFExtension(NAME, true, (loader) => new KHR_node_visibility(loader));\r\n}\r\n"]}
@@ -0,0 +1,126 @@
1
+ import { type Scene } from "@babylonjs/core/scene.js";
2
+ import { type TransformNode } from "@babylonjs/core/Meshes/transformNode.js";
3
+ import { type AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh.js";
4
+ import { type Material } from "@babylonjs/core/Materials/material.js";
5
+ import { type Vector3, Quaternion, type Matrix } from "@babylonjs/core/Maths/math.vector.js";
6
+ import { type IObjectAccessor } from "@babylonjs/core/FlowGraph/typeDefinitions.js";
7
+ import { type IObjectInfo, type IPathToObjectConverter } from "@babylonjs/core/ObjectModel/objectModelInterfaces.js";
8
+ /**
9
+ * Root of the JSON-Pointer namespace under which Babylon-scene objects are
10
+ * addressed by KHR_interactivity refs that did not originate from the source
11
+ * glTF asset (e.g. refs emitted by engine-specific event blocks).
12
+ *
13
+ * Trailing `/` is intentional: it lets path-prefix dispatchers like
14
+ * {@link CompositePathToObjectConverter} match cleanly.
15
+ */
16
+ export declare const BABYLON_SCENE_OBJECT_MODEL_PREFIX = "/extensions/BABYLON_scene_objects/";
17
+ /**
18
+ * Shape of the Babylon-scene object model tree consumed by
19
+ * {@link BabylonScenePathToObjectConverter}. Mirrors `IGLTFObjectModelTree`
20
+ * but is rooted at scene-asset arrays (`transformNodes`, `meshes`, …) and
21
+ * keyed by Babylon `uniqueId`. Initially we only expose the property leaves
22
+ * needed to validate the seam end-to-end; future leaves can be added without
23
+ * any path-converter changes.
24
+ */
25
+ export interface IBabylonSceneObjectModelTree {
26
+ /**
27
+ *
28
+ */
29
+ transformNodes: IBabylonObjectCollection<TransformNode>;
30
+ /**
31
+ *
32
+ */
33
+ meshes: IBabylonObjectCollection<AbstractMesh>;
34
+ /**
35
+ *
36
+ */
37
+ materials: IBabylonObjectCollection<Material>;
38
+ }
39
+ /**
40
+ * Generic per-collection node in the tree. `length` exposes a `.length`
41
+ * accessor (mirroring glTF). `__array__` is the per-instance leaf hit when a
42
+ * uniqueId index appears in the path.
43
+ */
44
+ export interface IBabylonObjectCollection<TBabylon> {
45
+ /**
46
+ *
47
+ */
48
+ length: IObjectAccessor<TBabylon[], TBabylon[], number>;
49
+ /**
50
+ *
51
+ */
52
+ __array__: IBabylonObjectLeaves<TBabylon>;
53
+ }
54
+ /** Per-instance accessors. Add new properties here as they are needed. */
55
+ export interface IBabylonObjectLeaves<TBabylon> {
56
+ /** Marks this position as a `getTarget` boundary so the resolver can hand back the instance itself. */
57
+ __target__?: boolean;
58
+ /**
59
+ *
60
+ */
61
+ name?: IObjectAccessor<TBabylon, TBabylon, string>;
62
+ /**
63
+ *
64
+ */
65
+ translation?: IObjectAccessor<TBabylon, TBabylon, Vector3>;
66
+ /**
67
+ *
68
+ */
69
+ rotation?: IObjectAccessor<TBabylon, TBabylon, Quaternion>;
70
+ /**
71
+ *
72
+ */
73
+ scale?: IObjectAccessor<TBabylon, TBabylon, Vector3>;
74
+ /**
75
+ *
76
+ */
77
+ matrix?: IObjectAccessor<TBabylon, TBabylon, Matrix>;
78
+ /**
79
+ *
80
+ */
81
+ globalMatrix?: IObjectAccessor<TBabylon, TBabylon, Matrix>;
82
+ /**
83
+ *
84
+ */
85
+ visible?: IObjectAccessor<TBabylon, TBabylon, boolean>;
86
+ }
87
+ /**
88
+ * Resolves JSON Pointer paths in the `/extensions/BABYLON_scene_objects/...`
89
+ * namespace to Babylon scene objects.
90
+ *
91
+ * The path layout is `/{root}/{collection}/{uniqueId}/{property}` where
92
+ * `{root}` is the literal `extensions/BABYLON_scene_objects` prefix and
93
+ * `{uniqueId}` is the Babylon `uniqueId` (stable per session) of the target
94
+ * instance. For example:
95
+ *
96
+ * - `/extensions/BABYLON_scene_objects/transformNodes/42/translation`
97
+ * - `/extensions/BABYLON_scene_objects/meshes/17/visible`
98
+ *
99
+ * Composite path dispatchers (see {@link CompositePathToObjectConverter})
100
+ * route paths starting with the prefix here; everything else continues to be
101
+ * resolved by the standard glTF converter.
102
+ */
103
+ export declare class BabylonScenePathToObjectConverter implements IPathToObjectConverter<IObjectAccessor> {
104
+ private _scene;
105
+ private _tree;
106
+ constructor(_scene: Scene, _tree: IBabylonSceneObjectModelTree);
107
+ /**
108
+ * @param path the full JSON Pointer (must start with the Babylon prefix)
109
+ * @returns an object-info container holding the resolved instance and accessor
110
+ */
111
+ convert(path: string): IObjectInfo<IObjectAccessor>;
112
+ private _getCollectionArray;
113
+ private _lookupInstanceByUniqueId;
114
+ private _buildIdentityAccessor;
115
+ }
116
+ /**
117
+ * Builds the default Babylon-scene object-model tree.
118
+ *
119
+ * We deliberately start with a minimal set of properties: the goal of this
120
+ * tree is to prove the seam (refs in the BABYLON namespace resolving through
121
+ * the same `FlowGraphJsonPointerParserBlock` that the glTF refs use) without
122
+ * committing to a complete property surface in this PR. Add new leaves here
123
+ * as concrete event-source operations need them.
124
+ * @returns a fresh Babylon-scene object-model tree with the default property surface.
125
+ */
126
+ export declare function CreateDefaultBabylonSceneObjectModelTree(): IBabylonSceneObjectModelTree;
@@ -0,0 +1,251 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention */
2
+ import { Quaternion } from "@babylonjs/core/Maths/math.vector.js";
3
+ /**
4
+ * Root of the JSON-Pointer namespace under which Babylon-scene objects are
5
+ * addressed by KHR_interactivity refs that did not originate from the source
6
+ * glTF asset (e.g. refs emitted by engine-specific event blocks).
7
+ *
8
+ * Trailing `/` is intentional: it lets path-prefix dispatchers like
9
+ * {@link CompositePathToObjectConverter} match cleanly.
10
+ */
11
+ export const BABYLON_SCENE_OBJECT_MODEL_PREFIX = "/extensions/BABYLON_scene_objects/";
12
+ /**
13
+ * Resolves JSON Pointer paths in the `/extensions/BABYLON_scene_objects/...`
14
+ * namespace to Babylon scene objects.
15
+ *
16
+ * The path layout is `/{root}/{collection}/{uniqueId}/{property}` where
17
+ * `{root}` is the literal `extensions/BABYLON_scene_objects` prefix and
18
+ * `{uniqueId}` is the Babylon `uniqueId` (stable per session) of the target
19
+ * instance. For example:
20
+ *
21
+ * - `/extensions/BABYLON_scene_objects/transformNodes/42/translation`
22
+ * - `/extensions/BABYLON_scene_objects/meshes/17/visible`
23
+ *
24
+ * Composite path dispatchers (see {@link CompositePathToObjectConverter})
25
+ * route paths starting with the prefix here; everything else continues to be
26
+ * resolved by the standard glTF converter.
27
+ */
28
+ export class BabylonScenePathToObjectConverter {
29
+ constructor(_scene, _tree) {
30
+ this._scene = _scene;
31
+ this._tree = _tree;
32
+ }
33
+ /**
34
+ * @param path the full JSON Pointer (must start with the Babylon prefix)
35
+ * @returns an object-info container holding the resolved instance and accessor
36
+ */
37
+ convert(path) {
38
+ if (!path.startsWith(BABYLON_SCENE_OBJECT_MODEL_PREFIX)) {
39
+ throw new Error(`BabylonScenePathToObjectConverter: path "${path}" does not start with the expected prefix "${BABYLON_SCENE_OBJECT_MODEL_PREFIX}".`);
40
+ }
41
+ // Strip the namespace prefix and split. Ignore trailing empty segments
42
+ // so refs of the form "/extensions/BABYLON_scene_objects/transformNodes/42/" parse cleanly.
43
+ const tail = path.slice(BABYLON_SCENE_OBJECT_MODEL_PREFIX.length);
44
+ const parts = tail.split("/").filter((p) => p.length > 0);
45
+ if (parts.length === 0) {
46
+ throw new Error(`BabylonScenePathToObjectConverter: path "${path}" is missing a collection name.`);
47
+ }
48
+ const collectionName = parts[0];
49
+ const collection = this._tree[collectionName];
50
+ if (!collection) {
51
+ throw new Error(`BabylonScenePathToObjectConverter: unknown collection "${collectionName}" in path "${path}".`);
52
+ }
53
+ // Handle `<collection>.length` (no instance lookup).
54
+ if (parts.length === 2 && parts[1] === "length") {
55
+ const arr = this._getCollectionArray(collectionName);
56
+ return { object: arr, info: collection.length };
57
+ }
58
+ if (parts.length < 2) {
59
+ throw new Error(`BabylonScenePathToObjectConverter: path "${path}" is missing an instance id.`);
60
+ }
61
+ // parseInt would accept "12abc" as 12; require an all-digits id so a malformed path fails
62
+ // loudly instead of binding to the wrong instance.
63
+ if (!/^\d+$/.test(parts[1])) {
64
+ throw new Error(`BabylonScenePathToObjectConverter: invalid uniqueId "${parts[1]}" in path "${path}".`);
65
+ }
66
+ const uniqueId = parseInt(parts[1], 10);
67
+ if (!Number.isFinite(uniqueId) || uniqueId < 0) {
68
+ throw new Error(`BabylonScenePathToObjectConverter: invalid uniqueId "${parts[1]}" in path "${path}".`);
69
+ }
70
+ const instance = this._lookupInstanceByUniqueId(collectionName, uniqueId);
71
+ if (!instance) {
72
+ throw new Error(`BabylonScenePathToObjectConverter: no ${collectionName} instance found with uniqueId ${uniqueId} (path "${path}").`);
73
+ }
74
+ // No property after the id → the ref itself is just a handle to the instance.
75
+ // The accessor's `get` and `getTarget` both return the instance.
76
+ if (parts.length === 2) {
77
+ return {
78
+ object: instance,
79
+ info: this._buildIdentityAccessor(instance),
80
+ };
81
+ }
82
+ // Walk the leaf descriptors for the requested property path. We keep this
83
+ // very simple right now: only one segment after the id is supported, which
84
+ // covers every property the initial leaves expose. Nested paths can be
85
+ // added later by extending the walker.
86
+ if (parts.length > 3) {
87
+ throw new Error(`BabylonScenePathToObjectConverter: nested property paths are not yet supported (path "${path}").`);
88
+ }
89
+ const propertyName = parts[2];
90
+ const leaf = collection.__array__[propertyName];
91
+ if (!leaf || typeof leaf === "boolean") {
92
+ throw new Error(`BabylonScenePathToObjectConverter: property "${propertyName}" is not registered on ${collectionName} (path "${path}").`);
93
+ }
94
+ return {
95
+ object: instance,
96
+ info: leaf,
97
+ };
98
+ }
99
+ _getCollectionArray(collectionName) {
100
+ switch (collectionName) {
101
+ case "transformNodes":
102
+ return this._scene.transformNodes;
103
+ case "meshes":
104
+ return this._scene.meshes;
105
+ case "materials":
106
+ return this._scene.materials;
107
+ default:
108
+ return [];
109
+ }
110
+ }
111
+ _lookupInstanceByUniqueId(collectionName, uniqueId) {
112
+ switch (collectionName) {
113
+ case "transformNodes": {
114
+ const direct = this._scene.transformNodes.find((n) => n.uniqueId === uniqueId);
115
+ if (direct) {
116
+ return direct;
117
+ }
118
+ // Meshes are also transform nodes; allow the same path to resolve them.
119
+ return this._scene.meshes.find((m) => m.uniqueId === uniqueId);
120
+ }
121
+ case "meshes":
122
+ return this._scene.meshes.find((m) => m.uniqueId === uniqueId);
123
+ case "materials":
124
+ return this._scene.materials.find((m) => m.uniqueId === uniqueId);
125
+ default:
126
+ return undefined;
127
+ }
128
+ }
129
+ _buildIdentityAccessor(instance) {
130
+ return {
131
+ type: "object",
132
+ get: () => instance,
133
+ getTarget: () => instance,
134
+ isReadOnly: true,
135
+ };
136
+ }
137
+ }
138
+ /**
139
+ * Builds the default Babylon-scene object-model tree.
140
+ *
141
+ * We deliberately start with a minimal set of properties: the goal of this
142
+ * tree is to prove the seam (refs in the BABYLON namespace resolving through
143
+ * the same `FlowGraphJsonPointerParserBlock` that the glTF refs use) without
144
+ * committing to a complete property surface in this PR. Add new leaves here
145
+ * as concrete event-source operations need them.
146
+ * @returns a fresh Babylon-scene object-model tree with the default property surface.
147
+ */
148
+ export function CreateDefaultBabylonSceneObjectModelTree() {
149
+ return {
150
+ transformNodes: {
151
+ length: {
152
+ type: "number",
153
+ get: (arr) => arr.length,
154
+ getTarget: (arr) => arr,
155
+ },
156
+ __array__: {
157
+ __target__: true,
158
+ name: {
159
+ type: "string",
160
+ get: (n) => n.name,
161
+ set: (v, n) => {
162
+ n.name = v;
163
+ },
164
+ getTarget: (n) => n,
165
+ },
166
+ translation: {
167
+ type: "Vector3",
168
+ get: (n) => n.position,
169
+ set: (v, n) => n.position.copyFrom(v),
170
+ getTarget: (n) => n,
171
+ },
172
+ rotation: {
173
+ type: "Quaternion",
174
+ get: (n) => n.rotationQuaternion ?? Quaternion.RotationYawPitchRoll(n.rotation.y, n.rotation.x, n.rotation.z),
175
+ set: (v, n) => {
176
+ if (!n.rotationQuaternion) {
177
+ n.rotationQuaternion = v.clone();
178
+ }
179
+ else {
180
+ n.rotationQuaternion.copyFrom(v);
181
+ }
182
+ },
183
+ getTarget: (n) => n,
184
+ },
185
+ scale: {
186
+ type: "Vector3",
187
+ get: (n) => n.scaling,
188
+ set: (v, n) => n.scaling.copyFrom(v),
189
+ getTarget: (n) => n,
190
+ },
191
+ matrix: {
192
+ type: "Matrix",
193
+ get: (n) => n.computeWorldMatrix(false),
194
+ getTarget: (n) => n,
195
+ isReadOnly: true,
196
+ },
197
+ globalMatrix: {
198
+ type: "Matrix",
199
+ get: (n) => n.computeWorldMatrix(true),
200
+ getTarget: (n) => n,
201
+ isReadOnly: true,
202
+ },
203
+ },
204
+ },
205
+ meshes: {
206
+ length: {
207
+ type: "number",
208
+ get: (arr) => arr.length,
209
+ getTarget: (arr) => arr,
210
+ },
211
+ __array__: {
212
+ __target__: true,
213
+ name: {
214
+ type: "string",
215
+ get: (m) => m.name,
216
+ set: (v, m) => {
217
+ m.name = v;
218
+ },
219
+ getTarget: (m) => m,
220
+ },
221
+ visible: {
222
+ type: "boolean",
223
+ get: (m) => m.isVisible,
224
+ set: (v, m) => {
225
+ m.isVisible = v;
226
+ },
227
+ getTarget: (m) => m,
228
+ },
229
+ },
230
+ },
231
+ materials: {
232
+ length: {
233
+ type: "number",
234
+ get: (arr) => arr.length,
235
+ getTarget: (arr) => arr,
236
+ },
237
+ __array__: {
238
+ __target__: true,
239
+ name: {
240
+ type: "string",
241
+ get: (m) => m.name,
242
+ set: (v, m) => {
243
+ m.name = v;
244
+ },
245
+ getTarget: (m) => m,
246
+ },
247
+ },
248
+ },
249
+ };
250
+ }
251
+ //# sourceMappingURL=babylonScenePathToObjectConverter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"babylonScenePathToObjectConverter.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/babylonScenePathToObjectConverter.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\nimport { type Scene } from \"core/scene\";\r\nimport { type TransformNode } from \"core/Meshes/transformNode\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { type Material } from \"core/Materials/material\";\r\nimport { type Vector3, Quaternion, type Matrix } from \"core/Maths/math.vector\";\r\nimport { type IObjectAccessor } from \"core/FlowGraph/typeDefinitions\";\r\nimport { type IObjectInfo, type IPathToObjectConverter } from \"core/ObjectModel/objectModelInterfaces\";\r\n\r\n/**\r\n * Root of the JSON-Pointer namespace under which Babylon-scene objects are\r\n * addressed by KHR_interactivity refs that did not originate from the source\r\n * glTF asset (e.g. refs emitted by engine-specific event blocks).\r\n *\r\n * Trailing `/` is intentional: it lets path-prefix dispatchers like\r\n * {@link CompositePathToObjectConverter} match cleanly.\r\n */\r\nexport const BABYLON_SCENE_OBJECT_MODEL_PREFIX = \"/extensions/BABYLON_scene_objects/\";\r\n\r\n/**\r\n * Shape of the Babylon-scene object model tree consumed by\r\n * {@link BabylonScenePathToObjectConverter}. Mirrors `IGLTFObjectModelTree`\r\n * but is rooted at scene-asset arrays (`transformNodes`, `meshes`, …) and\r\n * keyed by Babylon `uniqueId`. Initially we only expose the property leaves\r\n * needed to validate the seam end-to-end; future leaves can be added without\r\n * any path-converter changes.\r\n */\r\nexport interface IBabylonSceneObjectModelTree {\r\n /**\r\n *\r\n */\r\n transformNodes: IBabylonObjectCollection<TransformNode>;\r\n /**\r\n *\r\n */\r\n meshes: IBabylonObjectCollection<AbstractMesh>;\r\n /**\r\n *\r\n */\r\n materials: IBabylonObjectCollection<Material>;\r\n}\r\n\r\n/**\r\n * Generic per-collection node in the tree. `length` exposes a `.length`\r\n * accessor (mirroring glTF). `__array__` is the per-instance leaf hit when a\r\n * uniqueId index appears in the path.\r\n */\r\nexport interface IBabylonObjectCollection<TBabylon> {\r\n /**\r\n *\r\n */\r\n length: IObjectAccessor<TBabylon[], TBabylon[], number>;\r\n /**\r\n *\r\n */\r\n __array__: IBabylonObjectLeaves<TBabylon>;\r\n}\r\n\r\n/** Per-instance accessors. Add new properties here as they are needed. */\r\nexport interface IBabylonObjectLeaves<TBabylon> {\r\n /** Marks this position as a `getTarget` boundary so the resolver can hand back the instance itself. */\r\n __target__?: boolean;\r\n /**\r\n *\r\n */\r\n name?: IObjectAccessor<TBabylon, TBabylon, string>;\r\n /**\r\n *\r\n */\r\n translation?: IObjectAccessor<TBabylon, TBabylon, Vector3>;\r\n /**\r\n *\r\n */\r\n rotation?: IObjectAccessor<TBabylon, TBabylon, Quaternion>;\r\n /**\r\n *\r\n */\r\n scale?: IObjectAccessor<TBabylon, TBabylon, Vector3>;\r\n /**\r\n *\r\n */\r\n matrix?: IObjectAccessor<TBabylon, TBabylon, Matrix>;\r\n /**\r\n *\r\n */\r\n globalMatrix?: IObjectAccessor<TBabylon, TBabylon, Matrix>;\r\n /**\r\n *\r\n */\r\n visible?: IObjectAccessor<TBabylon, TBabylon, boolean>;\r\n}\r\n\r\n/**\r\n * Type aliases used internally to keep the per-property accessor signatures\r\n * narrow without forcing every leaf to be re-typed at the use site.\r\n */\r\ntype AnyAccessor = IObjectAccessor<any, any, any>;\r\n\r\n/**\r\n * Resolves JSON Pointer paths in the `/extensions/BABYLON_scene_objects/...`\r\n * namespace to Babylon scene objects.\r\n *\r\n * The path layout is `/{root}/{collection}/{uniqueId}/{property}` where\r\n * `{root}` is the literal `extensions/BABYLON_scene_objects` prefix and\r\n * `{uniqueId}` is the Babylon `uniqueId` (stable per session) of the target\r\n * instance. For example:\r\n *\r\n * - `/extensions/BABYLON_scene_objects/transformNodes/42/translation`\r\n * - `/extensions/BABYLON_scene_objects/meshes/17/visible`\r\n *\r\n * Composite path dispatchers (see {@link CompositePathToObjectConverter})\r\n * route paths starting with the prefix here; everything else continues to be\r\n * resolved by the standard glTF converter.\r\n */\r\nexport class BabylonScenePathToObjectConverter implements IPathToObjectConverter<IObjectAccessor> {\r\n public constructor(\r\n private _scene: Scene,\r\n private _tree: IBabylonSceneObjectModelTree\r\n ) {}\r\n\r\n /**\r\n * @param path the full JSON Pointer (must start with the Babylon prefix)\r\n * @returns an object-info container holding the resolved instance and accessor\r\n */\r\n public convert(path: string): IObjectInfo<IObjectAccessor> {\r\n if (!path.startsWith(BABYLON_SCENE_OBJECT_MODEL_PREFIX)) {\r\n throw new Error(`BabylonScenePathToObjectConverter: path \"${path}\" does not start with the expected prefix \"${BABYLON_SCENE_OBJECT_MODEL_PREFIX}\".`);\r\n }\r\n\r\n // Strip the namespace prefix and split. Ignore trailing empty segments\r\n // so refs of the form \"/extensions/BABYLON_scene_objects/transformNodes/42/\" parse cleanly.\r\n const tail = path.slice(BABYLON_SCENE_OBJECT_MODEL_PREFIX.length);\r\n const parts = tail.split(\"/\").filter((p) => p.length > 0);\r\n if (parts.length === 0) {\r\n throw new Error(`BabylonScenePathToObjectConverter: path \"${path}\" is missing a collection name.`);\r\n }\r\n\r\n const collectionName = parts[0];\r\n const collection = (this._tree as unknown as Record<string, IBabylonObjectCollection<any> | undefined>)[collectionName];\r\n if (!collection) {\r\n throw new Error(`BabylonScenePathToObjectConverter: unknown collection \"${collectionName}\" in path \"${path}\".`);\r\n }\r\n\r\n // Handle `<collection>.length` (no instance lookup).\r\n if (parts.length === 2 && parts[1] === \"length\") {\r\n const arr = this._getCollectionArray(collectionName);\r\n return { object: arr, info: collection.length as AnyAccessor };\r\n }\r\n\r\n if (parts.length < 2) {\r\n throw new Error(`BabylonScenePathToObjectConverter: path \"${path}\" is missing an instance id.`);\r\n }\r\n\r\n // parseInt would accept \"12abc\" as 12; require an all-digits id so a malformed path fails\r\n // loudly instead of binding to the wrong instance.\r\n if (!/^\\d+$/.test(parts[1])) {\r\n throw new Error(`BabylonScenePathToObjectConverter: invalid uniqueId \"${parts[1]}\" in path \"${path}\".`);\r\n }\r\n const uniqueId = parseInt(parts[1], 10);\r\n if (!Number.isFinite(uniqueId) || uniqueId < 0) {\r\n throw new Error(`BabylonScenePathToObjectConverter: invalid uniqueId \"${parts[1]}\" in path \"${path}\".`);\r\n }\r\n\r\n const instance = this._lookupInstanceByUniqueId(collectionName, uniqueId);\r\n if (!instance) {\r\n throw new Error(`BabylonScenePathToObjectConverter: no ${collectionName} instance found with uniqueId ${uniqueId} (path \"${path}\").`);\r\n }\r\n\r\n // No property after the id → the ref itself is just a handle to the instance.\r\n // The accessor's `get` and `getTarget` both return the instance.\r\n if (parts.length === 2) {\r\n return {\r\n object: instance,\r\n info: this._buildIdentityAccessor(instance),\r\n };\r\n }\r\n\r\n // Walk the leaf descriptors for the requested property path. We keep this\r\n // very simple right now: only one segment after the id is supported, which\r\n // covers every property the initial leaves expose. Nested paths can be\r\n // added later by extending the walker.\r\n if (parts.length > 3) {\r\n throw new Error(`BabylonScenePathToObjectConverter: nested property paths are not yet supported (path \"${path}\").`);\r\n }\r\n const propertyName = parts[2];\r\n const leaf = (collection.__array__ as Record<string, IObjectAccessor<any, any, any> | boolean | undefined>)[propertyName];\r\n if (!leaf || typeof leaf === \"boolean\") {\r\n throw new Error(`BabylonScenePathToObjectConverter: property \"${propertyName}\" is not registered on ${collectionName} (path \"${path}\").`);\r\n }\r\n\r\n return {\r\n object: instance,\r\n info: leaf as AnyAccessor,\r\n };\r\n }\r\n\r\n private _getCollectionArray(collectionName: string): readonly any[] {\r\n switch (collectionName) {\r\n case \"transformNodes\":\r\n return this._scene.transformNodes;\r\n case \"meshes\":\r\n return this._scene.meshes;\r\n case \"materials\":\r\n return this._scene.materials;\r\n default:\r\n return [];\r\n }\r\n }\r\n\r\n private _lookupInstanceByUniqueId(collectionName: string, uniqueId: number): unknown | undefined {\r\n switch (collectionName) {\r\n case \"transformNodes\": {\r\n const direct = this._scene.transformNodes.find((n) => n.uniqueId === uniqueId);\r\n if (direct) {\r\n return direct;\r\n }\r\n // Meshes are also transform nodes; allow the same path to resolve them.\r\n return this._scene.meshes.find((m) => m.uniqueId === uniqueId);\r\n }\r\n case \"meshes\":\r\n return this._scene.meshes.find((m) => m.uniqueId === uniqueId);\r\n case \"materials\":\r\n return this._scene.materials.find((m) => m.uniqueId === uniqueId);\r\n default:\r\n return undefined;\r\n }\r\n }\r\n\r\n private _buildIdentityAccessor(instance: unknown): AnyAccessor {\r\n return {\r\n type: \"object\",\r\n get: () => instance,\r\n getTarget: () => instance,\r\n isReadOnly: true,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Builds the default Babylon-scene object-model tree.\r\n *\r\n * We deliberately start with a minimal set of properties: the goal of this\r\n * tree is to prove the seam (refs in the BABYLON namespace resolving through\r\n * the same `FlowGraphJsonPointerParserBlock` that the glTF refs use) without\r\n * committing to a complete property surface in this PR. Add new leaves here\r\n * as concrete event-source operations need them.\r\n * @returns a fresh Babylon-scene object-model tree with the default property surface.\r\n */\r\nexport function CreateDefaultBabylonSceneObjectModelTree(): IBabylonSceneObjectModelTree {\r\n return {\r\n transformNodes: {\r\n length: {\r\n type: \"number\",\r\n get: (arr: TransformNode[]) => arr.length,\r\n getTarget: (arr: TransformNode[]) => arr,\r\n },\r\n __array__: {\r\n __target__: true,\r\n name: {\r\n type: \"string\",\r\n get: (n: TransformNode) => n.name,\r\n set: (v: string, n: TransformNode) => {\r\n n.name = v;\r\n },\r\n getTarget: (n: TransformNode) => n,\r\n },\r\n translation: {\r\n type: \"Vector3\",\r\n get: (n: TransformNode) => n.position,\r\n set: (v: Vector3, n: TransformNode) => n.position.copyFrom(v),\r\n getTarget: (n: TransformNode) => n,\r\n },\r\n rotation: {\r\n type: \"Quaternion\",\r\n get: (n: TransformNode) => n.rotationQuaternion ?? Quaternion.RotationYawPitchRoll(n.rotation.y, n.rotation.x, n.rotation.z),\r\n set: (v: Quaternion, n: TransformNode) => {\r\n if (!n.rotationQuaternion) {\r\n n.rotationQuaternion = v.clone();\r\n } else {\r\n n.rotationQuaternion.copyFrom(v);\r\n }\r\n },\r\n getTarget: (n: TransformNode) => n,\r\n },\r\n scale: {\r\n type: \"Vector3\",\r\n get: (n: TransformNode) => n.scaling,\r\n set: (v: Vector3, n: TransformNode) => n.scaling.copyFrom(v),\r\n getTarget: (n: TransformNode) => n,\r\n },\r\n matrix: {\r\n type: \"Matrix\",\r\n get: (n: TransformNode) => n.computeWorldMatrix(false),\r\n getTarget: (n: TransformNode) => n,\r\n isReadOnly: true,\r\n },\r\n globalMatrix: {\r\n type: \"Matrix\",\r\n get: (n: TransformNode) => n.computeWorldMatrix(true),\r\n getTarget: (n: TransformNode) => n,\r\n isReadOnly: true,\r\n },\r\n },\r\n },\r\n meshes: {\r\n length: {\r\n type: \"number\",\r\n get: (arr: AbstractMesh[]) => arr.length,\r\n getTarget: (arr: AbstractMesh[]) => arr,\r\n },\r\n __array__: {\r\n __target__: true,\r\n name: {\r\n type: \"string\",\r\n get: (m: AbstractMesh) => m.name,\r\n set: (v: string, m: AbstractMesh) => {\r\n m.name = v;\r\n },\r\n getTarget: (m: AbstractMesh) => m,\r\n },\r\n visible: {\r\n type: \"boolean\",\r\n get: (m: AbstractMesh) => m.isVisible,\r\n set: (v: boolean, m: AbstractMesh) => {\r\n m.isVisible = v;\r\n },\r\n getTarget: (m: AbstractMesh) => m,\r\n },\r\n },\r\n },\r\n materials: {\r\n length: {\r\n type: \"number\",\r\n get: (arr: Material[]) => arr.length,\r\n getTarget: (arr: Material[]) => arr,\r\n },\r\n __array__: {\r\n __target__: true,\r\n name: {\r\n type: \"string\",\r\n get: (m: Material) => m.name,\r\n set: (v: string, m: Material) => {\r\n m.name = v;\r\n },\r\n getTarget: (m: Material) => m,\r\n },\r\n },\r\n },\r\n };\r\n}\r\n"]}
@@ -0,0 +1,51 @@
1
+ import { type IObjectInfo, type IPathToObjectConverter } from "@babylonjs/core/ObjectModel/objectModelInterfaces.js";
2
+ /**
3
+ * Entry in the composite converter's prefix table. The first entry whose
4
+ * `prefix` matches the start of the path wins.
5
+ */
6
+ export interface IPathConverterPrefixEntry<T> {
7
+ /** Path prefix to match, e.g. `"/extensions/BABYLON_scene_objects/"`. */
8
+ prefix: string;
9
+ /** Converter to delegate to when the path starts with `prefix`. */
10
+ converter: IPathToObjectConverter<T>;
11
+ }
12
+ /**
13
+ * Composite path-to-object converter that dispatches by path prefix.
14
+ *
15
+ * The KHR_interactivity object model lives at the top of the JSON tree
16
+ * (`/nodes/...`, `/materials/...`, `/extensions/...`) and is resolved by
17
+ * `GLTFPathToObjectConverter` (see `gltfPathToObjectConverter`).
18
+ *
19
+ * Babylon-specific extensions can register additional namespaces here
20
+ * (for example `/extensions/BABYLON_scene_objects/...` for refs that point
21
+ * at scene objects not described by the source glTF) without forcing every
22
+ * caller to know about them — `FlowGraphJsonPointerParserBlock` and the
23
+ * existing template substitution machinery treat any path uniformly.
24
+ *
25
+ * Prefix entries are tried in order; if none matches, the fallback converter
26
+ * is used. The fallback is typically the glTF converter, since standard
27
+ * KHR_interactivity pointer paths sit at the JSON root and have no shared
28
+ * prefix that would distinguish them from a missing namespace.
29
+ */
30
+ export declare class CompositePathToObjectConverter<T> implements IPathToObjectConverter<T> {
31
+ private _prefixes;
32
+ private _fallback;
33
+ /**
34
+ * @param _prefixes prefix-keyed converter table, tried in order
35
+ * @param _fallback converter used when no prefix entry matches
36
+ */
37
+ constructor(_prefixes: IPathConverterPrefixEntry<T>[], _fallback: IPathToObjectConverter<T>);
38
+ /**
39
+ * Adds a new prefix entry at the front of the lookup list so it is tried
40
+ * before any entries registered earlier. Useful for late-registered
41
+ * loader extensions that want to override or augment a previously
42
+ * registered namespace.
43
+ * @param entry the entry to add
44
+ */
45
+ addPrefix(entry: IPathConverterPrefixEntry<T>): void;
46
+ /**
47
+ * @param path the JSON Pointer path to resolve
48
+ * @returns an object accessor for the resolved property
49
+ */
50
+ convert(path: string): IObjectInfo<T>;
51
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Composite path-to-object converter that dispatches by path prefix.
3
+ *
4
+ * The KHR_interactivity object model lives at the top of the JSON tree
5
+ * (`/nodes/...`, `/materials/...`, `/extensions/...`) and is resolved by
6
+ * `GLTFPathToObjectConverter` (see `gltfPathToObjectConverter`).
7
+ *
8
+ * Babylon-specific extensions can register additional namespaces here
9
+ * (for example `/extensions/BABYLON_scene_objects/...` for refs that point
10
+ * at scene objects not described by the source glTF) without forcing every
11
+ * caller to know about them — `FlowGraphJsonPointerParserBlock` and the
12
+ * existing template substitution machinery treat any path uniformly.
13
+ *
14
+ * Prefix entries are tried in order; if none matches, the fallback converter
15
+ * is used. The fallback is typically the glTF converter, since standard
16
+ * KHR_interactivity pointer paths sit at the JSON root and have no shared
17
+ * prefix that would distinguish them from a missing namespace.
18
+ */
19
+ export class CompositePathToObjectConverter {
20
+ /**
21
+ * @param _prefixes prefix-keyed converter table, tried in order
22
+ * @param _fallback converter used when no prefix entry matches
23
+ */
24
+ constructor(_prefixes, _fallback) {
25
+ this._prefixes = _prefixes;
26
+ this._fallback = _fallback;
27
+ }
28
+ /**
29
+ * Adds a new prefix entry at the front of the lookup list so it is tried
30
+ * before any entries registered earlier. Useful for late-registered
31
+ * loader extensions that want to override or augment a previously
32
+ * registered namespace.
33
+ * @param entry the entry to add
34
+ */
35
+ addPrefix(entry) {
36
+ this._prefixes.unshift(entry);
37
+ }
38
+ /**
39
+ * @param path the JSON Pointer path to resolve
40
+ * @returns an object accessor for the resolved property
41
+ */
42
+ convert(path) {
43
+ for (const { prefix, converter } of this._prefixes) {
44
+ if (path.startsWith(prefix)) {
45
+ return converter.convert(path);
46
+ }
47
+ }
48
+ return this._fallback.convert(path);
49
+ }
50
+ }
51
+ //# sourceMappingURL=compositePathToObjectConverter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositePathToObjectConverter.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/compositePathToObjectConverter.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,8BAA8B;IACvC;;;OAGG;IACH,YACY,SAAyC,EACzC,SAAoC;QADpC,cAAS,GAAT,SAAS,CAAgC;QACzC,cAAS,GAAT,SAAS,CAA2B;IAC7C,CAAC;IAEJ;;;;;;OAMG;IACI,SAAS,CAAC,KAAmC;QAChD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACI,OAAO,CAAC,IAAY;QACvB,KAAK,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjD,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,OAAO,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;CACJ","sourcesContent":["import { type IObjectInfo, type IPathToObjectConverter } from \"core/ObjectModel/objectModelInterfaces\";\r\n\r\n/**\r\n * Entry in the composite converter's prefix table. The first entry whose\r\n * `prefix` matches the start of the path wins.\r\n */\r\nexport interface IPathConverterPrefixEntry<T> {\r\n /** Path prefix to match, e.g. `\"/extensions/BABYLON_scene_objects/\"`. */\r\n prefix: string;\r\n /** Converter to delegate to when the path starts with `prefix`. */\r\n converter: IPathToObjectConverter<T>;\r\n}\r\n\r\n/**\r\n * Composite path-to-object converter that dispatches by path prefix.\r\n *\r\n * The KHR_interactivity object model lives at the top of the JSON tree\r\n * (`/nodes/...`, `/materials/...`, `/extensions/...`) and is resolved by\r\n * `GLTFPathToObjectConverter` (see `gltfPathToObjectConverter`).\r\n *\r\n * Babylon-specific extensions can register additional namespaces here\r\n * (for example `/extensions/BABYLON_scene_objects/...` for refs that point\r\n * at scene objects not described by the source glTF) without forcing every\r\n * caller to know about them — `FlowGraphJsonPointerParserBlock` and the\r\n * existing template substitution machinery treat any path uniformly.\r\n *\r\n * Prefix entries are tried in order; if none matches, the fallback converter\r\n * is used. The fallback is typically the glTF converter, since standard\r\n * KHR_interactivity pointer paths sit at the JSON root and have no shared\r\n * prefix that would distinguish them from a missing namespace.\r\n */\r\nexport class CompositePathToObjectConverter<T> implements IPathToObjectConverter<T> {\r\n /**\r\n * @param _prefixes prefix-keyed converter table, tried in order\r\n * @param _fallback converter used when no prefix entry matches\r\n */\r\n public constructor(\r\n private _prefixes: IPathConverterPrefixEntry<T>[],\r\n private _fallback: IPathToObjectConverter<T>\r\n ) {}\r\n\r\n /**\r\n * Adds a new prefix entry at the front of the lookup list so it is tried\r\n * before any entries registered earlier. Useful for late-registered\r\n * loader extensions that want to override or augment a previously\r\n * registered namespace.\r\n * @param entry the entry to add\r\n */\r\n public addPrefix(entry: IPathConverterPrefixEntry<T>): void {\r\n this._prefixes.unshift(entry);\r\n }\r\n\r\n /**\r\n * @param path the JSON Pointer path to resolve\r\n * @returns an object accessor for the resolved property\r\n */\r\n public convert(path: string): IObjectInfo<T> {\r\n for (const { prefix, converter } of this._prefixes) {\r\n if (path.startsWith(prefix)) {\r\n return converter.convert(path);\r\n }\r\n }\r\n return this._fallback.convert(path);\r\n }\r\n}\r\n"]}