Skip to content

Commit

Permalink
chore: backport selected improvements and fixes to 3.2.x release bran…
Browse files Browse the repository at this point in the history
…ch (#2635)

* chore: add workflow that deploys to NPM on Github release (#2586)

* test: initial dry run publish

* chore: trigger release on released published

* fix: remove caching on release workflow

Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com>

* fix: expose and fix bug causing getBoundingBoxByNodeId/TreeIndex not to modify out parameter (#2472)

* refact: keyboard and mouse event handling in viewer (#2492)

* Intermediate commit

* Removed isFocused check in keyboard handling

* Keyboard active only which domElement is focused, mouse events are active when canvas is focused

* Refactored axisview eventlistener

* Reverted axisview event passed to domElement

* updated examples yarn.lock

* clean up

* leftover clean up

* Keyboard event listen on domElement, removed unnecessary event push to domElement from Axis cross

* removed unused variables

* clean up

* Fixed visual test error

Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com>

* fixed point cloud picking precision issue (#2508)

Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com>

* improvement: use 'high-performance' powerPreference to avoid non-discrete GPU being used on certain systems (#2512)

* feat: add metrics to MeasurementTool (#2523)

* chore: backport to old file structure

* fix: remove flat modifier, while maintaining TreeIndex precision (#2536)

Contribution by @Strepto (Equinor)

* fix: do not blend in-front and back frame buffers when back objects have not been rendered (#2540)

Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com>

* fix: visualization artifacts due to wrongfully handling cylinder clip planes (#2556)

* fix: simplify shader

* fix: set proper plane length

* fix: reduce some matrix transformations, and use built-in face-forward

* fix: plane magnitude not adjusting for scaled world transform

* fix: bad merge

* chore: revert CDF environments json

* chore: add primitive test fixture

Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com>

* improvement: make CadModelUpdateHandler trigger sector loading immediately after the camera stops moving (#2573)

* Make CadModelUpdateHandler trigger sector loading immediately after the camera stops moving

* Remove setting of redraw flag

* Update test

* Fix test

Co-authored-by: Christopher J. Tannum <[email protected]>

* Use vec2 instead of struct for packing TreeIndexes (#2585)

This works around an issue with struct precision on ardeno gpus: KhronosGroup/WebGL#3351

* fix: general cylinder inside rendering (#2620)

* fix: rendering if camera is inside primitive

* fix: reverse normal direction if hitting inside of cylinder

* fix: enable depth writing for in-front pass (#2621)

* Enable depth writing for in-front pass

* Set depth to minimum of in-front and back pass

Co-authored-by: Christopher J. Tannum <[email protected]>

* fix: remove unused pcMaterialManager from bad merge

* fix: re-create v8 test image due to cylinder clipping planes fix

Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Lars Moastuen <[email protected]>
Co-authored-by: Pramod S <[email protected]>
Co-authored-by: Nils Henrik Hals <[email protected]>
Co-authored-by: eiriklegernaes <[email protected]>
Co-authored-by: Håkon Flatval <[email protected]>
  • Loading branch information
7 people authored Nov 3, 2022
1 parent 710c61e commit f3b5a9d
Show file tree
Hide file tree
Showing 68 changed files with 576 additions and 295 deletions.
Binary file modified examples/public/primitives/0.glb
Binary file not shown.
2 changes: 1 addition & 1 deletion examples/public/primitives/scene.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":9,"projectId":123,"modelId":456,"revisionId":789,"subRevisionId":999,"maxTreeIndex":76,"sectors":[{"id":0,"sectorFileName":"0.glb","path":"0/","depth":0,"boundingBox":{"min":{"x":-1.3934096876224187,"y":-1,"z":-1.788780573085674},"max":{"x":28.29323544313644,"y":25.458996612973937,"z":1.6256651949082248}},"estimatedTriangleCount":11632,"estimatedDrawCallCount":17,"minDiagonalLength":2,"maxDiagonalLength":2.8284270763397217,"downloadSize":27928}]}
{"version":9,"projectId":123,"modelId":456,"revisionId":789,"subRevisionId":999,"maxTreeIndex":76,"sectors":[{"id":0,"sectorFileName":"0.glb","path":"0/","depth":0,"boundingBox":{"min":{"x":-1.3934096876224187,"y":-1,"z":-1.788780573085674},"max":{"x":28.29323544313644,"y":25.458996612973937,"z":1.6256651949082248}},"geometryBoundingBox":{"min":{"x":-1.3934096876224187,"y":-1,"z":-1.788780573085674},"max":{"x":28.29323544313644,"y":25.458996612973937,"z":1.6256651949082248}},"estimatedTriangleCount":11632,"estimatedDrawCallCount":17,"minDiagonalLength":2,"maxDiagonalLength":2.8284270763397217,"downloadSize":27928}]}
4 changes: 3 additions & 1 deletion viewer/extensions/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ export {
ModelMetadataProvider,
ModelDataProvider,
BlobOutputMetadata,
File3dFormat
File3dFormat,
JsonFileProvider,
BinaryFileProvider
} from '../packages/modeldata-api';
3 changes: 2 additions & 1 deletion viewer/packages/api/src/public/RevealManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,14 @@ export class RevealManager {
!this._lastCamera.position.equals(camera.position) ||
!this._lastCamera.quaternion.equals(camera.quaternion);

this._cadManager.updateCamera(camera, hasCameraChanged);

if (hasCameraChanged) {
this._lastCamera.position.copy(camera.position);
this._lastCamera.quaternion.copy(camera.quaternion);
this._lastCamera.zoom = camera.zoom;
this._lastCamera.fov = camera.fov;

this._cadManager.updateCamera(camera);
this._pointCloudManager.updateCamera(camera);

this._updateSubject.next();
Expand Down
7 changes: 4 additions & 3 deletions viewer/packages/api/src/public/migration/Cognite3DViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ export class Cognite3DViewer {
this.canvas.style.maxHeight = '100%';

this._domElement = options.domElement ?? createCanvasWrapper();
this._domElement.tabIndex = 0;
this._domElement.appendChild(this.canvas);
this._domElementResizeObserver = this.setupDomElementResizeListener(this._domElement);

Expand All @@ -222,11 +223,11 @@ export class Cognite3DViewer {

this._sceneHandler = new SceneHandler();

this._mouseHandler = new InputHandler(this.canvas);
this._mouseHandler = new InputHandler(this.domElement);

this._cameraManager =
options.cameraManager ??
new DefaultCameraManager(this.canvas, this._mouseHandler, this.modelIntersectionCallback.bind(this));
new DefaultCameraManager(this._domElement, this._mouseHandler, this.modelIntersectionCallback.bind(this));

this._cameraManager.on('cameraChange', (position: THREE.Vector3, target: THREE.Vector3) => {
this._events.cameraChange.fire(position.clone(), target.clone());
Expand Down Expand Up @@ -1249,7 +1250,7 @@ function createCanvasWrapper(): HTMLElement {
}

function createRenderer(): THREE.WebGLRenderer {
const renderer = new THREE.WebGLRenderer();
const renderer = new THREE.WebGLRenderer({ powerPreference: 'high-performance' });
renderer.setPixelRatio(window.devicePixelRatio);
return renderer;
}
Expand Down
6 changes: 5 additions & 1 deletion viewer/packages/api/src/public/migration/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ export interface Cognite3DViewerOptions {
* Default implementation is {@link DefaultCameraManager}.
*/
cameraManager?: CameraManager;
/** Renderer used to visualize model (optional). */
/**
* Renderer used to visualize model (optional).
* Note that when providing a custom renderer, this should be configured with
* `'powerPreference': 'high-performance'` for best performance.
*/
renderer?: THREE.WebGLRenderer;

/**
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 2 additions & 3 deletions viewer/packages/cad-geometry-loaders/src/CadManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,8 @@ export class CadManager {
return this._needsRedraw;
}

updateCamera(camera: THREE.PerspectiveCamera): void {
this._cadModelUpdateHandler.updateCamera(camera);
this._needsRedraw = true;
updateCamera(camera: THREE.PerspectiveCamera, cameraInMotion: boolean): void {
this._cadModelUpdateHandler.updateCamera(camera, cameraInMotion);
}

get clippingPlanes(): THREE.Plane[] {
Expand Down
43 changes: 29 additions & 14 deletions viewer/packages/cad-geometry-loaders/src/CadModelUpdateHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@ import { assertNever } from '@reveal/utilities';
import { ConsumedSector } from '@reveal/cad-parsers';

import { Subject, Observable, combineLatest, asyncScheduler, BehaviorSubject } from 'rxjs';
import { scan, share, startWith, auditTime, filter, map, observeOn, mergeMap } from 'rxjs/operators';
import {
scan,
share,
startWith,
auditTime,
filter,
map,
observeOn,
mergeMap,
distinctUntilKeyChanged,
mergeWith
} from 'rxjs/operators';
import { SectorCuller } from './sector/culling/SectorCuller';
import { CadLoadingHints } from './CadLoadingHints';

import { LoadingState } from '@reveal/model-base';
import { emissionLastMillis } from './utilities/rxOperations';
import { loadingEnabled } from './sector/rxSectorUtilities';
import { SectorLoader } from './sector/SectorLoader';
import { CadModelBudget, defaultCadModelBudget } from './CadModelBudget';
Expand All @@ -29,7 +39,7 @@ export class CadModelUpdateHandler {
private _budget: CadModelBudget;
private _lastSpent: SectorLoadingSpent;

private readonly _cameraSubject: Subject<THREE.PerspectiveCamera> = new Subject();
private readonly _cameraSubject: Subject<CameraInput> = new Subject();
private readonly _clippingPlaneSubject: Subject<THREE.Plane[]> = new Subject();
private readonly _loadingHintsSubject: Subject<CadLoadingHints> = new Subject();
private readonly _prioritizedLoadingHintsSubject: Subject<void> = new Subject();
Expand Down Expand Up @@ -69,14 +79,20 @@ export class CadModelUpdateHandler {
combineLatest([
this._loadingHintsSubject.pipe(startWith({} as CadLoadingHints)),
this._budgetSubject.pipe(startWith(this._budget))
]).pipe(map(makeSettingsInput)),
this._prioritizedLoadingHintsSubject.pipe(startWith(undefined as void)),
combineLatest([
this._cameraSubject.pipe(auditTime(500)),
this._cameraSubject.pipe(auditTime(250), emissionLastMillis(600))
]).pipe(map(makeCameraInput)),
combineLatest([this._clippingPlaneSubject.pipe(startWith([]))]).pipe(map(makeClippingInput)),
this.loadingModelObservable()
]).pipe(map(makeSettingsInput), auditTime(250)),
this._prioritizedLoadingHintsSubject.pipe(startWith(undefined as void), auditTime(250)),
this._cameraSubject.pipe(
auditTime(500),
filter((input: CameraInput) => input.cameraInMotion),
mergeWith(
this._cameraSubject.pipe(
distinctUntilKeyChanged('cameraInMotion'),
filter((input: CameraInput) => !input.cameraInMotion)
)
)
),
combineLatest([this._clippingPlaneSubject.pipe(startWith([]))]).pipe(map(makeClippingInput), auditTime(250)),
this.loadingModelObservable().pipe(auditTime(250))
]);
const collectStatisticsCallback = (spendage: SectorLoadingSpent) => {
this._lastSpent = spendage;
Expand Down Expand Up @@ -106,7 +122,6 @@ export class CadModelUpdateHandler {

this._updateObservable = combinator.pipe(
observeOn(asyncScheduler), // Schedule tasks on macro task queue (setInterval)
auditTime(250), // Take the last value every 250ms
map(createDetermineSectorsInput), // Map from array to interface (enables destructuring)
filter(loadingEnabled), // should we load?
mergeMap(async x => loadSectors(x)),
Expand All @@ -120,8 +135,8 @@ export class CadModelUpdateHandler {
this._sectorCuller.dispose();
}

updateCamera(camera: THREE.PerspectiveCamera): void {
this._cameraSubject.next(camera);
updateCamera(camera: THREE.PerspectiveCamera, cameraInMotion: boolean): void {
this._cameraSubject.next(makeCameraInput([camera, cameraInMotion]));
}

set clippingPlanes(value: THREE.Plane[]) {
Expand Down
17 changes: 0 additions & 17 deletions viewer/packages/cad-geometry-loaders/src/utilities/rxOperations.ts

This file was deleted.

42 changes: 41 additions & 1 deletion viewer/packages/cad-model/src/wrappers/Cognite3DModel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,48 @@
* Copyright 2021 Cognite AS
*/

import * as THREE from 'three';
import { Cognite3DModel } from './Cognite3DModel';

import { DefaultNodeAppearance, NodeAppearance, TreeIndexNodeCollection } from '@reveal/cad-styling';
import { NodesApiClient } from '@reveal/nodes-api';

import { MetricsLogger } from '@reveal/metrics';
import { createCadModel } from '../../../../test-utilities';
import { It, Mock } from 'moq.ts';

describe(Cognite3DModel.name, () => {
let model: Cognite3DModel;
let mockApiClient: Mock<NodesApiClient>;

beforeAll(() => {
MetricsLogger.init(false, '', '', {});
});

beforeEach(() => {
model = createCadModel(1, 2, 3, 3);
mockApiClient = new Mock<NodesApiClient>();
mockApiClient
.setup(x => x.mapNodeIdsToTreeIndices(It.IsAny(), It.IsAny(), It.IsAny()))
.callback(expression => {
const nodeIds: number[] = expression.args[2];
return Promise.resolve(nodeIds);
});
mockApiClient
.setup(x => x.mapTreeIndicesToNodeIds(It.IsAny(), It.IsAny(), It.IsAny()))
.callback(expression => {
const treeIndices: number[] = expression.args[2];
return Promise.resolve(treeIndices);
});
mockApiClient
.setup(x => x.getBoundingBoxesByNodeIds(It.IsAny(), It.IsAny(), It.IsAny()))
.callback(expression => {
const nodeIds: number[] = expression.args[2];
const bboxes = nodeIds.map(
id => new THREE.Box3(new THREE.Vector3(id, id, id), new THREE.Vector3(id + 1, id + 1, id + 1))
);
return Promise.resolve(bboxes);
});
model = createCadModel(1, 2, 3, 3, mockApiClient.object());
});

test('(un)assignStyledNodeCollection maintains list of collections correctly', () => {
Expand Down Expand Up @@ -58,4 +84,18 @@ describe(Cognite3DModel.name, () => {

expect(model.styledNodeCollections).toBeEmpty();
});

test('getBoundingBoxByTreeIndex() modifies out-parameter', async () => {
const bbox = new THREE.Box3();
const result = await model.getBoundingBoxByTreeIndex(1, bbox);
expect(result).toBe(bbox);
expect(result).not.toEqual(new THREE.Box3());
});

test('getBoundingBoxByNodeId() modifies out-parameter', async () => {
const bbox = new THREE.Box3();
const result = await model.getBoundingBoxByNodeId(1, bbox);
expect(result).toBe(bbox);
expect(result).not.toEqual(new THREE.Box3());
});
});
3 changes: 2 additions & 1 deletion viewer/packages/cad-model/src/wrappers/Cognite3DModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,10 +421,11 @@ export class Cognite3DModel extends THREE.Object3D implements CogniteModelBase,
*/
async getBoundingBoxByNodeId(nodeId: number, box?: THREE.Box3): Promise<THREE.Box3> {
try {
box = box ?? new THREE.Box3();
const boxesResponse = await this.nodesApiClient.getBoundingBoxesByNodeIds(this.modelId, this.revisionId, [
nodeId
]);
box = boxesResponse[0];
box.copy(boxesResponse[0]);
box.applyMatrix4(this.cadModel.modelMatrix);
return box;
} catch (error) {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions viewer/packages/camera-manager/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ function init() {

scene = new THREE.Scene();

keyboard = new Keyboard();

const grid = new THREE.GridHelper(40, 40);
scene.add(grid);

Expand All @@ -44,6 +42,8 @@ function init() {
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(render);

keyboard = new Keyboard(renderer.domElement);

controls = new ComboControls(camera, renderer.domElement);

controls.dynamicTarget = true;
Expand Down
24 changes: 5 additions & 19 deletions viewer/packages/camera-manager/src/ComboControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,20 @@ export class ComboControls extends EventDispatcher {
private _sphericalEnd: Spherical = new Spherical();
private readonly _deltaTarget: Vector3 = new Vector3();
private readonly _rawCameraRotation = new Quaternion();
private _keyboard: Keyboard = new Keyboard();
private readonly _keyboard: Keyboard;

private readonly _offsetVector: Vector3 = new Vector3();
private readonly _panVector: Vector3 = new Vector3();
private readonly _raycaster: Raycaster = new Raycaster();
private readonly _targetFPS: number = 30;
private _targetFPSOverActualFPS: number = 1;
private _isFocused = false;

constructor(camera: PerspectiveCamera | OrthographicCamera, domElement: HTMLElement) {
super();
this._camera = camera;
this._reusableCamera = camera.clone() as typeof camera;
this._domElement = domElement;
this._keyboard = new Keyboard(this._domElement);

// rotation

Expand Down Expand Up @@ -387,23 +387,9 @@ export class ComboControls extends EventDispatcher {
};

private readonly onFocusChanged = (event: MouseEvent | TouchEvent | FocusEvent) => {
this._isFocused =
event.type !== 'blur' &&
(this.isDescendant(this._domElement.parentElement!, event.target as HTMLElement) ||
document.activeElement === this._domElement);

this._keyboard.disabled = !this._isFocused;
};

private readonly isDescendant = (parent: HTMLElement, child: HTMLElement) => {
let node = child.parentNode;
while (node !== null) {
if (node === parent) {
return true;
}
node = node.parentNode;
if (event.type !== 'blur') {
this._keyboard.disabled = false;
}
return false;
};

private readonly onContextMenu = (event: MouseEvent) => {
Expand Down Expand Up @@ -555,7 +541,7 @@ export class ComboControls extends EventDispatcher {
};

private readonly handleKeyboard = () => {
if (!this.enabled || !this.enableKeyboardNavigation || !this._isFocused) {
if (!this.enabled || !this.enableKeyboardNavigation) {
return;
}

Expand Down
16 changes: 9 additions & 7 deletions viewer/packages/camera-manager/src/Keyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const keyMap: { [s: string]: string } = {
export default class Keyboard {
private keys: { [s: string]: number } = {};
private _disabled = false;
private readonly _domElement: HTMLElement;

get disabled(): boolean {
return this._disabled;
Expand All @@ -40,7 +41,8 @@ export default class Keyboard {
}
}

constructor() {
constructor(domElement: HTMLElement) {
this._domElement = domElement;
this.addEventListeners();
}

Expand All @@ -64,15 +66,15 @@ export default class Keyboard {
private readonly addEventListeners = () => {
this.clearPressedKeys();

window.addEventListener('keydown', this.onKeydown);
window.addEventListener('keyup', this.onKeyup);
window.addEventListener('blur', this.clearPressedKeys);
this._domElement.addEventListener('keydown', this.onKeydown);
this._domElement.addEventListener('keyup', this.onKeyup);
this._domElement.addEventListener('blur', this.clearPressedKeys);
};

private readonly removeEventListeners = () => {
window.removeEventListener('keydown', this.onKeydown);
window.removeEventListener('keyup', this.onKeyup);
window.removeEventListener('blur', this.clearPressedKeys);
this._domElement.removeEventListener('keydown', this.onKeydown);
this._domElement.removeEventListener('keyup', this.onKeyup);
this._domElement.removeEventListener('blur', this.clearPressedKeys);
};

private readonly onKeydown = (event: KeyboardEvent) => {
Expand Down
3 changes: 2 additions & 1 deletion viewer/packages/metrics/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export type TrackedEvents =
| 'cameraNavigated'
| 'toolCreated'
| 'cadModelStyleAssigned'
| 'cadNodeTransformOverridden';
| 'cadNodeTransformOverridden'
| 'measurementAdded';

export type EventProps = {
[key: string]: any;
Expand Down
2 changes: 1 addition & 1 deletion viewer/packages/modeldata-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ export { LocalModelIdentifier } from './src/LocalModelIdentifier';
export { LocalModelMetadataProvider } from './src/LocalModelMetadataProvider';
export { ModelIdentifier } from './src/ModelIdentifier';
export { ModelMetadataProvider } from './src/ModelMetadataProvider';
export { BinaryFileProvider, File3dFormat, ModelDataProvider, BlobOutputMetadata } from './src/types';
export { BinaryFileProvider, JsonFileProvider, File3dFormat, ModelDataProvider, BlobOutputMetadata } from './src/types';
Loading

0 comments on commit f3b5a9d

Please sign in to comment.