Skip to content

Commit

Permalink
(fix): Update recalculateBoundingBox in Cognite3DViewer (#4715)
Browse files Browse the repository at this point in the history
* Update Cognite3DViewer.ts

* Update Cognite3DViewer.ts

* Update Cognite3DViewer.ts

* Update reveal.api.md

* Refactoring

* Update Cognite3DViewer.ts
  • Loading branch information
nilscognite authored Aug 29, 2024
1 parent 0a10e92 commit 99deb03
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 29 deletions.
120 changes: 92 additions & 28 deletions viewer/packages/api/src/public/migration/Cognite3DViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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);
}

Expand All @@ -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;
}
Expand All @@ -1281,9 +1322,18 @@ 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.
*/
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
Expand All @@ -1300,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);
}

/**
Expand Down Expand Up @@ -1880,34 +1933,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
for (const model of this.models) {
if (pass === 0 && !model.visible) {
continue;
}
model.getModelBoundingBox(temporaryBox);
if (temporaryBox.isEmpty()) {
continue;
}
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;
// The getModelBoundingBox is using restrictToMostGeometry = true
model.getModelBoundingBox(temporaryBox, true);
if (temporaryBox.isEmpty()) {
continue;
}
sceneBoundingBox.union(temporaryBox);
}
customObject.getBoundingBox(temporaryBox);
if (temporaryBox.isEmpty()) {
return;
for (const customObject of this._sceneHandler.customObjects) {
if (!customObject.object.visible) {
continue;
}
customObject.getBoundingBox(temporaryBox);
if (temporaryBox.isEmpty()) {
continue;
}
nearFarPlaneBoundingBox.union(temporaryBox);
if (!customObject.isPartOfBoundingBox) {
continue;
}
sceneBoundingBox.union(temporaryBox);
}
nearFarPlaneBoundingBox.union(temporaryBox);
if (!customObject.isPartOfBoundingBox) {
return;
if (!sceneBoundingBox.isEmpty()) {
break;
}
sceneBoundingBox.union(temporaryBox);
});
}
}

/** @private */
Expand Down
5 changes: 4 additions & 1 deletion viewer/reveal.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,10 @@ export class Cognite3DViewer {
get domElement(): HTMLElement;
enter360Image(image360: Image360, revision?: Image360Revision): Promise<void>;
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;
fitCameraToVisualSceneBoundingBox(duration?: number): void;
get360AnnotationIntersectionFromPixel(offsetX: number, offsetY: number): Promise<null | Image360AnnotationIntersection>;
get360ImageCollections(): Image360Collection[];
getActive360ImageInfo(): Image360WithCollection | undefined;
Expand All @@ -457,6 +458,8 @@ export class Cognite3DViewer {
getScreenshot(width?: number, height?: number, includeUI?: boolean): Promise<string>;
getVersion(): string;
getViewState(): ViewerState;
// @beta
getVisualSceneBoundingBox(): THREE.Box3;
loadCameraFromModel(model: CogniteModel): void;
get models(): CogniteModel[];
// (undocumented)
Expand Down

0 comments on commit 99deb03

Please sign in to comment.