@combeenation/3d-viewer 18.0.0-beta1 → 18.0.0-beta3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib-cjs/buildinfo.json +1 -1
- package/dist/lib-cjs/commonjs.tsconfig.tsbuildinfo +1 -1
- package/dist/lib-cjs/index.d.ts +6 -0
- package/dist/lib-cjs/index.js +6 -0
- package/dist/lib-cjs/index.js.map +1 -1
- package/dist/lib-cjs/internal/cloning-helper.js +1 -1
- package/dist/lib-cjs/internal/cloning-helper.js.map +1 -1
- package/dist/lib-cjs/manager/camera-manager.d.ts +23 -2
- package/dist/lib-cjs/manager/camera-manager.js +90 -25
- package/dist/lib-cjs/manager/camera-manager.js.map +1 -1
- package/dist/lib-cjs/manager/debug-manager.d.ts +1 -1
- package/dist/lib-cjs/manager/debug-manager.js +2 -2
- package/dist/lib-cjs/manager/debug-manager.js.map +1 -1
- package/dist/lib-cjs/manager/dimension-line-manager.d.ts +87 -0
- package/dist/lib-cjs/manager/dimension-line-manager.js +126 -0
- package/dist/lib-cjs/manager/dimension-line-manager.js.map +1 -0
- package/dist/lib-cjs/manager/html-anchor-manager.d.ts +93 -0
- package/dist/lib-cjs/manager/html-anchor-manager.js +228 -0
- package/dist/lib-cjs/manager/html-anchor-manager.js.map +1 -0
- package/dist/lib-cjs/manager/model-manager.d.ts +0 -1
- package/dist/lib-cjs/manager/model-manager.js +0 -1
- package/dist/lib-cjs/manager/model-manager.js.map +1 -1
- package/dist/lib-cjs/manager/parameter-manager.d.ts +1 -1
- package/dist/lib-cjs/manager/scene-manager.js +10 -3
- package/dist/lib-cjs/manager/scene-manager.js.map +1 -1
- package/dist/lib-cjs/viewer.d.ts +6 -2
- package/dist/lib-cjs/viewer.js +13 -1
- package/dist/lib-cjs/viewer.js.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +6 -0
- package/src/internal/cloning-helper.ts +1 -1
- package/src/manager/camera-manager.ts +152 -40
- package/src/manager/debug-manager.ts +2 -2
- package/src/manager/dimension-line-manager.ts +210 -0
- package/src/manager/html-anchor-manager.ts +332 -0
- package/src/manager/model-manager.ts +0 -1
- package/src/manager/parameter-manager.ts +1 -1
- package/src/manager/scene-manager.ts +12 -3
- package/src/viewer.ts +17 -1
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractMesh,
|
|
3
|
+
ArcRotateCamera,
|
|
4
|
+
Camera,
|
|
5
|
+
DimensionLineManager,
|
|
6
|
+
MeshBuilder,
|
|
7
|
+
ScreenshotSize,
|
|
8
|
+
StandardMaterial,
|
|
9
|
+
TransformNode,
|
|
10
|
+
Vector3,
|
|
11
|
+
Viewer,
|
|
12
|
+
Viewport,
|
|
13
|
+
} from '..';
|
|
14
|
+
import html2canvas from 'html2canvas';
|
|
15
|
+
|
|
16
|
+
export type HtmlAnchorOptions = {
|
|
17
|
+
/**
|
|
18
|
+
* Associated anchor mesh will be created underneath this parent node.\
|
|
19
|
+
* Can be used to make anchor position calculation easier in nested scene structures.
|
|
20
|
+
*/
|
|
21
|
+
parentNode?: TransformNode;
|
|
22
|
+
/**
|
|
23
|
+
* Can be used to filter affected html anchors in {@link HtmlAnchorManager.removeAllHtmlAnchors}
|
|
24
|
+
*/
|
|
25
|
+
group?: string;
|
|
26
|
+
/**
|
|
27
|
+
* `true`: html elements can be occluded by other meshes
|
|
28
|
+
* `false`: html elements will always be shown in front of the scene
|
|
29
|
+
*
|
|
30
|
+
* Default: `false`
|
|
31
|
+
*/
|
|
32
|
+
hideIfOccluded?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* `true`: html element size is relative to camera distance, just like a "normal" 3d object
|
|
35
|
+
* `false`: html element size remains constant
|
|
36
|
+
*
|
|
37
|
+
* Default: `false`
|
|
38
|
+
*/
|
|
39
|
+
scaleWithCameraDistance?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Activates/deactivates `pointer-events` CSS class of anchor element.\
|
|
42
|
+
* Set this to `true` if the html element should be interactive (e.g. button)
|
|
43
|
+
*
|
|
44
|
+
* Default: `false`
|
|
45
|
+
*/
|
|
46
|
+
enablePointerEvents?: boolean;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Manager for mapping html elements to 3d positions in the scene.\
|
|
51
|
+
* Common use cases are:
|
|
52
|
+
* - **Hotspot buttons**: Interactively add/remove elements in the scene or just show some info on hovering
|
|
53
|
+
* - **Input fields**: Interactively change the size of an element
|
|
54
|
+
* - **Info label**: Just shows some information on a certain position within the scene
|
|
55
|
+
*
|
|
56
|
+
* Html anchors are also used as dimension lables in the {@link DimensionLineManager}
|
|
57
|
+
*/
|
|
58
|
+
export class HtmlAnchorManager {
|
|
59
|
+
protected static readonly _HTML_ANCHOR_KEY = '$htmlAnchor';
|
|
60
|
+
|
|
61
|
+
protected _htmlAnchors: {
|
|
62
|
+
[name: string]: {
|
|
63
|
+
parentHtmlElement: HTMLDivElement;
|
|
64
|
+
anchorMesh: AbstractMesh;
|
|
65
|
+
options?: HtmlAnchorOptions;
|
|
66
|
+
};
|
|
67
|
+
} = {};
|
|
68
|
+
|
|
69
|
+
protected _anchorMeshMaterial: StandardMaterial | null = null;
|
|
70
|
+
|
|
71
|
+
/** @internal */
|
|
72
|
+
public constructor(protected viewer: Viewer) {
|
|
73
|
+
const canvas = viewer.canvas;
|
|
74
|
+
if (!canvas) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// html element positions need to be updated after each camera render call
|
|
79
|
+
viewer.scene.onAfterRenderCameraObservable.add(() => {
|
|
80
|
+
Object.values(this._htmlAnchors).forEach(({ parentHtmlElement, anchorMesh, options }) => {
|
|
81
|
+
this._updateHtmlAnchor(
|
|
82
|
+
parentHtmlElement,
|
|
83
|
+
anchorMesh,
|
|
84
|
+
viewer.scene.activeCamera!,
|
|
85
|
+
canvas.width,
|
|
86
|
+
canvas.height,
|
|
87
|
+
1,
|
|
88
|
+
options
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Assign a html element to a certain position in the scene.\
|
|
96
|
+
* The html elements 2d position will be updated on each camera render, so that the element appears like a "normal"
|
|
97
|
+
* mesh within the scene.
|
|
98
|
+
*/
|
|
99
|
+
public addHtmlAnchor(name: string, htmlElement: HTMLElement, position: Vector3, options?: HtmlAnchorOptions): void {
|
|
100
|
+
const canvasParentHtmlElement = this.viewer.canvas?.parentElement;
|
|
101
|
+
if (!canvasParentHtmlElement) {
|
|
102
|
+
console.warn(`No parent for desired html anchor available`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (this._htmlAnchors[name]) {
|
|
107
|
+
console.warn(`Html anchor "${name}" already exists`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const { parentNode, enablePointerEvents } = options ?? {};
|
|
112
|
+
|
|
113
|
+
// create a parent for the input html element, which will receive the updated style and transform data
|
|
114
|
+
// in this way the original input element remains untouched
|
|
115
|
+
const parentHtmlElement = document.createElement('div');
|
|
116
|
+
parentHtmlElement.dataset.anchorName = name;
|
|
117
|
+
parentHtmlElement.style.position = 'absolute';
|
|
118
|
+
parentHtmlElement.style.margin = '0';
|
|
119
|
+
parentHtmlElement.appendChild(htmlElement);
|
|
120
|
+
if (!enablePointerEvents) {
|
|
121
|
+
parentHtmlElement.style.pointerEvents = 'none';
|
|
122
|
+
}
|
|
123
|
+
canvasParentHtmlElement.appendChild(parentHtmlElement);
|
|
124
|
+
|
|
125
|
+
// NOTE: creates a sphere with fixed size, which could be problematic in scene with "strange" dimensions
|
|
126
|
+
// add a property for the sphere size if required
|
|
127
|
+
const anchorMesh = MeshBuilder.CreateSphere(`${HtmlAnchorManager._HTML_ANCHOR_KEY}_${name}`, { diameter: 0.01 });
|
|
128
|
+
anchorMesh.position = position;
|
|
129
|
+
anchorMesh.parent = parentNode ?? null;
|
|
130
|
+
// anchor mesh will be invisible, we only need it for positioning and occlusion check
|
|
131
|
+
anchorMesh.material = this._getOrCreateAnchorMeshMaterial();
|
|
132
|
+
anchorMesh.occlusionType = AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC;
|
|
133
|
+
anchorMesh.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE;
|
|
134
|
+
// it's important that the occlusion check mesh is rendered after all "normal" meshes, which should be taken into
|
|
135
|
+
// account for the occlusion check
|
|
136
|
+
anchorMesh.renderingGroupId = 1;
|
|
137
|
+
|
|
138
|
+
this._htmlAnchors[name] = { parentHtmlElement, anchorMesh, options };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Remove html anchor element and disposes all associated ressources
|
|
143
|
+
*/
|
|
144
|
+
public removeHtmlAnchor(name: string): void {
|
|
145
|
+
const htmlAnchor = this._htmlAnchors[name];
|
|
146
|
+
if (!htmlAnchor) {
|
|
147
|
+
console.warn(`Html anchor "${name}" does not exist`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
htmlAnchor.parentHtmlElement.remove();
|
|
152
|
+
htmlAnchor.anchorMesh.dispose();
|
|
153
|
+
|
|
154
|
+
delete this._htmlAnchors[name];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Removes html anchor elements, as defined by the `groups` input
|
|
159
|
+
*
|
|
160
|
+
* @param groups if set, only html anchors which are part of these groups will be removed\
|
|
161
|
+
* if left `undefined`, ALL html anchors will be removed
|
|
162
|
+
*/
|
|
163
|
+
public removeAllHtmlAnchors(groups?: string[]): void {
|
|
164
|
+
const anchorKeysToRemove = this.getHtmlAnchorKeys(
|
|
165
|
+
groups,
|
|
166
|
+
undefined,
|
|
167
|
+
// system groups should not be remove, as there is a dedicated workflow
|
|
168
|
+
// (e.g. `DimensionLineManager.removeDimensionLine`) to do this
|
|
169
|
+
false
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
anchorKeysToRemove.forEach(name => this.removeHtmlAnchor(name));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Creates a screenshot of defined html anchors and returns the associated canvas.\
|
|
177
|
+
* This function is used @internal from the main screenshot function.
|
|
178
|
+
*/
|
|
179
|
+
public async createScreenshotCanvas(
|
|
180
|
+
size: ScreenshotSize,
|
|
181
|
+
camera: ArcRotateCamera,
|
|
182
|
+
htmlAnchorKeys: string[]
|
|
183
|
+
): Promise<HTMLCanvasElement> {
|
|
184
|
+
const canvasParentHtmlElement = this.viewer.canvas?.parentElement;
|
|
185
|
+
if (!canvasParentHtmlElement) {
|
|
186
|
+
console.warn(`No parent for html anchors available`);
|
|
187
|
+
return new HTMLCanvasElement();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const htmlContainer = document.createElement('div');
|
|
191
|
+
htmlContainer.style.width = `${size.canvasWidth}px`;
|
|
192
|
+
htmlContainer.style.height = `${size.canvasHeight}px`;
|
|
193
|
+
|
|
194
|
+
// the `html2canvas` library requires the html to be present in the DOM
|
|
195
|
+
// that's why we create it top level and move it out of the viewport
|
|
196
|
+
// @reviewer: maybe there is a smoother method of doing that?
|
|
197
|
+
document.body.append(htmlContainer);
|
|
198
|
+
htmlContainer.style.position = 'absolute';
|
|
199
|
+
htmlContainer.style.top = `${-size.canvasHeight}px`;
|
|
200
|
+
|
|
201
|
+
htmlAnchorKeys.forEach(key => {
|
|
202
|
+
const { parentHtmlElement, anchorMesh, options } = this._htmlAnchors[key];
|
|
203
|
+
|
|
204
|
+
// create clones of html anchors, so that the position of the original elements remains untouched
|
|
205
|
+
const clonedHtmlNode = parentHtmlElement.cloneNode(true) as HTMLDivElement;
|
|
206
|
+
htmlContainer.append(clonedHtmlNode);
|
|
207
|
+
|
|
208
|
+
// reposition that cloned html element, so that it fits to the desired camera position
|
|
209
|
+
const baseScale = size.canvasHeight / this.viewer.canvas!.height;
|
|
210
|
+
this._updateHtmlAnchor(
|
|
211
|
+
clonedHtmlNode,
|
|
212
|
+
anchorMesh,
|
|
213
|
+
camera,
|
|
214
|
+
size.canvasWidth,
|
|
215
|
+
size.canvasHeight,
|
|
216
|
+
baseScale,
|
|
217
|
+
options
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const screenshotHtmlCanvas = await html2canvas(htmlContainer, {
|
|
222
|
+
width: size.imageWidth,
|
|
223
|
+
height: size.imageHeight,
|
|
224
|
+
// apply difference of canvas and image size as offsets
|
|
225
|
+
x: (size.canvasWidth - size.imageWidth) / 2,
|
|
226
|
+
y: (size.canvasHeight - size.imageHeight) / 2,
|
|
227
|
+
logging: false,
|
|
228
|
+
backgroundColor: null,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
htmlContainer.remove();
|
|
232
|
+
|
|
233
|
+
return screenshotHtmlCanvas;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Receive html anchor keys that pass the `includeGroups` and `excludeGroups` filter
|
|
238
|
+
* @param allowSystemGroups defines if html anchors created by the viewer should be considered (e.g. dimension line
|
|
239
|
+
* labels)
|
|
240
|
+
* @internal
|
|
241
|
+
*/
|
|
242
|
+
public getHtmlAnchorKeys(includeGroups?: string[], excludeGroups?: string[], allowSystemGroups?: boolean): string[] {
|
|
243
|
+
const anchorKeys = Object.keys(this._htmlAnchors).filter(name => {
|
|
244
|
+
const group = this._htmlAnchors[name].options?.group;
|
|
245
|
+
const passIncludeGroupFilter =
|
|
246
|
+
includeGroups === undefined || (group !== undefined && includeGroups.includes(group));
|
|
247
|
+
const passExcludeGroupFilter =
|
|
248
|
+
excludeGroups === undefined || group === undefined || !excludeGroups.includes(group);
|
|
249
|
+
// ATM only dimension labels are system html anchors
|
|
250
|
+
const passSystemGroupFilter = allowSystemGroups || group !== DimensionLineManager.DIMENSION_LINE_KEY;
|
|
251
|
+
|
|
252
|
+
return passIncludeGroupFilter && passExcludeGroupFilter && passSystemGroupFilter;
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
return anchorKeys;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Check if input mesh is a html anchor mesh, created by this manager.\
|
|
260
|
+
* This check is done via the material, as all html anchor meshes have the generic `_anchorMeshMaterial` set.
|
|
261
|
+
* @internal
|
|
262
|
+
*/
|
|
263
|
+
public isHtmlAnchorMesh(mesh: AbstractMesh): boolean {
|
|
264
|
+
return mesh.material === this._anchorMeshMaterial;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
protected _updateHtmlAnchor(
|
|
268
|
+
parentHtmlElement: HTMLDivElement,
|
|
269
|
+
anchorMesh: AbstractMesh,
|
|
270
|
+
camera: Camera,
|
|
271
|
+
width: number,
|
|
272
|
+
height: number,
|
|
273
|
+
baseScale: number,
|
|
274
|
+
options?: HtmlAnchorOptions
|
|
275
|
+
): void {
|
|
276
|
+
const { hideIfOccluded, scaleWithCameraDistance } = options ?? {};
|
|
277
|
+
|
|
278
|
+
const viewMatrix = camera.getViewMatrix();
|
|
279
|
+
const projectionMatrix = camera.getProjectionMatrix();
|
|
280
|
+
const transformMatrix = viewMatrix.multiply(projectionMatrix);
|
|
281
|
+
|
|
282
|
+
// convert into 2d space
|
|
283
|
+
const vertexScreenCoords = Vector3.Project(
|
|
284
|
+
Vector3.Zero(),
|
|
285
|
+
anchorMesh.getWorldMatrix(),
|
|
286
|
+
transformMatrix,
|
|
287
|
+
new Viewport(0, 0, width, height)
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
// base scale is used if width and height don't equal the viewer canvas, which is the case for screenshots
|
|
291
|
+
let scale = baseScale;
|
|
292
|
+
if (scaleWithCameraDistance) {
|
|
293
|
+
const meshWorldPos = anchorMesh.getAbsolutePosition();
|
|
294
|
+
// calculate camera world position manually, as there is no help function like for meshes
|
|
295
|
+
const camWorldMatrix = camera.computeWorldMatrix();
|
|
296
|
+
const camWorldPos = camWorldMatrix.getTranslation();
|
|
297
|
+
const distance = Vector3.Distance(meshWorldPos, camWorldPos);
|
|
298
|
+
const frustumSlopeY = Math.tan(camera.fov / 2);
|
|
299
|
+
// if the distance from camera to mesh gets larger, the html elements scaling will be decreased
|
|
300
|
+
// we also consider the cameras FOV, so scale 1 means, that the resulting vertical frustum of the camera
|
|
301
|
+
// distance equals 1
|
|
302
|
+
// ...this is probably too small in some scenarios, so we might have to add a general scale setting here
|
|
303
|
+
scale *= 1 / (distance * frustumSlopeY);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const elementXOffset = (parentHtmlElement.offsetWidth * scale) / 2;
|
|
307
|
+
const elementYOffset = (parentHtmlElement.offsetHeight * scale) / 2;
|
|
308
|
+
// finally move and scale the HTML element
|
|
309
|
+
parentHtmlElement.style.transform = `translate3d(calc(${vertexScreenCoords.x}px - 50%), calc(${vertexScreenCoords.y}px - 50%), 0px) scale(${scale})`;
|
|
310
|
+
|
|
311
|
+
// check for occlusion if desired
|
|
312
|
+
// we use the opacity setting, which could also be animated nicely if we want
|
|
313
|
+
const isInViewport =
|
|
314
|
+
vertexScreenCoords.x - elementXOffset > 0 &&
|
|
315
|
+
vertexScreenCoords.x + elementXOffset < width &&
|
|
316
|
+
vertexScreenCoords.y - elementYOffset > 0 &&
|
|
317
|
+
vertexScreenCoords.y + elementYOffset < height;
|
|
318
|
+
const isOccluded = hideIfOccluded && anchorMesh.isOccluded;
|
|
319
|
+
parentHtmlElement.style.opacity = isInViewport && !isOccluded ? '1' : '0';
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
protected _getOrCreateAnchorMeshMaterial(): StandardMaterial {
|
|
323
|
+
if (this._anchorMeshMaterial) {
|
|
324
|
+
return this._anchorMeshMaterial;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
this._anchorMeshMaterial = new StandardMaterial('$matAnchorMesh');
|
|
328
|
+
this._anchorMeshMaterial.alpha = 0;
|
|
329
|
+
this.viewer.scene.removeMaterial(this._anchorMeshMaterial);
|
|
330
|
+
return this._anchorMeshMaterial;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
@@ -97,7 +97,7 @@ export type ParameterObserver = (payload: ParameterObserverPayload) => Promise<v
|
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Payload of parameter observer.\
|
|
100
|
-
* Contains current data of parameter entry, which can be
|
|
100
|
+
* Contains current data of parameter entry, which can be useful for implementing the dedicated observer
|
|
101
101
|
*/
|
|
102
102
|
export type ParameterObserverPayload = {
|
|
103
103
|
subject: ParameterSubject;
|
|
@@ -105,7 +105,7 @@ type SceneAsset = BaseAsset & {
|
|
|
105
105
|
* This contains creating or loading scenes with certain settings for lighting, cameras and appearance in genereal.
|
|
106
106
|
*/
|
|
107
107
|
export class SceneManager {
|
|
108
|
-
protected static _DEFAULT_SCENE_ASSET_NAME = '$
|
|
108
|
+
protected static _DEFAULT_SCENE_ASSET_NAME = '$defaultScene';
|
|
109
109
|
protected static _DEFAULT_GROUND_PLANE_NAME = 'BackgroundPlane';
|
|
110
110
|
protected static _DEFAULT_GROUND_SIZING_FACTOR = 5;
|
|
111
111
|
|
|
@@ -294,10 +294,19 @@ export class SceneManager {
|
|
|
294
294
|
const hasInfiniteDistance = mesh.infiniteDistance;
|
|
295
295
|
// ignore meshes with "BackgroundMaterial" - usually a ground or skybox
|
|
296
296
|
const hasBackgroundMaterial = mesh.material instanceof BackgroundMaterial;
|
|
297
|
+
// ignore dummy meshes for html anchor occlusion check
|
|
298
|
+
const isHtmlAnchorMesh = this.viewer.htmlAnchorManager.isHtmlAnchorMesh(mesh);
|
|
297
299
|
// ignore excluded meshes
|
|
298
300
|
const isExcluded = excludeGeometry ? isNodeExcluded(mesh, excludeGeometry) : false;
|
|
299
301
|
|
|
300
|
-
return
|
|
302
|
+
return (
|
|
303
|
+
isEnabled &&
|
|
304
|
+
hasValidBBoxInfo &&
|
|
305
|
+
!hasInfiniteDistance &&
|
|
306
|
+
!hasBackgroundMaterial &&
|
|
307
|
+
!isHtmlAnchorMesh &&
|
|
308
|
+
!isExcluded
|
|
309
|
+
);
|
|
301
310
|
})
|
|
302
311
|
.reduce(
|
|
303
312
|
(accBBoxMinMax, curMesh, idx) => {
|
|
@@ -399,7 +408,7 @@ export class SceneManager {
|
|
|
399
408
|
// camera
|
|
400
409
|
if (cameraSettings.create) {
|
|
401
410
|
const camera = new ArcRotateCamera(
|
|
402
|
-
`${SceneManager._DEFAULT_SCENE_ASSET_NAME}
|
|
411
|
+
`${SceneManager._DEFAULT_SCENE_ASSET_NAME}_camera`,
|
|
403
412
|
cameraSettings.initialPosition.alpha,
|
|
404
413
|
cameraSettings.initialPosition.beta,
|
|
405
414
|
cameraSettings.initialPosition.radius,
|
package/src/viewer.ts
CHANGED
|
@@ -5,10 +5,12 @@ import {
|
|
|
5
5
|
CameraManager,
|
|
6
6
|
DebugManager,
|
|
7
7
|
DefaultSceneSettings,
|
|
8
|
+
DimensionLineManager,
|
|
8
9
|
Engine,
|
|
9
10
|
EngineOptions,
|
|
10
11
|
EventManager,
|
|
11
12
|
GltfExportManager,
|
|
13
|
+
HtmlAnchorManager,
|
|
12
14
|
MaterialManager,
|
|
13
15
|
ModelManager,
|
|
14
16
|
NullEngine,
|
|
@@ -80,8 +82,10 @@ export class Viewer {
|
|
|
80
82
|
|
|
81
83
|
protected _cameraManager!: CameraManager;
|
|
82
84
|
protected _debugManager!: DebugManager;
|
|
85
|
+
protected _dimensionLineManager!: DimensionLineManager;
|
|
83
86
|
protected _eventManager!: EventManager;
|
|
84
87
|
protected _gltfExportManager!: GltfExportManager;
|
|
88
|
+
protected _htmlAnchorManager!: HtmlAnchorManager;
|
|
85
89
|
protected _materialManager!: MaterialManager;
|
|
86
90
|
protected _modelManager!: ModelManager;
|
|
87
91
|
protected _parameterManager!: ParameterManager;
|
|
@@ -119,12 +123,18 @@ export class Viewer {
|
|
|
119
123
|
get debugManager(): DebugManager {
|
|
120
124
|
return this._debugManager;
|
|
121
125
|
}
|
|
126
|
+
get dimensionLineManager(): DimensionLineManager {
|
|
127
|
+
return this._dimensionLineManager;
|
|
128
|
+
}
|
|
122
129
|
get eventManager(): EventManager {
|
|
123
130
|
return this._eventManager;
|
|
124
131
|
}
|
|
125
132
|
get gltfExportManager(): GltfExportManager {
|
|
126
133
|
return this._gltfExportManager;
|
|
127
134
|
}
|
|
135
|
+
get htmlAnchorManager(): HtmlAnchorManager {
|
|
136
|
+
return this._htmlAnchorManager;
|
|
137
|
+
}
|
|
128
138
|
get materialManager(): MaterialManager {
|
|
129
139
|
return this._materialManager;
|
|
130
140
|
}
|
|
@@ -171,7 +181,7 @@ export class Viewer {
|
|
|
171
181
|
}
|
|
172
182
|
|
|
173
183
|
/**
|
|
174
|
-
* Pause rendering can be
|
|
184
|
+
* Pause rendering can be useful when doing internal scene processings that should not be visible to the user,
|
|
175
185
|
* e.g. cloning meshes for gltf export
|
|
176
186
|
*/
|
|
177
187
|
public pauseRendering(): void {
|
|
@@ -227,14 +237,20 @@ export class Viewer {
|
|
|
227
237
|
}
|
|
228
238
|
|
|
229
239
|
this._scene = new Scene(engine);
|
|
240
|
+
// NOTE: rendering group id "1" is reserved for occlusion helper sphere (see `HtmlAnchorManager`)
|
|
241
|
+
// rendering group id "1" has the same depth buffer as 0 in order to make this work
|
|
242
|
+
// => use rendering group id "2" or higher for keeping meshes in foreground
|
|
243
|
+
this._scene.setRenderingAutoClearDepthStencil(1, false, false, false);
|
|
230
244
|
|
|
231
245
|
// NOTE: order of manage seems to be a bit counter intuitive as it's sorted alphabetically
|
|
232
246
|
// semantically one would start with scene manager, etc...
|
|
233
247
|
// still this is a good test as the order of manager constructors should not matter
|
|
234
248
|
this._cameraManager = new CameraManager(this);
|
|
235
249
|
this._debugManager = new DebugManager(this);
|
|
250
|
+
this._dimensionLineManager = new DimensionLineManager(this);
|
|
236
251
|
this._eventManager = new EventManager(this);
|
|
237
252
|
this._gltfExportManager = new GltfExportManager(this);
|
|
253
|
+
this._htmlAnchorManager = new HtmlAnchorManager(this);
|
|
238
254
|
this._materialManager = new MaterialManager(this);
|
|
239
255
|
this._modelManager = new ModelManager(this);
|
|
240
256
|
this._parameterManager = new ParameterManager(this);
|