diff --git a/CHANGELOG.md b/CHANGELOG.md index 05b18f6276784127bd88e32e1638280f6b525bbc..93cc94ca22c91b4f83b06dd845311c8e2dfce517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ Note that since we don't clearly distinguish between a public and private interf - Add StructureElement.Loci.forEachLocation - Add RepresentationRegistry.clear and ThemeRegistry.clear - Add generic Loci support for overpaint, substance, clipping themes +- Add `.getCenter` and `.center` to `Camera` ## [v3.28.0] - 2022-12-20 diff --git a/src/mol-canvas3d/camera.ts b/src/mol-canvas3d/camera.ts index 169478586e24ba8d072321be640a24eccfb887e2..50ba8fe635fd7b535c291df209c61a1a25b1616a 100644 --- a/src/mol-canvas3d/camera.ts +++ b/src/mol-canvas3d/camera.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> * @author Alexander Rose <alexander.rose@weirdbyte.de> @@ -137,6 +137,18 @@ class Camera implements ICamera { return state; } + getCenter(target: Vec3, radius?: number): Partial<Camera.Snapshot> { + Vec3.sub(this.deltaDirection, this.target, this.position); + Vec3.sub(this.newPosition, target, this.deltaDirection); + + const state = Camera.copySnapshot(Camera.createDefaultSnapshot(), this.state); + state.target = Vec3.clone(target); + state.position = Vec3.clone(this.newPosition); + if (radius) state.radius = Math.max(radius, 0.01); + + return state; + } + getInvariantFocus(target: Vec3, radius: number, up: Vec3, dir: Vec3): Partial<Camera.Snapshot> { const r = Math.max(radius, 0.01); const targetDistance = this.getTargetDistance(r); @@ -160,6 +172,10 @@ class Camera implements ICamera { } } + center(target: Vec3, durationMs?: number) { + this.setState(this.getCenter(target), durationMs); + } + /** Transform point into 2D window coordinates. */ project(out: Vec4, point: Vec3) { return cameraProject(out, point, this.viewport, this.projectionView); diff --git a/src/mol-plugin-state/manager/camera.ts b/src/mol-plugin-state/manager/camera.ts index b4a4f8fb9a49671df57dfa67f2b1531b9ea67887..10f5583e7c1f3ec243c5c574602d1e31a15579aa 100644 --- a/src/mol-plugin-state/manager/camera.ts +++ b/src/mol-plugin-state/manager/camera.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2019-2023 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> * @author Alexander Rose <alexander.rose@weirdbyte.de> @@ -18,7 +18,7 @@ import { StructureElement } from '../../mol-model/structure'; const DefaultCameraFocusOptions = { minRadius: 5, extraRadius: 4, - durationMs: 250 + durationMs: 250, }; export type CameraFocusOptions = typeof DefaultCameraFocusOptions @@ -107,19 +107,19 @@ export class CameraManager { } focusSphere(sphere: Sphere3D, options?: Partial<CameraFocusOptions> & { principalAxes?: PrincipalAxes }) { + const { canvas3d } = this.plugin; + if (!canvas3d) return; + const { extraRadius, minRadius, durationMs } = { ...DefaultCameraFocusOptions, ...options }; const radius = Math.max(sphere.radius + extraRadius, minRadius); if (options?.principalAxes) { const { origin, dirA, dirC } = options?.principalAxes.boxAxes; - const snapshot = this.plugin.canvas3d?.camera.getFocus(origin, radius, dirA, dirC); - this.plugin.canvas3d?.requestCameraReset({ durationMs, snapshot }); - // this.plugin.canvas3d?.camera.focus(origin, radius, durationMs, dirA, dirC); + const snapshot = canvas3d.camera.getFocus(origin, radius, dirA, dirC); + canvas3d.requestCameraReset({ durationMs, snapshot }); } else { - const snapshot = this.plugin.canvas3d?.camera.getFocus(sphere.center, radius); - this.plugin.canvas3d?.requestCameraReset({ durationMs, snapshot }); - - // this.plugin.canvas3d?.camera.focus(sphere.center, radius, durationMs); + const snapshot = canvas3d.camera.getFocus(sphere.center, radius); + canvas3d.requestCameraReset({ durationMs, snapshot }); } }