diff --git a/CHANGELOG.md b/CHANGELOG.md index 51c32f32628150a617d4e26313e117d2dcd615ef..cca3f467d493717268808df9ad3646ee08d9906c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Note that since we don't clearly distinguish between a public and private interf ## [Unreleased] + - Handle resizes of viewer element even when window remains the same size - Throttle canvas resize events - Selection toggle buttons hidden if selection mode is off @@ -16,6 +17,7 @@ Note that since we don't clearly distinguish between a public and private interf - Apply bumpiness as lightness variation with `ignoreLight` - Remove `JSX` reference from `loci-labels.ts` - Fix overpaint/transparency/substance smoothing not updated when geometry changes +- Fix camera project/unproject when using offset viewport ## [v3.32.0] - 2023-03-20 diff --git a/src/mol-canvas3d/_spec/camera.spec.ts b/src/mol-canvas3d/_spec/camera.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..84cbdbcdbb6b176f6c58e044e19f6abe6ac431a4 --- /dev/null +++ b/src/mol-canvas3d/_spec/camera.spec.ts @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2023 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Vec3, Vec4 } from '../../mol-math/linear-algebra'; +import { Mat4 } from '../../mol-math/linear-algebra/3d/mat4'; +import { Viewport, cameraProject, cameraUnproject } from '../camera/util'; + +describe('camera', () => { + it('project/unproject', () => { + const proj = Mat4.perspective(Mat4(), -1, 1, 1, -1, 1, 100); + const invProj = Mat4.invert(Mat4(), proj); + + const c = Vec4(); + const po = Vec3(); + + const vp = Viewport.create(0, 0, 100, 100); + const pi = Vec3.create(0, 0, 1); + cameraProject(c, pi, vp, proj); + expect(Vec4.equals(c, Vec4.create(50, 50, 2.020202, -1))).toBe(true); + cameraUnproject(po, c, vp, invProj); + expect(Vec3.equals(po, pi)).toBe(true); + + Vec3.set(pi, 0.5, 0.5, 1); + cameraProject(c, pi, vp, proj); + cameraUnproject(po, c, vp, invProj); + expect(Vec3.equals(po, pi)).toBe(true); + + Viewport.set(vp, 50, 50, 100, 100); + Vec3.set(pi, 0.5, 0.5, 1); + cameraProject(c, pi, vp, proj); + cameraUnproject(po, c, vp, invProj); + expect(Vec3.equals(po, pi)).toBe(true); + }); +}); \ No newline at end of file diff --git a/src/mol-canvas3d/camera.ts b/src/mol-canvas3d/camera.ts index 72b788c2320df29ed697cba1e7bc41f64574292c..702006bf2cd63b1e3d368e4dc2156d2dcb5d1f02 100644 --- a/src/mol-canvas3d/camera.ts +++ b/src/mol-canvas3d/camera.ts @@ -194,7 +194,7 @@ class Camera implements ICamera { getPixelSize(point: Vec3) { // project -> unproject of `point` does not exactly return the same // to get a sufficiently accurate measure we unproject the original - // clip position in addition to the one shifted bey one pixel + // clip position in addition to the one shifted by one pixel this.project(tmpClip, point); this.unproject(tmpPos1, tmpClip); tmpClip[0] += 1; diff --git a/src/mol-canvas3d/camera/util.ts b/src/mol-canvas3d/camera/util.ts index 573d123133eee967a8cbfa0012825f957edcacfb..5929b716ea4e1237dc24fdc6b780a23aebd3a9bd 100644 --- a/src/mol-canvas3d/camera/util.ts +++ b/src/mol-canvas3d/camera/util.ts @@ -77,7 +77,7 @@ export function cameraProject(out: Vec4, point: Vec3, viewport: Viewport, projec // transform into window coordinates, set fourth component to 1 / clip.w as in gl_FragCoord.w out[0] = (tmpVec4[0] + 1) * width * 0.5 + x; - out[1] = (1 - tmpVec4[1]) * height * 0.5 + y; // flip Y + out[1] = (tmpVec4[1] + 1) * height * 0.5 + y; out[2] = (tmpVec4[2] + 1) * 0.5; out[3] = w === 0 ? 0 : 1 / w; return out; @@ -92,7 +92,7 @@ export function cameraUnproject(out: Vec3, point: Vec3 | Vec4, viewport: Viewpor const { x, y, width, height } = viewport; const px = point[0] - x; - const py = (height - point[1] - 1) - y; + const py = point[1] - y; const pz = point[2]; out[0] = (2 * px) / width - 1; diff --git a/src/mol-canvas3d/passes/pick.ts b/src/mol-canvas3d/passes/pick.ts index 8df182f66519b1c6332fcfc7b870e83e44b95410..0dd6473211d01a153100c44a415fe0e623987774 100644 --- a/src/mol-canvas3d/passes/pick.ts +++ b/src/mol-canvas3d/passes/pick.ts @@ -358,7 +358,7 @@ export class PickHelper { const z = this.getDepth(xp, yp); // console.log('z', z); - const position = Vec3.create(x, viewport.height - y, z); + const position = Vec3.create(x, y, z); if (StereoCamera.is(camera)) { const halfWidth = Math.floor(viewport.width / 2); if (x > viewport.x + halfWidth) {