From ef7f4b550a5ab522a3d8b7b181271ae0fcec4631 Mon Sep 17 00:00:00 2001 From: AlexandruPopovici Date: Wed, 30 Nov 2022 17:03:29 +0200 Subject: [PATCH] Fixed the commnet bubbles issues with orthographic projection, so we can bring it back in the frontend. Also fixed some issues with camera zooming in orthographic mode and the rendering pipeline, and the zoom in animation --- .../components/viewer/CommentAddOverlay.vue | 2 +- .../components/viewer/CommentsOverlay.vue | 2 +- .../main/components/viewer/ViewerControls.vue | 6 +-- .../src/main/lib/core/composables/dom.ts | 5 +- .../viewer/src/modules/SpeckleRenderer.ts | 1 - packages/viewer/src/modules/Viewer.ts | 2 +- .../src/modules/context/CameraHanlder.js | 27 ++++++++--- .../modules/objects/SpeckleCameraControls.ts | 47 +++++++++++++++++-- 8 files changed, 72 insertions(+), 20 deletions(-) diff --git a/packages/frontend/src/main/components/viewer/CommentAddOverlay.vue b/packages/frontend/src/main/components/viewer/CommentAddOverlay.vue index f2cc32dfe..5faf3188d 100644 --- a/packages/frontend/src/main/components/viewer/CommentAddOverlay.vue +++ b/packages/frontend/src/main/components/viewer/CommentAddOverlay.vue @@ -509,7 +509,7 @@ export default { updateCommentBubble() { if (!this.location) return if (!this.$refs.commentButton) return - const cam = this.viewer.cameraHandler.camera + const cam = this.viewer.cameraHandler.activeCam.camera cam.updateProjectionMatrix() const projectedLocation = this.location.clone() projectedLocation.project(cam) diff --git a/packages/frontend/src/main/components/viewer/CommentsOverlay.vue b/packages/frontend/src/main/components/viewer/CommentsOverlay.vue index d02597332..22c515c8e 100644 --- a/packages/frontend/src/main/components/viewer/CommentsOverlay.vue +++ b/packages/frontend/src/main/components/viewer/CommentsOverlay.vue @@ -565,7 +565,7 @@ export default { }, updateCommentBubbles() { if (!this.comments) return - const cam = this.viewer.cameraHandler.camera + const cam = this.viewer.cameraHandler.activeCam.camera cam.updateProjectionMatrix() for (const comment of this.localComments) { // get html elements diff --git a/packages/frontend/src/main/components/viewer/ViewerControls.vue b/packages/frontend/src/main/components/viewer/ViewerControls.vue index 75d5c5e3f..aed11ef3c 100644 --- a/packages/frontend/src/main/components/viewer/ViewerControls.vue +++ b/packages/frontend/src/main/components/viewer/ViewerControls.vue @@ -30,8 +30,8 @@ - + eventHub.$emit('resize-viewer'), 300) + setTimeout(() => { + // @Dim: Why are we resizing the viewer here? We generally want to avoid needless resizes + eventHub.$emit('resize-viewer') + }, 300) } // Setup resize events diff --git a/packages/viewer/src/modules/SpeckleRenderer.ts b/packages/viewer/src/modules/SpeckleRenderer.ts index 6bf9a3423..cdbe84cb7 100644 --- a/packages/viewer/src/modules/SpeckleRenderer.ts +++ b/packages/viewer/src/modules/SpeckleRenderer.ts @@ -395,7 +395,6 @@ export default class SpeckleRenderer { if (this._needsRender) { this.batcher.render(this.renderer) this._needsRender = this.pipeline.render() - // this.renderer.render(this.scene, this.viewer.cameraHandler.activeCam.camera) // this._needsRender = true } diff --git a/packages/viewer/src/modules/Viewer.ts b/packages/viewer/src/modules/Viewer.ts index ff5393f68..d88bd1cd2 100644 --- a/packages/viewer/src/modules/Viewer.ts +++ b/packages/viewer/src/modules/Viewer.ts @@ -330,7 +330,7 @@ export class Viewer extends EventEmitter implements IViewer { public toggleCameraProjection() { this.cameraHandler.toggleCameras() - this.speckleRenderer.resetPipeline() + this.speckleRenderer.resetPipeline(true) } public setLightConfiguration(config: SunLightConfiguration): void { diff --git a/packages/viewer/src/modules/context/CameraHanlder.js b/packages/viewer/src/modules/context/CameraHanlder.js index e1b7b935b..5bb0a7720 100644 --- a/packages/viewer/src/modules/context/CameraHanlder.js +++ b/packages/viewer/src/modules/context/CameraHanlder.js @@ -291,13 +291,26 @@ export default class CameraHandler { this.viewer.container.offsetWidth / this.viewer.container.offsetHeight this.camera.updateProjectionMatrix() - const aspect = - this.viewer.container.offsetWidth / this.viewer.container.offsetHeight - const fustrumSize = 50 - this.orthoCamera.left = (-fustrumSize * aspect) / 2 - this.orthoCamera.right = (fustrumSize * aspect) / 2 - this.orthoCamera.top = fustrumSize / 2 - this.orthoCamera.bottom = -fustrumSize / 2 + const lineOfSight = new THREE.Vector3() + this.camera.getWorldDirection(lineOfSight) + const target = new THREE.Vector3() + this.controls.getTarget(target) + const distance = target.clone().sub(this.camera.position) + const depth = distance.dot(lineOfSight) + const dims = { + x: this.viewer.container.offsetWidth, + y: this.viewer.container.offsetHeight + } + const aspect = dims.x / dims.y + const fov = this.camera.fov + const height = depth * 2 * Math.atan((fov * (Math.PI / 180)) / 2) + const width = height * aspect + + this.orthoCamera.zoom = 1 + this.orthoCamera.left = width / -2 + this.orthoCamera.right = width / 2 + this.orthoCamera.top = height / 2 + this.orthoCamera.bottom = height / -2 this.orthoCamera.updateProjectionMatrix() } diff --git a/packages/viewer/src/modules/objects/SpeckleCameraControls.ts b/packages/viewer/src/modules/objects/SpeckleCameraControls.ts index 2a93f4988..d7b60a09c 100644 --- a/packages/viewer/src/modules/objects/SpeckleCameraControls.ts +++ b/packages/viewer/src/modules/objects/SpeckleCameraControls.ts @@ -44,7 +44,9 @@ export class SpeckleCameraControls extends CameraControls { private _didDollyLastFrame = false public _isTrucking = false private _hasRestedLastFrame = false + private _didZoom = false private overrideDollyLerpRatio = 0 + private overrideZoomLerpRatio = 0 static install() { _v3A = new Vector3() _v3B = new Vector3() @@ -101,7 +103,7 @@ export class SpeckleCameraControls extends CameraControls { const zoomScale = Math.pow(0.95, delta * this.dollySpeed) // for both PerspectiveCamera and OrthographicCamera - this.zoomTo(this._zoom * zoomScale) + this.zoomTo(this._zoom * zoomScale, false, 1) this._didDolly = true this.dispatchEvent({ type: 'controlstart' }) if (this.dollyToCursor) { @@ -113,6 +115,30 @@ export class SpeckleCameraControls extends CameraControls { return } + /** + * Zoom in/out camera to given scale. The value overwrites camera zoom. + * Limits set with .minZoom and .maxZoom + * @param zoom + * @param enableTransition + * @category Methods + */ + zoomTo( + zoom: number, + enableTransition = false, + lerpRatio: number = undefined + ): Promise { + this._zoomEnd = MathUtils.clamp(zoom, this.minZoom, this.maxZoom) + this._needsUpdate = true + this.overrideZoomLerpRatio = enableTransition ? 0.05 : lerpRatio + if (!enableTransition) { + this._zoom = this._zoomEnd + } + + const resolveImmediately = + !enableTransition || approxEquals(this._zoom, this._zoomEnd, this.restThreshold) + return this._createOnRestPromise(resolveImmediately) + } + /** * Dolly in/out camera position to given distance. * @param distance Distance of dolly. @@ -282,13 +308,22 @@ export class SpeckleCameraControls extends CameraControls { ) } const zoomDelta = this._zoomEnd - this._zoom - this._zoom += zoomDelta * lerpRatio + this._zoom += + zoomDelta * + (this.overrideZoomLerpRatio + ? this.overrideZoomLerpRatio + : this.overrideZoomLerpRatio) if (this._camera.zoom !== this._zoom) { - if (approxZero(zoomDelta)) this._zoom = this._zoomEnd + if (approxZero(zoomDelta)) { + this._zoom = this._zoomEnd + } this._camera.zoom = this._zoom this._camera.updateProjectionMatrix() this._updateNearPlaneCorners() this._needsUpdate = true + this._didZoom = true + } else { + this._didZoom = false } const updated = this._needsUpdate if (updated && !this._updatedLastTime) { @@ -308,7 +343,8 @@ export class SpeckleCameraControls extends CameraControls { approxZero(deltaOffset.y, this.restThreshold) && approxZero(deltaOffset.z, this.restThreshold) && !this._hasRested && - !this._isTrucking + !this._isTrucking && + !this._didZoom ) { this._hasRested = true this.dispatchEvent({ type: 'rest' }) @@ -327,7 +363,8 @@ export class SpeckleCameraControls extends CameraControls { approxZero(deltaOffset.x, this.restThreshold) && approxZero(deltaOffset.y, this.restThreshold) && approxZero(deltaOffset.z, this.restThreshold) && - !this._isTrucking + !this._isTrucking && + !this._didZoom ) { this.dispatchEvent({ type: 'rest' }) this._didDollyLastFrame = false