Fixed the issues in #1611. There is still an issue left, where zooming in in orthographic mode, then switching to perspective does not yield the correct camera distance, especially when the controls target is off model (#1616)

This commit is contained in:
Alexandru Popovici
2023-06-16 15:55:27 +03:00
committed by GitHub
parent 5f6a696def
commit a52bb75414
6 changed files with 55 additions and 25 deletions
+3 -2
View File
@@ -109,7 +109,7 @@ const getStream = () => {
// prettier-ignore
// 'https://speckle.xyz/streams/da9e320dad/commits/5388ef24b8?c=%5B-7.66134,10.82932,6.41935,-0.07739,-13.88552,1.8697,0,1%5D'
// Revit sample house (good for bim-like stuff with many display meshes)
// 'https://speckle.xyz/streams/da9e320dad/commits/5388ef24b8'
'https://speckle.xyz/streams/da9e320dad/commits/5388ef24b8'
// 'https://latest.speckle.dev/streams/c1faab5c62/commits/6c6e43e5f3'
// 'https://latest.speckle.dev/streams/58b5648c4d/commits/60371ecb2d'
// 'Super' heavy revit shit
@@ -270,10 +270,11 @@ const getStream = () => {
// 'https://latest.speckle.dev/streams/c1faab5c62/objects/d3466547df9df86397eb4dff7ac9713f'
// 'https://latest.speckle.dev/streams/c1faab5c62/commits/140c443886'
// 'https://latest.speckle.dev/streams/e258b0e8db/commits/108971810d'
// 'https://latest.speckle.dev/streams/e258b0e8db/objects/3fcd63d80cf791c3f554a795846e62f6'
// 'https://latest.speckle.dev/streams/55cc1cbf0a/objects/d7ae178fb6a7b1f599a177486e14f9a6'
// 'https://latest.speckle.dev/streams/e258b0e8db/objects/3fcd63d80cf791c3f554a795846e62f6'
// 'https://latest.speckle.dev/streams/92b620fb17/commits/6adbcfa8dc'
'https://latest.speckle.dev/streams/92b620fb17/commits/6adbcfa8dc'
// 'https://latest.speckle.dev/streams/92b620fb17/commits/6adbcfa8dc'
)
}
+8 -2
View File
@@ -164,12 +164,18 @@ export interface IViewer {
transition?: boolean
)
loadObject(url: string, token?: string, enableCaching?: boolean): Promise<void>
loadObject(
url: string,
token?: string,
enableCaching?: boolean,
zoomToObject?: boolean
): Promise<void>
loadObjectAsync(
url: string,
token?: string,
enableCaching?: boolean,
priority?: number
priority?: number,
zoomToObject?: boolean
): Promise<void>
cancelLoad(url: string, unload?: boolean): Promise<void>
unloadObject(url: string): Promise<void>
+15 -4
View File
@@ -520,7 +520,11 @@ export default class SpeckleRenderer {
this._needsRender = true
}
public async addRenderTreeAsync(subtreeId: string, priority = 1) {
public async addRenderTreeAsync(
subtreeId: string,
priority = 1,
zoomToObject = true
) {
this.cancel[subtreeId] = false
const subtreeGroup = new Group()
subtreeGroup.name = subtreeId
@@ -537,11 +541,9 @@ export default class SpeckleRenderer {
if (!batch) continue
this.addBatch(batch, subtreeGroup)
this.zoom()
if (zoomToObject) this.zoom()
if (batch.geometryType === GeometryType.MESH) {
this.updateDirectLights()
/** Updating the shadowcatcher after each batch is a bit too much. Stalls a lot */
// this.updateShadowCatcher()
}
this._needsRender = true
if (this.cancel[subtreeId]) {
@@ -1176,6 +1178,7 @@ export default class SpeckleRenderer {
view.view.target['z'],
transition
)
this.viewer.cameraHandler.enableRotations()
}
/**
@@ -1191,12 +1194,14 @@ export default class SpeckleRenderer {
switch (side) {
case 'front':
this.zoomExtents()
this.viewer.cameraHandler.controls.rotateTo(0, DEG90, transition)
if (this.viewer.cameraHandler.activeCam.name === 'ortho')
this.viewer.cameraHandler.disableRotations()
break
case 'back':
this.zoomExtents()
this.viewer.cameraHandler.controls.rotateTo(DEG180, DEG90, transition)
if (this.viewer.cameraHandler.activeCam.name === 'ortho')
this.viewer.cameraHandler.disableRotations()
@@ -1204,6 +1209,7 @@ export default class SpeckleRenderer {
case 'up':
case 'top':
this.zoomExtents()
this.viewer.cameraHandler.controls.rotateTo(0, 0, transition)
if (this.viewer.cameraHandler.activeCam.name === 'ortho')
this.viewer.cameraHandler.disableRotations()
@@ -1211,18 +1217,21 @@ export default class SpeckleRenderer {
case 'down':
case 'bottom':
this.zoomExtents()
this.viewer.cameraHandler.controls.rotateTo(0, DEG180, transition)
if (this.viewer.cameraHandler.activeCam.name === 'ortho')
this.viewer.cameraHandler.disableRotations()
break
case 'right':
this.zoomExtents()
this.viewer.cameraHandler.controls.rotateTo(DEG90, DEG90, transition)
if (this.viewer.cameraHandler.activeCam.name === 'ortho')
this.viewer.cameraHandler.disableRotations()
break
case 'left':
this.zoomExtents()
this.viewer.cameraHandler.controls.rotateTo(-DEG90, DEG90, transition)
if (this.viewer.cameraHandler.activeCam.name === 'ortho')
this.viewer.cameraHandler.disableRotations()
@@ -1261,10 +1270,12 @@ export default class SpeckleRenderer {
view.target.z,
transition
)
this.viewer.cameraHandler.enableRotations()
}
private setViewPolar(view: PolarView, transition = true) {
this.viewer.cameraHandler.controls.rotate(view.azimuth, view.polar, transition)
this.viewer.cameraHandler.enableRotations()
}
public screenToNDC(
+11 -4
View File
@@ -467,7 +467,12 @@ export class Viewer extends EventEmitter implements IViewer {
await loader.load()
}
public async loadObject(url: string, token: string = null, enableCaching = true) {
public async loadObject(
url: string,
token: string = null,
enableCaching = true,
zoomToObject = true
) {
if (++this.inProgressOperations === 1)
(this as EventEmitter).emit(ViewerEvent.Busy, true)
await this.downloadObject(url, token, enableCaching)
@@ -480,7 +485,8 @@ export class Viewer extends EventEmitter implements IViewer {
await this.speckleRenderer.addRenderTree(url)
Logger.log('SYNC batch build time -> ', performance.now() - t0)
this.zoom()
if (zoomToObject) this.zoom()
this.speckleRenderer.resetPipeline(true)
this.emit(ViewerEvent.LoadComplete, url)
this.loaders[url].dispose()
@@ -493,7 +499,8 @@ export class Viewer extends EventEmitter implements IViewer {
url: string,
token: string = null,
enableCaching = true,
priority = 1
priority = 1,
zoomToObject = true
) {
if (++this.inProgressOperations === 1)
(this as EventEmitter).emit(ViewerEvent.Busy, true)
@@ -505,7 +512,7 @@ export class Viewer extends EventEmitter implements IViewer {
if (treeBuilt) {
t0 = performance.now()
await this.speckleRenderer.addRenderTreeAsync(url, priority)
await this.speckleRenderer.addRenderTreeAsync(url, priority, zoomToObject)
Logger.log('ASYNC batch build time -> ', performance.now() - t0)
this.speckleRenderer.resetPipeline(true)
this.emit(ViewerEvent.LoadComplete, url)
@@ -118,10 +118,9 @@ export default class CameraHandler {
const lineOfSight = new THREE.Vector3()
this.camera.getWorldDirection(lineOfSight)
const target = new THREE.Vector3()
this.controls.getTarget(target)
const target = new THREE.Vector3().copy(this.viewer.World.worldOrigin)
const distance = target.clone().sub(this.camera.position)
const depth = distance.dot(lineOfSight)
const depth = distance.length()
const dims = {
x: this.viewer.container.offsetWidth,
y: this.viewer.container.offsetHeight
@@ -141,21 +140,22 @@ export default class CameraHandler {
this.orthoCamera.updateProjectionMatrix()
this.orthoCamera.position.copy(this.camera.position)
this.orthoCamera.quaternion.copy(this.camera.quaternion)
this.orthoCamera.updateProjectionMatrix()
this.controls.camera = this.orthoCamera
// fit the camera inside, so we don't have clipping plane issues.
// WIP implementation
const camPos = this.orthoCamera.position
const box = new THREE.Box3().setFromObject(this.viewer.speckleRenderer.allObjects)
const sphere = new THREE.Sphere()
box.getBoundingSphere(sphere)
// const camPos = this.orthoCamera.position
// const box = new THREE.Box3().setFromObject(this.viewer.speckleRenderer.allObjects)
// const sphere = new THREE.Sphere()
// box.getBoundingSphere(sphere)
let dist = sphere.distanceToPoint(camPos)
if (dist < 0) {
dist *= -1
this.controls.setPosition(camPos.x + dist, camPos.y + dist, camPos.z + dist)
}
// let dist = sphere.distanceToPoint(camPos)
// if (dist < 0) {
// dist *= -1
// this.controls.setPosition(camPos.x + dist, camPos.y + dist, camPos.z + dist)
// }
this.viewer.emit('projection-change', 'ortho')
}
@@ -165,7 +165,7 @@ export default class CameraHandler {
this.camera.position.copy(this.orthoCamera.position)
this.camera.quaternion.copy(this.orthoCamera.quaternion)
this.camera.updateProjectionMatrix()
this.controls.distance = this.previousDistance
// this.controls.distance = this.previousDistance
this.controls.camera = this.camera
this.controls.zoomTo(1)
this.enableRotations()
@@ -47,6 +47,7 @@ export class SpeckleCameraControls extends CameraControls {
private _didZoom = false
private overrideDollyLerpRatio = 0
private overrideZoomLerpRatio = 0
static install() {
_v3A = new Vector3()
_v3B = new Vector3()
@@ -101,6 +102,10 @@ export class SpeckleCameraControls extends CameraControls {
protected _zoomInternal = (delta: number, x: number, y: number): void => {
const zoomScale = Math.pow(0.95, delta * this.dollySpeed)
/** We need to move the camera as well when zooming in orthographic mode */
const dollyScale = Math.pow(0.95, -delta * this.dollySpeed)
const distance = this._sphericalEnd.radius * dollyScale
this.dollyTo(distance, true, 0.9)
// for both PerspectiveCamera and OrthographicCamera
this.zoomTo(this._zoom * zoomScale, false, 1)