From 6a7e085fd7e7a78cf38fd4ae57df96565f48c7de Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Wed, 21 Aug 2024 14:13:31 +0200 Subject: [PATCH 1/6] Update Cognite3DViewer.ts --- .../src/public/migration/Cognite3DViewer.ts | 76 ++++++++++++------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts index 86ebcde2f3a..5b9861efdc2 100644 --- a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts +++ b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts @@ -1281,6 +1281,19 @@ export class Cognite3DViewer { this.fitCameraToBoundingBox(boundingBox, duration); } + /** + * Move camera to a place where a all objects in the scene are visible + * @param duration The duration of the animation moving the camera. Set this to 0 (zero) to disable animation. + */ + fitCameraToSceneBoundingBox(duration?: number): void { + this.recalculateBoundingBox(); + const boundingBox = this.getSceneBoundingBox(); + if (boundingBox.isEmpty()) { + return; + } + this.fitCameraToBoundingBox(boundingBox, duration); + } + /** * Move camera to a place where the content of a bounding box is visible to the camera. * @param box The bounding box in world space. @@ -1880,34 +1893,45 @@ export class Cognite3DViewer { nearFarPlaneBoundingBox.makeEmpty(); sceneBoundingBox.makeEmpty(); - this._models.forEach(model => { - model.getModelBoundingBox(temporaryBox); - if (temporaryBox.isEmpty()) { - return; - } - nearFarPlaneBoundingBox.union(temporaryBox); + for (let pass = 0; pass < 2; pass++) { + // On the first pass, use visible models only + // If no bounding box is found, use all models on the second pass + // By this way, a bounding box is forced to be calculated + this._models.forEach(model => { + if (pass === 0 && !model.visible) { + return; + } + model.getModelBoundingBox(temporaryBox); + if (temporaryBox.isEmpty()) { + return; + } + nearFarPlaneBoundingBox.union(temporaryBox); - // The getModelBoundingBox is using restrictToMostGeometry = true - model.getModelBoundingBox(temporaryBox, true); - if (temporaryBox.isEmpty()) { - return; - } - sceneBoundingBox.union(temporaryBox); - }); - this._sceneHandler.customObjects.forEach(customObject => { - if (!customObject.object.visible) { - return; - } - customObject.getBoundingBox(temporaryBox); - if (temporaryBox.isEmpty()) { - return; - } - nearFarPlaneBoundingBox.union(temporaryBox); - if (!customObject.isPartOfBoundingBox) { - return; + // The getModelBoundingBox is using restrictToMostGeometry = true + model.getModelBoundingBox(temporaryBox, true); + if (temporaryBox.isEmpty()) { + return; + } + sceneBoundingBox.union(temporaryBox); + }); + this._sceneHandler.customObjects.forEach(customObject => { + if (!customObject.object.visible) { + return; + } + customObject.getBoundingBox(temporaryBox); + if (temporaryBox.isEmpty()) { + return; + } + nearFarPlaneBoundingBox.union(temporaryBox); + if (!customObject.isPartOfBoundingBox) { + return; + } + sceneBoundingBox.union(temporaryBox); + }); + if (!sceneBoundingBox.isEmpty()) { + break; } - sceneBoundingBox.union(temporaryBox); - }); + } } /** @private */ From b83a9b77f2a090a66242f84d0f522899991d0d63 Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Wed, 28 Aug 2024 13:42:24 +0200 Subject: [PATCH 2/6] Update Cognite3DViewer.ts --- .../src/public/migration/Cognite3DViewer.ts | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts index 5b9861efdc2..4ad94b8ace5 100644 --- a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts +++ b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts @@ -1893,6 +1893,51 @@ export class Cognite3DViewer { nearFarPlaneBoundingBox.makeEmpty(); sceneBoundingBox.makeEmpty(); + this._models.forEach(model => { + model.getModelBoundingBox(temporaryBox); + if (temporaryBox.isEmpty()) { + return; + } + nearFarPlaneBoundingBox.union(temporaryBox); + + // The getModelBoundingBox is using restrictToMostGeometry = true + model.getModelBoundingBox(temporaryBox, true); + if (temporaryBox.isEmpty()) { + return; + } + sceneBoundingBox.union(temporaryBox); + }); + this._sceneHandler.customObjects.forEach(customObject => { + if (!customObject.object.visible) { + return; + } + customObject.getBoundingBox(temporaryBox); + if (temporaryBox.isEmpty()) { + return; + } + nearFarPlaneBoundingBox.union(temporaryBox); + if (!customObject.isPartOfBoundingBox) { + return; + } + sceneBoundingBox.union(temporaryBox); + }); + console.log('old:'); + console.log('nearFarPlaneBoundingBox: ', nearFarPlaneBoundingBox); + console.log('sceneBoundingBox: ', sceneBoundingBox); + } + + /* + /** @private * + private recalculateBoundingBox() { + // See https://stackoverflow.com/questions/8101119/how-do-i-methodically-choose-the-near-clip-plane-distance-for-a-perspective-proj + if (this.isDisposed) { + return; + } + + const { nearFarPlaneBoundingBox, sceneBoundingBox, temporaryBox } = this._boundingBoxes; + nearFarPlaneBoundingBox.makeEmpty(); + sceneBoundingBox.makeEmpty(); + for (let pass = 0; pass < 2; pass++) { // On the first pass, use visible models only // If no bounding box is found, use all models on the second pass @@ -1932,7 +1977,10 @@ export class Cognite3DViewer { break; } } + console.log('nearFarPlaneBoundingBox: ', nearFarPlaneBoundingBox); + console.log('sceneBoundingBox: ', sceneBoundingBox); } + */ /** @private */ private setupDomElementResizeListener(domElement: HTMLElement): ResizeObserver { From 3901fed7f8ffbf1a9b2b8d4ae547e7aa3bd5f1c9 Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Thu, 29 Aug 2024 11:22:01 +0200 Subject: [PATCH 3/6] Update Cognite3DViewer.ts --- .../src/public/migration/Cognite3DViewer.ts | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts index 4ad94b8ace5..5b9861efdc2 100644 --- a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts +++ b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts @@ -1893,51 +1893,6 @@ export class Cognite3DViewer { nearFarPlaneBoundingBox.makeEmpty(); sceneBoundingBox.makeEmpty(); - this._models.forEach(model => { - model.getModelBoundingBox(temporaryBox); - if (temporaryBox.isEmpty()) { - return; - } - nearFarPlaneBoundingBox.union(temporaryBox); - - // The getModelBoundingBox is using restrictToMostGeometry = true - model.getModelBoundingBox(temporaryBox, true); - if (temporaryBox.isEmpty()) { - return; - } - sceneBoundingBox.union(temporaryBox); - }); - this._sceneHandler.customObjects.forEach(customObject => { - if (!customObject.object.visible) { - return; - } - customObject.getBoundingBox(temporaryBox); - if (temporaryBox.isEmpty()) { - return; - } - nearFarPlaneBoundingBox.union(temporaryBox); - if (!customObject.isPartOfBoundingBox) { - return; - } - sceneBoundingBox.union(temporaryBox); - }); - console.log('old:'); - console.log('nearFarPlaneBoundingBox: ', nearFarPlaneBoundingBox); - console.log('sceneBoundingBox: ', sceneBoundingBox); - } - - /* - /** @private * - private recalculateBoundingBox() { - // See https://stackoverflow.com/questions/8101119/how-do-i-methodically-choose-the-near-clip-plane-distance-for-a-perspective-proj - if (this.isDisposed) { - return; - } - - const { nearFarPlaneBoundingBox, sceneBoundingBox, temporaryBox } = this._boundingBoxes; - nearFarPlaneBoundingBox.makeEmpty(); - sceneBoundingBox.makeEmpty(); - for (let pass = 0; pass < 2; pass++) { // On the first pass, use visible models only // If no bounding box is found, use all models on the second pass @@ -1977,10 +1932,7 @@ export class Cognite3DViewer { break; } } - console.log('nearFarPlaneBoundingBox: ', nearFarPlaneBoundingBox); - console.log('sceneBoundingBox: ', sceneBoundingBox); } - */ /** @private */ private setupDomElementResizeListener(domElement: HTMLElement): ResizeObserver { From 1e8d758a71ba687e754579aec642ef2032decdb3 Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Thu, 29 Aug 2024 11:24:20 +0200 Subject: [PATCH 4/6] Update reveal.api.md --- viewer/reveal.api.md | 1 + 1 file changed, 1 insertion(+) diff --git a/viewer/reveal.api.md b/viewer/reveal.api.md index 7ca02503634..b444a959624 100644 --- a/viewer/reveal.api.md +++ b/viewer/reveal.api.md @@ -438,6 +438,7 @@ export class Cognite3DViewer { fitCameraToBoundingBox(box: THREE.Box3, duration?: number, radiusFactor?: number): void; fitCameraToModel(model: CogniteModel, duration?: number): void; fitCameraToModels(models?: CogniteModel[], duration?: number, restrictToMostGeometry?: boolean): void; + fitCameraToSceneBoundingBox(duration?: number): void; get360AnnotationIntersectionFromPixel(offsetX: number, offsetY: number): Promise; get360ImageCollections(): Image360Collection[]; getActive360ImageInfo(): Image360WithCollection | undefined; From 53be82317c4e83074d2092857cd2f9a312d9ed03 Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Thu, 29 Aug 2024 11:48:44 +0200 Subject: [PATCH 5/6] Refactoring --- .../src/public/migration/Cognite3DViewer.ts | 80 ++++++++++++++----- viewer/reveal.api.md | 6 +- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts index 5b9861efdc2..0fe987fc409 100644 --- a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts +++ b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts @@ -1217,6 +1217,45 @@ export class Cognite3DViewer { return this._boundingBoxes.sceneBoundingBox; } + /** + * Get the union of bounding box of all visual objects in the Cognite3DViewer. + * @returns The visual bounding box of the Cognite3DViewer. + * @beta + */ + getVisualSceneBoundingBox(): THREE.Box3 { + const boundingBox = new THREE.Box3(); + boundingBox.makeEmpty(); + + if (this.isDisposed) { + return boundingBox; + } + const temporaryBox = new THREE.Box3(); + for (const model of this.models) { + if (!model.visible) { + continue; + } + model.getModelBoundingBox(temporaryBox, true); + if (temporaryBox.isEmpty()) { + continue; + } + boundingBox.union(temporaryBox); + } + for (const customObject of this._sceneHandler.customObjects) { + if (!customObject.object.visible) { + continue; + } + customObject.getBoundingBox(temporaryBox); + if (temporaryBox.isEmpty()) { + continue; + } + if (!customObject.isPartOfBoundingBox) { + continue; + } + boundingBox.union(temporaryBox); + } + return boundingBox; + } + /** * Attempts to load the camera settings from the settings stored for the * provided model. See {@link https://docs.cognite.com/api/v1/#operation/get3DRevision} @@ -1257,6 +1296,9 @@ export class Cognite3DViewer { */ fitCameraToModel(model: CogniteModel, duration?: number): void { const boundingBox = model.getModelBoundingBox(new THREE.Box3(), true); + if (boundingBox.isEmpty()) { + return; + } this._activeCameraManager.fitCameraToBoundingBox(boundingBox, duration); } @@ -1268,7 +1310,6 @@ export class Cognite3DViewer { */ fitCameraToModels(models?: CogniteModel[], duration?: number, restrictToMostGeometry = false): void { const cogniteModels = models ?? this.models; - if (cogniteModels.length < 1) { return; } @@ -1285,18 +1326,14 @@ export class Cognite3DViewer { * Move camera to a place where a all objects in the scene are visible * @param duration The duration of the animation moving the camera. Set this to 0 (zero) to disable animation. */ - fitCameraToSceneBoundingBox(duration?: number): void { - this.recalculateBoundingBox(); - const boundingBox = this.getSceneBoundingBox(); - if (boundingBox.isEmpty()) { - return; - } + fitCameraToVisualSceneBoundingBox(duration?: number): void { + const boundingBox = this.getVisualSceneBoundingBox(); this.fitCameraToBoundingBox(boundingBox, duration); } /** * Move camera to a place where the content of a bounding box is visible to the camera. - * @param box The bounding box in world space. + * @param boundingBox The bounding box in world space. * @param duration The duration of the animation moving the camera. Set this to 0 (zero) to disable animation. * @param radiusFactor The ratio of the distance from camera to center of box and radius of the box. * @example @@ -1313,8 +1350,11 @@ export class Cognite3DViewer { * viewer.fitCameraToBoundingBox(boundingBox, 500, 2); * ``` */ - fitCameraToBoundingBox(box: THREE.Box3, duration?: number, radiusFactor: number = 2): void { - this._activeCameraManager.fitCameraToBoundingBox(box, duration, radiusFactor); + fitCameraToBoundingBox(boundingBox: THREE.Box3, duration?: number, radiusFactor: number = 2): void { + if (boundingBox.isEmpty()) { + return; + } + this._activeCameraManager.fitCameraToBoundingBox(boundingBox, duration, radiusFactor); } /** @@ -1897,37 +1937,37 @@ export class Cognite3DViewer { // On the first pass, use visible models only // If no bounding box is found, use all models on the second pass // By this way, a bounding box is forced to be calculated - this._models.forEach(model => { + for (const model of this.models) { if (pass === 0 && !model.visible) { - return; + continue; } model.getModelBoundingBox(temporaryBox); if (temporaryBox.isEmpty()) { - return; + continue; } nearFarPlaneBoundingBox.union(temporaryBox); // The getModelBoundingBox is using restrictToMostGeometry = true model.getModelBoundingBox(temporaryBox, true); if (temporaryBox.isEmpty()) { - return; + continue; } sceneBoundingBox.union(temporaryBox); - }); - this._sceneHandler.customObjects.forEach(customObject => { + } + for (const customObject of this._sceneHandler.customObjects) { if (!customObject.object.visible) { - return; + continue; } customObject.getBoundingBox(temporaryBox); if (temporaryBox.isEmpty()) { - return; + continue; } nearFarPlaneBoundingBox.union(temporaryBox); if (!customObject.isPartOfBoundingBox) { - return; + continue; } sceneBoundingBox.union(temporaryBox); - }); + } if (!sceneBoundingBox.isEmpty()) { break; } diff --git a/viewer/reveal.api.md b/viewer/reveal.api.md index b444a959624..83d9180a7da 100644 --- a/viewer/reveal.api.md +++ b/viewer/reveal.api.md @@ -435,10 +435,10 @@ export class Cognite3DViewer { get domElement(): HTMLElement; enter360Image(image360: Image360, revision?: Image360Revision): Promise; exit360Image(): void; - fitCameraToBoundingBox(box: THREE.Box3, duration?: number, radiusFactor?: number): void; + fitCameraToBoundingBox(boundingBox: THREE.Box3, duration?: number, radiusFactor?: number): void; fitCameraToModel(model: CogniteModel, duration?: number): void; fitCameraToModels(models?: CogniteModel[], duration?: number, restrictToMostGeometry?: boolean): void; - fitCameraToSceneBoundingBox(duration?: number): void; + fitCameraToVisualSceneBoundingBox(duration?: number): void; get360AnnotationIntersectionFromPixel(offsetX: number, offsetY: number): Promise; get360ImageCollections(): Image360Collection[]; getActive360ImageInfo(): Image360WithCollection | undefined; @@ -458,6 +458,8 @@ export class Cognite3DViewer { getScreenshot(width?: number, height?: number, includeUI?: boolean): Promise; getVersion(): string; getViewState(): ViewerState; + // @beta + getVisualSceneBoundingBox(): THREE.Box3; loadCameraFromModel(model: CogniteModel): void; get models(): CogniteModel[]; // (undocumented) From 57c379a457a5db4e57f01d7dfc8e45a4e532c832 Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Thu, 29 Aug 2024 12:12:20 +0200 Subject: [PATCH 6/6] Update Cognite3DViewer.ts --- viewer/packages/api/src/public/migration/Cognite3DViewer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts index 0fe987fc409..6cd7d3a7482 100644 --- a/viewer/packages/api/src/public/migration/Cognite3DViewer.ts +++ b/viewer/packages/api/src/public/migration/Cognite3DViewer.ts @@ -1323,7 +1323,7 @@ export class Cognite3DViewer { } /** - * Move camera to a place where a all objects in the scene are visible + * Move camera to a place where a all objects in the scene are visible. * @param duration The duration of the animation moving the camera. Set this to 0 (zero) to disable animation. */ fitCameraToVisualSceneBoundingBox(duration?: number): void {