@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
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AdvancedDynamicTexture,
|
|
2
3
|
AxesViewer,
|
|
3
4
|
BoundingSphere,
|
|
4
5
|
Color3,
|
|
5
|
-
DynamicTexture,
|
|
6
6
|
IInspectorOptions,
|
|
7
|
+
Matrix,
|
|
8
|
+
Mesh,
|
|
7
9
|
MeshBuilder,
|
|
8
|
-
Scene,
|
|
9
10
|
StandardMaterial,
|
|
11
|
+
TextBlock,
|
|
10
12
|
TransformNode,
|
|
11
13
|
UtilityLayerRenderer,
|
|
12
14
|
Vector3,
|
|
@@ -14,19 +16,10 @@ import {
|
|
|
14
16
|
ViewerEvent,
|
|
15
17
|
} from '../index';
|
|
16
18
|
|
|
17
|
-
type DebugAxisKeys = 'X' | 'Y' | 'Z';
|
|
18
|
-
type DebugAxisConfig = { color: Color3; position: Vector3 };
|
|
19
|
-
|
|
20
19
|
/**
|
|
21
20
|
* Manager for debugging functionalities
|
|
22
21
|
*/
|
|
23
22
|
export class DebugManager {
|
|
24
|
-
protected static _DEBUG_AXIS_MAP: Record<DebugAxisKeys, DebugAxisConfig> = {
|
|
25
|
-
X: { color: Color3.Red().scale(0.5), position: new Vector3(1, 0, 0) },
|
|
26
|
-
Y: { color: Color3.Green().scale(0.5), position: new Vector3(0, 1, 0) },
|
|
27
|
-
Z: { color: Color3.Blue().scale(0.5), position: new Vector3(0, 0, 1) },
|
|
28
|
-
};
|
|
29
|
-
protected static _WORLD_COORD_ROOT_KEY = '__world_coordinates__';
|
|
30
23
|
protected static _BOUNDING_SPHERE_KEY = '__bounding_sphere__';
|
|
31
24
|
|
|
32
25
|
protected _axesViewer: AxesViewer | null = null;
|
|
@@ -91,38 +84,63 @@ The inspector can only be used in development builds.`);
|
|
|
91
84
|
}
|
|
92
85
|
|
|
93
86
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
87
|
+
* Displays the coordinate system.\
|
|
88
|
+
* Shows the local coordinate system of a specified node or the world coordinate system if no node is provided.\
|
|
89
|
+
* The size defaults to one-third of the scene's bounding sphere radius but can be set manually.
|
|
96
90
|
*/
|
|
97
|
-
public
|
|
91
|
+
public showCoordinateSystem(node?: TransformNode, size?: number): void {
|
|
92
|
+
// calculate the default size of not provided
|
|
93
|
+
if (!size) {
|
|
94
|
+
const sceneBoundingInfo = this.viewer.calculateBoundingInfo();
|
|
95
|
+
const radius = sceneBoundingInfo.boundingSphere.radius;
|
|
96
|
+
|
|
97
|
+
// takes a third of the radius from scene boundingsphere
|
|
98
|
+
size = radius * (1 / 3);
|
|
99
|
+
}
|
|
100
|
+
|
|
98
101
|
// make sure to remove already existing debug coordinate systems
|
|
99
|
-
this.
|
|
102
|
+
this.hideCoordinateSystem();
|
|
100
103
|
|
|
101
104
|
// draw in utility layer, so that there is no interaction with the actually scene content
|
|
102
105
|
// (e.g. glb export, autofocus)
|
|
103
106
|
const utilityLayerScene = UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;
|
|
104
|
-
|
|
105
|
-
const worldCoordRoot = new TransformNode(DebugManager._WORLD_COORD_ROOT_KEY, utilityLayerScene);
|
|
106
107
|
// axes viewer coordinate system is a bit too large
|
|
107
108
|
// multiply with unify factor to create arrows which exactly match the length of the input dimension
|
|
108
109
|
const factor = DebugManager._getWorldCoordinatesAxesUnifyFactor();
|
|
109
|
-
this._axesViewer = new AxesViewer(utilityLayerScene,
|
|
110
|
+
this._axesViewer = new AxesViewer(utilityLayerScene, size * factor);
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
if (node) {
|
|
113
|
+
// get the world rotation of the mesh and extract the x, y, z axes from that
|
|
114
|
+
// NOTE: `node.getDirection` can't be used because it considers the scaling as well, resulting in distorted axes
|
|
115
|
+
const worldRotMatrix = new Matrix();
|
|
116
|
+
node.absoluteRotationQuaternion.toRotationMatrix(worldRotMatrix);
|
|
115
117
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
const xAxis = Vector3.FromArray(worldRotMatrix.m.slice(0, 3)); // First column
|
|
119
|
+
const yAxis = Vector3.FromArray(worldRotMatrix.m.slice(4, 7)); // Second column
|
|
120
|
+
const zAxis = Vector3.FromArray(worldRotMatrix.m.slice(8, 11)); // Third column
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
// consider scaling only for axis direction
|
|
123
|
+
if (node.absoluteScaling.x < 0) {
|
|
124
|
+
xAxis.scaleInPlace(-1);
|
|
125
|
+
}
|
|
126
|
+
if (node.absoluteScaling.y < 0) {
|
|
127
|
+
yAxis.scaleInPlace(-1);
|
|
128
|
+
}
|
|
129
|
+
if (node.absoluteScaling.z < 0) {
|
|
130
|
+
zAxis.scaleInPlace(-1);
|
|
131
|
+
}
|
|
121
132
|
|
|
122
|
-
|
|
123
|
-
if (worldCoordRoot) {
|
|
124
|
-
worldCoordRoot.dispose(false, true);
|
|
133
|
+
this._axesViewer.update(node.absolutePosition, xAxis, yAxis, zAxis);
|
|
125
134
|
}
|
|
135
|
+
|
|
136
|
+
DebugManager._prepareAxisVisual('X', this._axesViewer.xAxis);
|
|
137
|
+
DebugManager._prepareAxisVisual('Y', this._axesViewer.yAxis);
|
|
138
|
+
DebugManager._prepareAxisVisual('Z', this._axesViewer.zAxis);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public hideCoordinateSystem(): void {
|
|
142
|
+
this._axesViewer?.dispose();
|
|
143
|
+
this._axesViewer = null;
|
|
126
144
|
}
|
|
127
145
|
|
|
128
146
|
/**
|
|
@@ -138,58 +156,6 @@ The inspector can only be used in development builds.`);
|
|
|
138
156
|
this._removeBoundingSphereForAutofocus();
|
|
139
157
|
}
|
|
140
158
|
|
|
141
|
-
/**
|
|
142
|
-
* Adjust and enhance coordinate axes to fulfill our needs.
|
|
143
|
-
* - moves nodes into common root
|
|
144
|
-
* - adds text node
|
|
145
|
-
*/
|
|
146
|
-
protected static _prepareWorldCoordinateAxis(
|
|
147
|
-
text: 'X' | 'Y' | 'Z',
|
|
148
|
-
axis: TransformNode,
|
|
149
|
-
root: TransformNode,
|
|
150
|
-
dimension: number,
|
|
151
|
-
utilityLayerScene: Scene
|
|
152
|
-
): void {
|
|
153
|
-
// create unique names
|
|
154
|
-
axis.name = `${DebugManager._WORLD_COORD_ROOT_KEY}.${text}`;
|
|
155
|
-
axis.parent = root;
|
|
156
|
-
|
|
157
|
-
// create text mesh via dynamic texture
|
|
158
|
-
const dynamicTexture = new DynamicTexture(
|
|
159
|
-
`${DebugManager._WORLD_COORD_ROOT_KEY}.${text}`,
|
|
160
|
-
50,
|
|
161
|
-
utilityLayerScene,
|
|
162
|
-
true
|
|
163
|
-
);
|
|
164
|
-
dynamicTexture.hasAlpha = true;
|
|
165
|
-
// 42.5 is a magic offset, so that the text is vertically centered for font size 50px
|
|
166
|
-
// horizontal centering works well with the standard behaviour of Babylon.js (setting "null" as "width")
|
|
167
|
-
dynamicTexture.drawText(text, null, 42.5, 'bold 50px Arial', 'white', 'transparent', true);
|
|
168
|
-
|
|
169
|
-
const material = new StandardMaterial(`${DebugManager._WORLD_COORD_ROOT_KEY}.${text}`, utilityLayerScene);
|
|
170
|
-
material.disableLighting = true;
|
|
171
|
-
material.emissiveColor = DebugManager._DEBUG_AXIS_MAP[text].color;
|
|
172
|
-
material.diffuseTexture = dynamicTexture;
|
|
173
|
-
|
|
174
|
-
const plane = MeshBuilder.CreatePlane(
|
|
175
|
-
`${DebugManager._WORLD_COORD_ROOT_KEY}.${text}.TextPlane`,
|
|
176
|
-
{ size: dimension / 10 },
|
|
177
|
-
utilityLayerScene
|
|
178
|
-
);
|
|
179
|
-
// make sure that text is located outside of arrow
|
|
180
|
-
plane.position = DebugManager._DEBUG_AXIS_MAP[text].position.multiplyByFloats(
|
|
181
|
-
dimension * 1.05,
|
|
182
|
-
dimension * 1.05,
|
|
183
|
-
dimension * 1.05
|
|
184
|
-
);
|
|
185
|
-
plane.parent = root;
|
|
186
|
-
plane.material = material;
|
|
187
|
-
// will be rendered on top of "default" meshes => taken from Babylon.js repo "AxesViewer" implementation
|
|
188
|
-
plane.renderingGroupId = 2;
|
|
189
|
-
// setting billboard mode ensures, that the text is always readable
|
|
190
|
-
plane.billboardMode = TransformNode.BILLBOARDMODE_ALL;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
159
|
/**
|
|
194
160
|
* Calculate factor for creating world coordinate axes with exactly one unit in length
|
|
195
161
|
*/
|
|
@@ -208,6 +174,42 @@ The inspector can only be used in development builds.`);
|
|
|
208
174
|
return factor;
|
|
209
175
|
}
|
|
210
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Creates and adds a label with a direction letter at the tip of each axis arrow.\
|
|
179
|
+
* Also adjust the brightness of the arrow and created label.
|
|
180
|
+
*/
|
|
181
|
+
protected static _prepareAxisVisual(labelText: string, axisNode: TransformNode): void {
|
|
182
|
+
// fixed values used for label size and distance
|
|
183
|
+
const colorScale = 2; // used to multiply the original color scale of 0.5 - result is 1
|
|
184
|
+
const labelSize = 0.05;
|
|
185
|
+
const labelDistance = 0.4;
|
|
186
|
+
|
|
187
|
+
// inherit the color from the arrow and adjust brightness scaling to be 1
|
|
188
|
+
const axisMesh = axisNode.getChildMeshes()[0];
|
|
189
|
+
const axisMaterial = axisMesh.material as StandardMaterial;
|
|
190
|
+
const color = axisMaterial.emissiveColor.clone().scale(colorScale);
|
|
191
|
+
|
|
192
|
+
axisMaterial.emissiveColor = color;
|
|
193
|
+
|
|
194
|
+
const utilityLayerScene = UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;
|
|
195
|
+
const labelPlane = MeshBuilder.CreatePlane(`${labelText}_label`, { size: labelSize }, utilityLayerScene);
|
|
196
|
+
labelPlane.parent = axisNode;
|
|
197
|
+
labelPlane.position = new Vector3(0, 0, labelDistance);
|
|
198
|
+
// keep orientation of mesh, so that it is always visible, independent of the camera position
|
|
199
|
+
labelPlane.billboardMode = Mesh.BILLBOARDMODE_ALL;
|
|
200
|
+
|
|
201
|
+
// create GUI element
|
|
202
|
+
const textElement = new TextBlock();
|
|
203
|
+
textElement.text = labelText;
|
|
204
|
+
textElement.color = color.toHexString();
|
|
205
|
+
textElement.fontSize = '100%';
|
|
206
|
+
textElement.fontFamily = 'Arial';
|
|
207
|
+
textElement.fontWeight = 'bold';
|
|
208
|
+
|
|
209
|
+
const labelTexture = AdvancedDynamicTexture.CreateForMesh(labelPlane);
|
|
210
|
+
labelTexture.addControl(textElement);
|
|
211
|
+
}
|
|
212
|
+
|
|
211
213
|
/**
|
|
212
214
|
* Visualize bounding sphere which is used to zoom in via `autofocusActiveCamera` function
|
|
213
215
|
*/
|
|
@@ -19,6 +19,7 @@ import { bakeGeometryOfMesh, createMeshFromInstancedMesh, resetTransformation }
|
|
|
19
19
|
import { isNodeExcluded } from '../internal/geometry-helper';
|
|
20
20
|
import {
|
|
21
21
|
clearInternalMetadataValue,
|
|
22
|
+
cloneInternalMetadata,
|
|
22
23
|
getInternalMetadataValue,
|
|
23
24
|
setInternalMetadataValue,
|
|
24
25
|
} from '../internal/metadata-helper';
|
|
@@ -42,7 +43,7 @@ export class GltfExportManager {
|
|
|
42
43
|
shouldExportNode: function (node: Node): boolean {
|
|
43
44
|
if (optimizeForAR) {
|
|
44
45
|
// we explicitely marked nodes, that should be exported in AR mode
|
|
45
|
-
return getInternalMetadataValue(node, 'exportNode')
|
|
46
|
+
return getInternalMetadataValue(node, 'exportNode');
|
|
46
47
|
} else {
|
|
47
48
|
// use the default export node check (enabled state, exclusion list, etc...)
|
|
48
49
|
return GltfExportManager._shouldExportNode(node, excluded);
|
|
@@ -101,9 +102,7 @@ export class GltfExportManager {
|
|
|
101
102
|
|
|
102
103
|
const newName = `${material.name}_clone`;
|
|
103
104
|
const clonedMaterial = material.clone(newName)!;
|
|
104
|
-
|
|
105
|
-
// it wasn't an issue for materials yet, but still this is safer than to make a deep clone
|
|
106
|
-
clonedMaterial._internalMetadata = null;
|
|
105
|
+
cloneInternalMetadata(material, clonedMaterial);
|
|
107
106
|
const clonedTextures = clonedMaterial.getActiveTextures();
|
|
108
107
|
|
|
109
108
|
// mark all exported textures, so that they will be deleted after the export
|
|
@@ -310,11 +309,7 @@ export class GltfExportManager {
|
|
|
310
309
|
transformNode instanceof InstancedMesh
|
|
311
310
|
? createMeshFromInstancedMesh(transformNode, clonedNodeName, clonedParent)
|
|
312
311
|
: transformNode.clone(clonedNodeName, clonedParent, true)!;
|
|
313
|
-
|
|
314
|
-
// nodes with node geometry have very large internal metadata, this leads to long export times (CB-10094)
|
|
315
|
-
// existing internal metadata is not required for the export so we can just delete it
|
|
316
|
-
// internal metadata will be set some lines beyond!
|
|
317
|
-
clonedNode._internalMetadata = null;
|
|
312
|
+
cloneInternalMetadata(transformNode, clonedNode);
|
|
318
313
|
|
|
319
314
|
// exchange material
|
|
320
315
|
if (clonedNode instanceof Mesh) {
|
|
@@ -50,6 +50,14 @@ export type NodeNamingStrategy = (node: TransformNode, newModelName: string) =>
|
|
|
50
50
|
export type TagNamingStrategy = (tag: string, newModelName: string) => string;
|
|
51
51
|
|
|
52
52
|
export type ModelCloneOptions = {
|
|
53
|
+
/**
|
|
54
|
+
* `true:` Creates "[InstancedMeshes](https://doc.babylonjs.com/typedoc/classes/BABYLON.InstancedMesh)" from meshes of
|
|
55
|
+
* the base model instead of "independent" meshes. Most of the data, especially the geometry and material assignment
|
|
56
|
+
* is shared, only the transformation data (e.g. position) can be adjusted.\
|
|
57
|
+
* Activating this flag can lead to huge performance improvements, especially when working with a large amount of
|
|
58
|
+
* clones.
|
|
59
|
+
*/
|
|
60
|
+
createInstance?: boolean;
|
|
53
61
|
nodeNamingStrategy?: NodeNamingStrategy;
|
|
54
62
|
tagNamingStrategy?: TagNamingStrategy;
|
|
55
63
|
};
|
|
@@ -61,6 +69,8 @@ type Model = {
|
|
|
61
69
|
assetContainer: AssetContainer;
|
|
62
70
|
cbnBabylonFileData?: CbnBabylonFileData;
|
|
63
71
|
isClone: boolean;
|
|
72
|
+
// only set for "instantiated" clones
|
|
73
|
+
sourceModelName?: string;
|
|
64
74
|
visibilityCallId?: number;
|
|
65
75
|
};
|
|
66
76
|
|
|
@@ -288,16 +298,9 @@ export class ModelManager {
|
|
|
288
298
|
name: newModelName,
|
|
289
299
|
url: sourceModel.url,
|
|
290
300
|
state: 'loaded',
|
|
291
|
-
assetContainer: cloneModelAssetContainer(
|
|
292
|
-
sourceModel.assetContainer,
|
|
293
|
-
newModelName,
|
|
294
|
-
{
|
|
295
|
-
nodeNamingStrategy: options?.nodeNamingStrategy,
|
|
296
|
-
tagNamingStrategy: options?.tagNamingStrategy,
|
|
297
|
-
},
|
|
298
|
-
this.viewer.scene
|
|
299
|
-
),
|
|
301
|
+
assetContainer: cloneModelAssetContainer(sourceModel.assetContainer, newModelName, this.viewer.scene, options),
|
|
300
302
|
isClone: true,
|
|
303
|
+
sourceModelName: options?.createInstance ? sourceModel.name : undefined,
|
|
301
304
|
};
|
|
302
305
|
this._modelAssets[newModelName] = clonedModel;
|
|
303
306
|
|
|
@@ -329,10 +332,6 @@ export class ModelManager {
|
|
|
329
332
|
});
|
|
330
333
|
}
|
|
331
334
|
|
|
332
|
-
// parameter entries of deleted model can get in the way when recreating a clone with the same node names
|
|
333
|
-
// that's why it's benefitial to wipe the parameter entries of the model as well after removing it
|
|
334
|
-
this.viewer.parameterManager.removeParameterEntriesOfModel(model.assetContainer);
|
|
335
|
-
|
|
336
335
|
model.assetContainer.dispose();
|
|
337
336
|
|
|
338
337
|
delete this._modelAssets[name];
|
|
@@ -444,7 +443,7 @@ export class ModelManager {
|
|
|
444
443
|
} catch (e) {
|
|
445
444
|
throw new ViewerError({
|
|
446
445
|
id: ViewerErrorIds.AssetLoadingFailed,
|
|
447
|
-
message:
|
|
446
|
+
message: (e as Error).message,
|
|
448
447
|
});
|
|
449
448
|
}
|
|
450
449
|
|
|
@@ -453,6 +452,15 @@ export class ModelManager {
|
|
|
453
452
|
[...assetContainer.lights].forEach(light => light.dispose());
|
|
454
453
|
[...assetContainer.cameras].forEach(camera => camera.dispose());
|
|
455
454
|
|
|
455
|
+
// materials should be a "global" thing and not assigned to an asset container
|
|
456
|
+
// this is not relevant in most of the cases, since materials are cropped from babylon models on the CBN server
|
|
457
|
+
// anyway
|
|
458
|
+
assetContainer.materials.forEach(material => {
|
|
459
|
+
this.viewer.scene.addMaterial(material);
|
|
460
|
+
material._parentContainer = null;
|
|
461
|
+
});
|
|
462
|
+
assetContainer.materials = [];
|
|
463
|
+
|
|
456
464
|
// environment texture and intensity has been overwritten by load asset container function
|
|
457
465
|
this.viewer.scene.environmentTexture = curEnvTexture;
|
|
458
466
|
this.viewer.scene.environmentIntensity = curEnvIntensity;
|
|
@@ -473,6 +481,15 @@ export class ModelManager {
|
|
|
473
481
|
* a smooth model switch behaviour.
|
|
474
482
|
*/
|
|
475
483
|
protected async _prepareModelForScene(model: Model): Promise<void> {
|
|
484
|
+
if (model.sourceModelName) {
|
|
485
|
+
// source model has to be prepared for scene as well in "instantiate" mode, because materials would not be
|
|
486
|
+
// loaded otherwise
|
|
487
|
+
// => the instantiated model only consistes of Instanced Meshes and therefore has no material assignments on
|
|
488
|
+
// it's own
|
|
489
|
+
const sourceModel = this._getModel(model.sourceModelName)!;
|
|
490
|
+
await this._prepareModelForScene(sourceModel);
|
|
491
|
+
}
|
|
492
|
+
|
|
476
493
|
await this.viewer.parameterManager.applyAllParameterValuesToModel(model.assetContainer);
|
|
477
494
|
// parameter manager did his job, now apply the deferred materials to all meshes that are not explicitely hidden by
|
|
478
495
|
// the parameter manager
|
|
@@ -345,20 +345,6 @@ export class ParameterManager {
|
|
|
345
345
|
await this._applyParameterValues(this._parameterEntries, model);
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
-
/**
|
|
349
|
-
* Removes existing parameter entries of all nodes of a model.\
|
|
350
|
-
* This can be useful to clean up the parameter state when removing a (cloned) model.
|
|
351
|
-
*
|
|
352
|
-
* @internal
|
|
353
|
-
*/
|
|
354
|
-
public removeParameterEntriesOfModel(model: IAssetContainer): void {
|
|
355
|
-
const allNodeNames = [...model.meshes, ...model.transformNodes].map(node => node.name);
|
|
356
|
-
|
|
357
|
-
this._parameterEntries = this._parameterEntries.filter(
|
|
358
|
-
entry => !allNodeNames.includes(entry.subject.nodeName ?? '')
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
348
|
/**
|
|
363
349
|
* Applies all parameter values which are targeting a material.\
|
|
364
350
|
* This can be useful when updating a material definition before creating it.
|
|
@@ -387,16 +373,6 @@ export class ParameterManager {
|
|
|
387
373
|
await this._applyParameterValues(parameterEntriesToApply);
|
|
388
374
|
}
|
|
389
375
|
|
|
390
|
-
/**
|
|
391
|
-
* Removes all parameter entries of a certain material.\
|
|
392
|
-
* This can be useful to clean up the parameter state when removing a (cloned) material.
|
|
393
|
-
*
|
|
394
|
-
* @internal
|
|
395
|
-
*/
|
|
396
|
-
public removeParameterEntriesOfMaterial(material: Material): void {
|
|
397
|
-
this._parameterEntries = this._parameterEntries.filter(entry => entry.subject.materialName !== material.id);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
376
|
/**
|
|
401
377
|
* Applies subset of texture parameter values which are targeting a certain texture channel in a material.\
|
|
402
378
|
* This can be useful when updating texture settings (e.g. uScale) before the texture is actually created.
|
|
@@ -26,7 +26,7 @@ export class TextureManager {
|
|
|
26
26
|
const indexOfTextureQueryParam = texture.name.lastIndexOf(textureQueryString);
|
|
27
27
|
|
|
28
28
|
if (isUrl && indexOfTextureQueryParam > -1) {
|
|
29
|
-
texture.
|
|
29
|
+
texture.displayName = texture.name.substring(indexOfTextureQueryParam + textureQueryString.length);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
package/src/viewer.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import buildInfo from './buildinfo.json';
|
|
2
2
|
import * as Index from './index';
|
|
3
3
|
import {
|
|
4
|
+
BackgroundMaterial,
|
|
4
5
|
BoundingInfo,
|
|
5
6
|
CameraManager,
|
|
6
7
|
DebugManager,
|
|
@@ -199,6 +200,7 @@ export class Viewer {
|
|
|
199
200
|
* Only takes meshes into considerations that:
|
|
200
201
|
* - are visible
|
|
201
202
|
* - are not excluded by "excludeGeometry" parameter
|
|
203
|
+
* - do not have a material of type "BackgroundMaterial"
|
|
202
204
|
* - do not have an infinite distance (like sky boxes)
|
|
203
205
|
*/
|
|
204
206
|
public calculateBoundingInfo(excludeGeometry?: ExcludedGeometryList): BoundingInfo {
|
|
@@ -212,9 +214,12 @@ export class Viewer {
|
|
|
212
214
|
const hasValidBBoxInfo = mesh.getBoundingInfo().boundingSphere.radius > 0;
|
|
213
215
|
// ignore meshes with infinite distance, typically these are sky boxes
|
|
214
216
|
const hasInfiniteDistance = mesh.infiniteDistance;
|
|
217
|
+
// ignore meshes with "BackgroundMaterial" - usually a ground or skybox
|
|
218
|
+
const hasBackgroundMaterial = mesh.material instanceof BackgroundMaterial;
|
|
215
219
|
// ignore excluded meshes
|
|
216
220
|
const isExcluded = excludeGeometry ? isNodeExcluded(mesh, excludeGeometry) : false;
|
|
217
|
-
|
|
221
|
+
|
|
222
|
+
return isEnabled && hasValidBBoxInfo && !hasInfiniteDistance && !hasBackgroundMaterial && !isExcluded;
|
|
218
223
|
})
|
|
219
224
|
.reduce(
|
|
220
225
|
(accBBoxMinMax, curMesh, idx) => {
|
|
@@ -240,6 +245,13 @@ export class Viewer {
|
|
|
240
245
|
// asset manager
|
|
241
246
|
registerCustomCbnBabylonLoaderPlugin();
|
|
242
247
|
|
|
248
|
+
// without setting this flag, meshes with billboard mode set would not integrate into the node tree structure,
|
|
249
|
+
// that means the position would not be updated by the rotation of the parent node
|
|
250
|
+
// it's a bit dangerous to set this globally, but we need that for:
|
|
251
|
+
// - `DebugManager.showCoordinateSystem`
|
|
252
|
+
// - probably dimensions line handling (not implemented yet)
|
|
253
|
+
TransformNode.BillboardUseParentOrientation = true;
|
|
254
|
+
|
|
243
255
|
const engine = new Engine(
|
|
244
256
|
this.canvas,
|
|
245
257
|
this._viewerSettings.antialiasing,
|