@combeenation/3d-viewer 16.0.0 → 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/lib-cjs/buildinfo.json +1 -1
- package/dist/lib-cjs/commonjs.tsconfig.tsbuildinfo +1 -1
- package/dist/lib-cjs/helper/decals-helper.d.ts +0 -8
- package/dist/lib-cjs/helper/decals-helper.js +20 -17
- package/dist/lib-cjs/helper/decals-helper.js.map +1 -1
- package/dist/lib-cjs/index.d.ts +3 -0
- package/dist/lib-cjs/index.js +3 -0
- package/dist/lib-cjs/index.js.map +1 -1
- package/dist/lib-cjs/internal/cbn-custom-babylon-loader-plugin.js +9 -1
- package/dist/lib-cjs/internal/cbn-custom-babylon-loader-plugin.js.map +1 -1
- package/dist/lib-cjs/internal/cloning-helper.d.ts +3 -2
- package/dist/lib-cjs/internal/cloning-helper.js +66 -43
- package/dist/lib-cjs/internal/cloning-helper.js.map +1 -1
- package/dist/lib-cjs/internal/metadata-helper.d.ts +15 -13
- package/dist/lib-cjs/internal/metadata-helper.js +11 -17
- package/dist/lib-cjs/internal/metadata-helper.js.map +1 -1
- package/dist/lib-cjs/internal/tags-helper.js +9 -9
- package/dist/lib-cjs/internal/tags-helper.js.map +1 -1
- package/dist/lib-cjs/manager/debug-manager.d.ts +11 -19
- package/dist/lib-cjs/manager/debug-manager.js +67 -50
- package/dist/lib-cjs/manager/debug-manager.js.map +1 -1
- package/dist/lib-cjs/manager/gltf-export-manager.js +2 -7
- package/dist/lib-cjs/manager/gltf-export-manager.js.map +1 -1
- package/dist/lib-cjs/manager/material-manager.js +0 -1
- package/dist/lib-cjs/manager/material-manager.js.map +1 -1
- package/dist/lib-cjs/manager/model-manager.d.ts +9 -0
- package/dist/lib-cjs/manager/model-manager.js +19 -8
- package/dist/lib-cjs/manager/model-manager.js.map +1 -1
- package/dist/lib-cjs/manager/parameter-manager.d.ts +0 -14
- package/dist/lib-cjs/manager/parameter-manager.js +0 -19
- package/dist/lib-cjs/manager/parameter-manager.js.map +1 -1
- package/dist/lib-cjs/manager/texture-manager.js +1 -1
- package/dist/lib-cjs/manager/texture-manager.js.map +1 -1
- package/dist/lib-cjs/viewer.d.ts +1 -0
- package/dist/lib-cjs/viewer.js +10 -1
- package/dist/lib-cjs/viewer.js.map +1 -1
- package/package.json +12 -13
- package/src/helper/decals-helper.ts +27 -23
- package/src/index.ts +3 -0
- package/src/internal/cbn-custom-babylon-loader-plugin.ts +9 -1
- package/src/internal/cloning-helper.ts +83 -55
- package/src/internal/metadata-helper.ts +31 -28
- package/src/internal/tags-helper.ts +1 -2
- package/src/manager/debug-manager.ts +83 -81
- package/src/manager/gltf-export-manager.ts +4 -9
- package/src/manager/material-manager.ts +0 -2
- package/src/manager/model-manager.ts +31 -14
- package/src/manager/parameter-manager.ts +0 -24
- package/src/manager/texture-manager.ts +1 -1
- package/src/viewer.ts +13 -1
package/dist/lib-cjs/viewer.js
CHANGED
|
@@ -144,6 +144,7 @@ class Viewer {
|
|
|
144
144
|
* Only takes meshes into considerations that:
|
|
145
145
|
* - are visible
|
|
146
146
|
* - are not excluded by "excludeGeometry" parameter
|
|
147
|
+
* - do not have a material of type "BackgroundMaterial"
|
|
147
148
|
* - do not have an infinite distance (like sky boxes)
|
|
148
149
|
*/
|
|
149
150
|
calculateBoundingInfo(excludeGeometry) {
|
|
@@ -156,9 +157,11 @@ class Viewer {
|
|
|
156
157
|
const hasValidBBoxInfo = mesh.getBoundingInfo().boundingSphere.radius > 0;
|
|
157
158
|
// ignore meshes with infinite distance, typically these are sky boxes
|
|
158
159
|
const hasInfiniteDistance = mesh.infiniteDistance;
|
|
160
|
+
// ignore meshes with "BackgroundMaterial" - usually a ground or skybox
|
|
161
|
+
const hasBackgroundMaterial = mesh.material instanceof index_1.BackgroundMaterial;
|
|
159
162
|
// ignore excluded meshes
|
|
160
163
|
const isExcluded = excludeGeometry ? (0, geometry_helper_1.isNodeExcluded)(mesh, excludeGeometry) : false;
|
|
161
|
-
return isEnabled && hasValidBBoxInfo && !hasInfiniteDistance && !isExcluded;
|
|
164
|
+
return isEnabled && hasValidBBoxInfo && !hasInfiniteDistance && !hasBackgroundMaterial && !isExcluded;
|
|
162
165
|
})
|
|
163
166
|
.reduce((accBBoxMinMax, curMesh, idx) => {
|
|
164
167
|
curMesh.refreshBoundingInfo(true, true);
|
|
@@ -178,6 +181,12 @@ class Viewer {
|
|
|
178
181
|
// we use a custom plugin for ".babylon" files to be able to lazy load materials that were cropped by the CBN
|
|
179
182
|
// asset manager
|
|
180
183
|
(0, cbn_custom_babylon_loader_plugin_1.registerCustomCbnBabylonLoaderPlugin)();
|
|
184
|
+
// without setting this flag, meshes with billboard mode set would not integrate into the node tree structure,
|
|
185
|
+
// that means the position would not be updated by the rotation of the parent node
|
|
186
|
+
// it's a bit dangerous to set this globally, but we need that for:
|
|
187
|
+
// - `DebugManager.showCoordinateSystem`
|
|
188
|
+
// - probably dimensions line handling (not implemented yet)
|
|
189
|
+
index_1.TransformNode.BillboardUseParentOrientation = true;
|
|
181
190
|
const engine = new index_1.Engine(this.canvas, this._viewerSettings.antialiasing, (0, lodash_es_1.cloneDeep)(this._viewerSettings.engineOptions), this._viewerSettings.adaptToDeviceRatio);
|
|
182
191
|
const isScaledDownDevice = (0, device_helper_1.getIsScaledDownDevice)(this._viewerSettings.limitTextureSize);
|
|
183
192
|
if (this._viewerSettings.limitTextureSize && isScaledDownDevice) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/viewer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sEAAyC;AACzC,+CAAiC;AACjC,
|
|
1
|
+
{"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/viewer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@combeenation/3d-viewer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "17.0.0",
|
|
4
4
|
"description": "Combeenation 3D Viewer",
|
|
5
5
|
"homepage": "https://github.com/Combeenation/3d-viewer#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"pub-beta": "npm run dist-cjs && npm publish --tag beta",
|
|
42
42
|
"pub-final": "npm run dist-cjs && npm publish",
|
|
43
43
|
"pub-rc": "npm run dist-cjs && npm publish --tag rc",
|
|
44
|
-
"replace-version": "cross-env-shell replace \"@VERSION@\" $npm_package_version dist -r"
|
|
45
|
-
"types": "tsc --project declaration.tsconfig.json"
|
|
44
|
+
"replace-version": "cross-env-shell replace \"@VERSION@\" $npm_package_version dist -r"
|
|
46
45
|
},
|
|
47
46
|
"prettier": "@combeenation/prettier-config",
|
|
48
47
|
"dependencies": {
|
|
49
|
-
"@babylonjs/core": "7.
|
|
50
|
-
"@babylonjs/
|
|
51
|
-
"@babylonjs/
|
|
48
|
+
"@babylonjs/core": "7.34.3",
|
|
49
|
+
"@babylonjs/gui": "7.34.3",
|
|
50
|
+
"@babylonjs/loaders": "7.34.3",
|
|
51
|
+
"@babylonjs/serializers": "7.34.3",
|
|
52
52
|
"eventemitter3": "4.0.7",
|
|
53
53
|
"is-svg": "^5.0.0",
|
|
54
54
|
"lodash-es": "4.17.21"
|
|
@@ -78,15 +78,14 @@
|
|
|
78
78
|
"webpack-merge": "5.8.0"
|
|
79
79
|
},
|
|
80
80
|
"optionalDependencies": {
|
|
81
|
-
"@babylonjs/gui": "7.
|
|
82
|
-
"@babylonjs/
|
|
83
|
-
"@babylonjs/
|
|
84
|
-
"@babylonjs/
|
|
85
|
-
"@babylonjs/node-editor": "7.
|
|
86
|
-
"@babylonjs/node-geometry-editor": "7.30.1"
|
|
81
|
+
"@babylonjs/gui-editor": "7.34.3",
|
|
82
|
+
"@babylonjs/inspector": "7.34.3",
|
|
83
|
+
"@babylonjs/materials": "7.34.3",
|
|
84
|
+
"@babylonjs/node-editor": "7.34.3",
|
|
85
|
+
"@babylonjs/node-geometry-editor": "7.34.3"
|
|
87
86
|
},
|
|
88
87
|
"dependenciesComments": {
|
|
89
|
-
"@babylonjs": "Latest version 7.
|
|
88
|
+
"@babylonjs": "Latest version 7.34.3 enables us to overwrite the texture display name, which is shown in the inspector (https://forum.babylonjs.com/t/add-display-name-for-textures/54745), also tags are now shown in the inspector (https://forum.babylonjs.com/t/display-tags-in-the-inspector/42781)"
|
|
90
89
|
},
|
|
91
90
|
"optionalDependenciesComments": {
|
|
92
91
|
"@babylonjs": "Defining the inspector package (and it's dependencies) as optional is required to omit these packages in the production build of the CBN react-app (see CB-9269)"
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
IAssetContainer,
|
|
3
|
+
Material,
|
|
4
|
+
Mesh,
|
|
5
|
+
MeshBuilder,
|
|
6
|
+
Tuple,
|
|
7
|
+
Vector3,
|
|
8
|
+
VertexBuffer,
|
|
9
|
+
ViewerError,
|
|
10
|
+
ViewerErrorIds,
|
|
11
|
+
} from '..';
|
|
2
12
|
|
|
3
13
|
export const DEFAULT_DECAL_CONFIG = {
|
|
4
14
|
normal: [0, 0, 1],
|
|
5
15
|
angle: 0,
|
|
6
16
|
offset: 0.001,
|
|
7
|
-
scaling: [1, 1, 1],
|
|
8
17
|
captureUVS: false,
|
|
9
18
|
cullBackFaces: true,
|
|
10
19
|
localMode: true,
|
|
@@ -31,14 +40,6 @@ export type DecalConfiguration = {
|
|
|
31
40
|
*/
|
|
32
41
|
offset?: number;
|
|
33
42
|
|
|
34
|
-
/**
|
|
35
|
-
* Can be used for shifting the decal away from the source mesh as alternative to `offset`.\
|
|
36
|
-
* Use this setting when the offset should be applied in radial direction (e.g. cylinders)
|
|
37
|
-
*
|
|
38
|
-
* Default `[1, 1, 1]` (no offset through scaling)
|
|
39
|
-
*/
|
|
40
|
-
scaling?: Tuple<number, 3>;
|
|
41
|
-
|
|
42
43
|
/**
|
|
43
44
|
* `true`: Use UV mapping from source mesh\
|
|
44
45
|
* `false`: Use default box mapping from the decal
|
|
@@ -86,15 +87,9 @@ export function createDecalMesh(config: DecalConfiguration, assetContainer: IAss
|
|
|
86
87
|
});
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
const position = Vector3.FromArray(config.position);
|
|
90
|
-
const normal = Vector3.FromArray(config.normal ?? DEFAULT_DECAL_CONFIG.normal).normalizeToNew();
|
|
91
|
-
|
|
92
|
-
const localMode = config.localMode ?? DEFAULT_DECAL_CONFIG.localMode;
|
|
93
|
-
const worldNormal = localMode ? Vector3.TransformNormal(normal, sourceMesh.getWorldMatrix()) : normal;
|
|
94
|
-
|
|
95
90
|
const decalMesh = MeshBuilder.CreateDecal(config.name, sourceMesh, {
|
|
96
|
-
position: position,
|
|
97
|
-
normal: normal,
|
|
91
|
+
position: Vector3.FromArray(config.position),
|
|
92
|
+
normal: Vector3.FromArray(config.normal ?? DEFAULT_DECAL_CONFIG.normal).normalizeToNew(),
|
|
98
93
|
size: Vector3.FromArray(config.size),
|
|
99
94
|
angle: config.angle ?? DEFAULT_DECAL_CONFIG.angle,
|
|
100
95
|
captureUVS: config.captureUVS ?? DEFAULT_DECAL_CONFIG.captureUVS,
|
|
@@ -115,11 +110,20 @@ export function createDecalMesh(config: DecalConfiguration, assetContainer: IAss
|
|
|
115
110
|
|
|
116
111
|
// move decal away from mesh to avoid clipping
|
|
117
112
|
// NOTE: zOffset of material can't be used, since it's not supported in glTF and therefore not usable in AR
|
|
118
|
-
const
|
|
119
|
-
decalMesh.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
113
|
+
const positions = decalMesh.getVerticesData(VertexBuffer.PositionKind);
|
|
114
|
+
const normals = decalMesh.getVerticesData(VertexBuffer.NormalKind);
|
|
115
|
+
|
|
116
|
+
if (positions && normals) {
|
|
117
|
+
const offset = config.offset ?? DEFAULT_DECAL_CONFIG.offset;
|
|
118
|
+
// move each vertice individually along it's dedicated normal
|
|
119
|
+
for (let i = 0; i < positions.length; i += 3) {
|
|
120
|
+
positions[i] += normals[i] * offset;
|
|
121
|
+
positions[i + 1] += normals[i + 1] * offset;
|
|
122
|
+
positions[i + 2] += normals[i + 2] * offset;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
decalMesh.setVerticesData(VertexBuffer.PositionKind, positions);
|
|
126
|
+
}
|
|
123
127
|
|
|
124
128
|
return decalMesh;
|
|
125
129
|
}
|
package/src/index.ts
CHANGED
|
@@ -36,11 +36,14 @@ export * from '@babylonjs/core/Meshes/meshBuilder';
|
|
|
36
36
|
export * from '@babylonjs/core/Meshes/transformNode';
|
|
37
37
|
export * from '@babylonjs/core/Misc/interfaces/screenshotSize';
|
|
38
38
|
export * from '@babylonjs/core/Misc/screenshotTools';
|
|
39
|
+
export * from '@babylonjs/core/Misc/tags';
|
|
39
40
|
export * from '@babylonjs/core/Morph';
|
|
40
41
|
export * from '@babylonjs/core/node';
|
|
41
42
|
export * from '@babylonjs/core/Rendering/utilityLayerRenderer';
|
|
42
43
|
export * from '@babylonjs/core/scene';
|
|
43
44
|
export * from '@babylonjs/core/types';
|
|
45
|
+
export * from '@babylonjs/gui/2D/advancedDynamicTexture';
|
|
46
|
+
export * from '@babylonjs/gui/2D/controls/textBlock';
|
|
44
47
|
export * from '@babylonjs/loaders/glTF/2.0/glTFLoader';
|
|
45
48
|
export * from '@babylonjs/serializers/glTF/2.0/glTFSerializer';
|
|
46
49
|
|
|
@@ -63,7 +63,15 @@ export function registerCustomCbnBabylonLoaderPlugin(): void {
|
|
|
63
63
|
|
|
64
64
|
_addMissingMaterialMetadata(dataParsed, importedContainer);
|
|
65
65
|
_reconstructTagsForInstancedMeshes(dataParsed, importedContainer);
|
|
66
|
-
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
_createDecals(dataParsed, importedContainer);
|
|
69
|
+
} catch (e) {
|
|
70
|
+
// Errors are generally swallowed by the Babylon.js `loadAssetContainer` implementation, resulting in generic
|
|
71
|
+
// error message and losing the information about the original error
|
|
72
|
+
// When forwarding the message in the `onError` callback at least the message can be preserved
|
|
73
|
+
onError?.((e as Error).message);
|
|
74
|
+
}
|
|
67
75
|
|
|
68
76
|
// add `cbnData` to output asset container, so that this information can be store as metadata for the model
|
|
69
77
|
const extendedContainer = importedContainer as ExtendedAssetContainer;
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
clearInternalMetadataValue,
|
|
15
15
|
cloneInternalMetadata,
|
|
16
|
-
cloneMetadata,
|
|
17
16
|
getInternalMetadataValue,
|
|
18
17
|
setInternalMetadataValue,
|
|
19
18
|
} from './metadata-helper';
|
|
@@ -39,38 +38,41 @@ const _defaultTagNamingStrategy: TagNamingStrategy = (tag: string, clonedObjectI
|
|
|
39
38
|
export function cloneModelAssetContainer(
|
|
40
39
|
sourceAssetContainer: AssetContainer,
|
|
41
40
|
newModelName: string,
|
|
42
|
-
|
|
41
|
+
scene: Scene,
|
|
42
|
+
options?: {
|
|
43
|
+
createInstance?: boolean;
|
|
43
44
|
nodeNamingStrategy?: NodeNamingStrategy;
|
|
44
45
|
tagNamingStrategy?: TagNamingStrategy;
|
|
45
|
-
}
|
|
46
|
-
scene: Scene
|
|
46
|
+
}
|
|
47
47
|
): AssetContainer {
|
|
48
|
+
const createInstance = !!options?.createInstance;
|
|
49
|
+
|
|
48
50
|
const targetAssetContainer = new AssetContainer(scene);
|
|
49
51
|
|
|
50
52
|
sourceAssetContainer.rootNodes.forEach(node => {
|
|
51
53
|
if (node instanceof TransformNode) {
|
|
52
54
|
// this is the actual node tree cloning procedure
|
|
53
|
-
_cloneNode(node, newModelName, null, targetAssetContainer,
|
|
54
|
-
nodeNamingStrategy: renaming?.nodeNamingStrategy,
|
|
55
|
-
tagNamingStrategy: renaming?.tagNamingStrategy,
|
|
56
|
-
});
|
|
55
|
+
_cloneNode(node, newModelName, null, targetAssetContainer, options);
|
|
57
56
|
}
|
|
58
57
|
});
|
|
59
58
|
|
|
60
59
|
targetAssetContainer.populateRootNodes();
|
|
61
|
-
targetAssetContainer.rootNodes.forEach(node => {
|
|
62
|
-
if (node instanceof TransformNode) {
|
|
63
|
-
// reassigning instanced meshes can only be done after the model has been fully cloned, as we can't be sure if
|
|
64
|
-
// the source or instanced mesh is handled prior
|
|
65
|
-
_reAssignSourceMesh(node, sourceAssetContainer.meshes, targetAssetContainer.meshes);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
60
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
if (!createInstance) {
|
|
62
|
+
targetAssetContainer.rootNodes.forEach(node => {
|
|
63
|
+
if (node instanceof TransformNode) {
|
|
64
|
+
// reassigning instanced meshes can only be done after the model has been fully cloned, as we can't be sure if
|
|
65
|
+
// the source or instanced mesh is handled prior
|
|
66
|
+
_reAssignSourceMesh(node, sourceAssetContainer.meshes, targetAssetContainer.meshes);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// morph target manager is not cloned per default, therefore morph targets would affect original and cloned model at
|
|
71
|
+
// the same time, which we don't want
|
|
72
|
+
sourceAssetContainer.morphTargetManagers.forEach(sourceMTM => {
|
|
73
|
+
_cloneMorphTargetManager(sourceMTM, targetAssetContainer);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
74
76
|
|
|
75
77
|
_clearCloningMetadata(sourceAssetContainer);
|
|
76
78
|
_clearCloningMetadata(targetAssetContainer);
|
|
@@ -136,47 +138,77 @@ function _cloneNode(
|
|
|
136
138
|
newModelName: string,
|
|
137
139
|
newParent: TransformNode | null,
|
|
138
140
|
assetContainer: AssetContainer,
|
|
139
|
-
|
|
141
|
+
options?: {
|
|
142
|
+
createInstance?: boolean;
|
|
140
143
|
nodeNamingStrategy?: NodeNamingStrategy;
|
|
141
144
|
tagNamingStrategy?: TagNamingStrategy;
|
|
142
145
|
}
|
|
143
146
|
): void {
|
|
144
|
-
const nodeNamingStrategy =
|
|
145
|
-
const tagNamingStrategy =
|
|
147
|
+
const nodeNamingStrategy = options?.nodeNamingStrategy ?? _defaultNodeNamingStrategy;
|
|
148
|
+
const tagNamingStrategy = options?.tagNamingStrategy ?? _defaultTagNamingStrategy;
|
|
146
149
|
|
|
147
150
|
const cloneName = nodeNamingStrategy(node, newModelName);
|
|
148
|
-
const clone = node.clone(cloneName, newParent, true);
|
|
149
|
-
if (!clone) {
|
|
150
|
-
throw new Error(`Cloning node "${node.name}" failed`);
|
|
151
|
-
}
|
|
152
151
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
// ATM the assignment from clone to source is needed for reassigning instanced meshes after cloning
|
|
158
|
-
// may be usefull for other node types in the future as well
|
|
159
|
-
setInternalMetadataValue(clone, 'cloneSource', node.uniqueId);
|
|
160
|
-
setInternalMetadataValue(node, 'cloneTarget', clone.uniqueId);
|
|
152
|
+
const createInstance = options?.createInstance && node instanceof Mesh && !!node.getTotalVertices();
|
|
153
|
+
let resultNode: TransformNode;
|
|
154
|
+
if (createInstance) {
|
|
155
|
+
const instance = node.createInstance(cloneName);
|
|
161
156
|
|
|
162
|
-
|
|
163
|
-
|
|
157
|
+
_cloneInstancedMeshData(node, instance);
|
|
158
|
+
|
|
159
|
+
instance.parent = newParent;
|
|
160
|
+
instance.position = node.position.clone();
|
|
161
|
+
instance.rotation = node.rotation.clone();
|
|
162
|
+
instance.scaling = node.scaling.clone();
|
|
163
|
+
|
|
164
|
+
if (node.rotationQuaternion) {
|
|
165
|
+
instance.rotationQuaternion = node.rotationQuaternion.clone();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
resultNode = instance;
|
|
169
|
+
} else {
|
|
170
|
+
const clone = node.clone(cloneName, newParent, true);
|
|
171
|
+
if (!clone) {
|
|
172
|
+
throw new Error(`Cloning node "${node.name}" failed`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (node instanceof InstancedMesh) {
|
|
176
|
+
_cloneInstancedMeshData(node, clone as InstancedMesh);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// create a shallow clone for internal metadata, as the default clone function just assignes the sources internal
|
|
180
|
+
// metadata
|
|
181
|
+
cloneInternalMetadata(node, clone);
|
|
182
|
+
|
|
183
|
+
// NOTE: "public" metadata are not cloned by default, we rely on the Babylon.js default behaviour:
|
|
184
|
+
// - execute metadata.clone function if there is one
|
|
185
|
+
// - assign the metadata of the original node to the clone other wise
|
|
186
|
+
// making deep copies of the node metadata might be an optional flag in the cloning functions in the future
|
|
187
|
+
|
|
188
|
+
// ATM the assignment from clone to source is needed for reassigning instanced meshes after cloning
|
|
189
|
+
// may be usefull for other node types in the future as well
|
|
190
|
+
setInternalMetadataValue(clone, 'cloneSource', node.uniqueId);
|
|
191
|
+
setInternalMetadataValue(node, 'cloneTarget', clone.uniqueId);
|
|
192
|
+
|
|
193
|
+
resultNode = clone;
|
|
164
194
|
}
|
|
165
195
|
|
|
196
|
+
resultNode.id = cloneName;
|
|
197
|
+
|
|
166
198
|
const sourceTags = getTags(node);
|
|
167
199
|
const mappedTags = sourceTags.map(tag => tagNamingStrategy(tag, newModelName));
|
|
168
|
-
setTags(
|
|
200
|
+
setTags(resultNode, mappedTags);
|
|
169
201
|
|
|
170
|
-
|
|
202
|
+
resultNode._parentContainer = assetContainer;
|
|
171
203
|
// TODO WTT: create global helper function for distinguishing between transform nodes and meshes
|
|
172
|
-
if (
|
|
173
|
-
assetContainer.meshes.push(
|
|
204
|
+
if (resultNode instanceof AbstractMesh) {
|
|
205
|
+
assetContainer.meshes.push(resultNode);
|
|
174
206
|
} else {
|
|
175
|
-
assetContainer.transformNodes.push(
|
|
207
|
+
assetContainer.transformNodes.push(resultNode);
|
|
176
208
|
}
|
|
177
209
|
|
|
178
210
|
const children = node.getChildTransformNodes(true);
|
|
179
|
-
children.forEach(child => _cloneNode(child, newModelName,
|
|
211
|
+
children.forEach(child => _cloneNode(child, newModelName, resultNode, assetContainer, options));
|
|
180
212
|
}
|
|
181
213
|
|
|
182
214
|
/**
|
|
@@ -189,16 +221,10 @@ function _reAssignSourceMesh(node: TransformNode, sourceMeshes: AbstractMesh[],
|
|
|
189
221
|
if (node instanceof InstancedMesh) {
|
|
190
222
|
// find the cloned instance and source mesh
|
|
191
223
|
const clonedInstance = node;
|
|
192
|
-
const originalInstance = _findByUniqueId(
|
|
193
|
-
sourceMeshes,
|
|
194
|
-
getInternalMetadataValue(clonedInstance, 'cloneSource') as number
|
|
195
|
-
);
|
|
224
|
+
const originalInstance = _findByUniqueId(sourceMeshes, getInternalMetadataValue(clonedInstance, 'cloneSource'));
|
|
196
225
|
if (originalInstance instanceof InstancedMesh) {
|
|
197
226
|
const originalSource = originalInstance.sourceMesh;
|
|
198
|
-
const clonedSource = _findByUniqueId(
|
|
199
|
-
clonedMeshes,
|
|
200
|
-
getInternalMetadataValue(originalSource, 'cloneTarget') as number
|
|
201
|
-
);
|
|
227
|
+
const clonedSource = _findByUniqueId(clonedMeshes, getInternalMetadataValue(originalSource, 'cloneTarget'));
|
|
202
228
|
if (clonedSource instanceof Mesh) {
|
|
203
229
|
// it's not possible to just exchange the source mesh => readonly property
|
|
204
230
|
// we have to create a new clone with the correct source mesh
|
|
@@ -238,10 +264,12 @@ function _clearCloningMetadata(assetContainer: AssetContainer): void {
|
|
|
238
264
|
* correctly.
|
|
239
265
|
* This function adjusts the behaviour to fulfill our expectations.
|
|
240
266
|
*/
|
|
241
|
-
function _cloneInstancedMeshData(
|
|
242
|
-
targetInstancedMesh.setEnabled(
|
|
243
|
-
|
|
244
|
-
|
|
267
|
+
function _cloneInstancedMeshData(sourceMesh: AbstractMesh, targetInstancedMesh: InstancedMesh): void {
|
|
268
|
+
targetInstancedMesh.setEnabled(sourceMesh.isEnabled(false));
|
|
269
|
+
|
|
270
|
+
// handling of tags and metadata is exactly the same as in the original Babylon.js code
|
|
271
|
+
cloneTags(sourceMesh, targetInstancedMesh);
|
|
272
|
+
targetInstancedMesh.metadata = sourceMesh.metadata?.clone?.() ?? sourceMesh.metadata;
|
|
245
273
|
}
|
|
246
274
|
|
|
247
275
|
function _findByUniqueId(nodes: TransformNode[], uniqueId: number): TransformNode | undefined {
|
|
@@ -1,29 +1,36 @@
|
|
|
1
1
|
import { BaseTexture, Material, Node } from '../index';
|
|
2
|
-
import { cloneDeep } from 'lodash-es';
|
|
3
2
|
|
|
4
|
-
type MetadataValue = string | number | boolean | object | undefined;
|
|
5
3
|
type MetadataTarget = Node | Material | BaseTexture;
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
// this map contains all allowed metadata keys and the associated typings, which can then be used as generic of the API
|
|
6
|
+
// functions
|
|
7
|
+
// IMPORTANT: only use primitive types (string|number|boolean) for metadata as we rely on shallow copying
|
|
8
|
+
type MetadataValueMap = {
|
|
7
9
|
// CBN babylon loader
|
|
8
|
-
|
|
10
|
+
deferredMaterial: string;
|
|
9
11
|
// material manager
|
|
10
|
-
|
|
12
|
+
materialToBeSet: string;
|
|
11
13
|
// GLTF export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
exportNode: boolean;
|
|
15
|
+
deleteAfterExport: boolean;
|
|
16
|
+
exchangeMaterialWith: number;
|
|
15
17
|
// cloning
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
cloneSource: number;
|
|
19
|
+
cloneTarget: number;
|
|
20
|
+
};
|
|
21
|
+
type MetadataKeys = keyof MetadataValueMap;
|
|
18
22
|
|
|
19
|
-
// TODO WTT: use generics or some kind of logic that is able to type the metadata according to their key
|
|
20
23
|
/**
|
|
21
24
|
* Sets certain metadata on the objects INTERNAL metadata storage.
|
|
22
25
|
* "object._internalMetadata.cbn" is reserved for CBN specific metadata information.
|
|
23
26
|
* The objects public metadata ("object.metadata") is not affected and should therefore not interfere with metadata
|
|
24
27
|
* that is used in consumer projects.
|
|
25
28
|
*/
|
|
26
|
-
export function setInternalMetadataValue
|
|
29
|
+
export function setInternalMetadataValue<K extends MetadataKeys>(
|
|
30
|
+
object: MetadataTarget,
|
|
31
|
+
key: K,
|
|
32
|
+
value: MetadataValueMap[K]
|
|
33
|
+
): void {
|
|
27
34
|
if (!object._internalMetadata) {
|
|
28
35
|
object._internalMetadata = {};
|
|
29
36
|
}
|
|
@@ -38,26 +45,22 @@ export function clearInternalMetadataValue(object: MetadataTarget, key: Metadata
|
|
|
38
45
|
delete object._internalMetadata?.cbn?.[key];
|
|
39
46
|
}
|
|
40
47
|
|
|
41
|
-
export function getInternalMetadataValue(object: MetadataTarget, key:
|
|
48
|
+
export function getInternalMetadataValue<K extends MetadataKeys>(object: MetadataTarget, key: K): MetadataValueMap[K] {
|
|
42
49
|
return object._internalMetadata?.cbn?.[key];
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
53
|
+
* This only creates a (shallow) clone of the CBN internal metadata, as we need to have individual metadata for our
|
|
54
|
+
* viewer state handling in each node.
|
|
55
|
+
* The rest, which is coming from Babylon.js directly, is left untouched as we don't interfere with this data anyway.
|
|
49
56
|
*/
|
|
50
57
|
export function cloneInternalMetadata(sourceObject: MetadataTarget, targetObject: MetadataTarget): void {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
export function cloneMetadata(sourceObject: MetadataTarget, targetObject: MetadataTarget): void {
|
|
60
|
-
const clonedMetadata = cloneDeep(sourceObject.metadata);
|
|
61
|
-
|
|
62
|
-
targetObject.metadata = clonedMetadata;
|
|
58
|
+
if (!sourceObject._internalMetadata?.cbn) {
|
|
59
|
+
targetObject._internalMetadata = sourceObject._internalMetadata;
|
|
60
|
+
} else {
|
|
61
|
+
targetObject._internalMetadata = {
|
|
62
|
+
...sourceObject._internalMetadata,
|
|
63
|
+
cbn: { ...sourceObject._internalMetadata.cbn },
|
|
64
|
+
};
|
|
65
|
+
}
|
|
63
66
|
}
|