From 4b50540c383cd2a67d79110c9bd414ce479658dc Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 30 May 2024 17:10:17 -0400 Subject: [PATCH] fix: only reset camera in views Avoids 3d reset in viewport from overriding 2d reset in view-2d if timing is strange --- packages/viewer/src/view-2d.ts | 54 ++++++++++++++++++++++++--------- packages/viewer/src/viewport.ts | 20 +----------- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/packages/viewer/src/view-2d.ts b/packages/viewer/src/view-2d.ts index 1f802369..95a68b05 100644 --- a/packages/viewer/src/view-2d.ts +++ b/packages/viewer/src/view-2d.ts @@ -5,6 +5,7 @@ import { enqueueActions, fromPromise, setup, + stateIn, } from 'xstate'; import { MultiscaleSpatialImage, @@ -147,17 +148,18 @@ export const view2d = setup({ ), findDefaultAxis: fromPromise( async ({ - input: { image }, + input: { image, scale }, }: { input: { image: MultiscaleSpatialImage; + scale: number; }; }) => { - const ijkSpacing = await image.scaleSpacing(image.coarsestScale); + const ijkSpacing = await image.scaleSpacing(scale); if (ijkSpacing.length > 3) { ijkSpacing.push(0); } - const shape = image.scaleInfos[image.coarsestScale].arrayShape; + const shape = image.scaleInfos[scale].arrayShape; const shape3d = ensuredDims(0, ['x', 'y', 'z'], shape); const shapeArray = XYZ.map((axis) => shape3d.get(axis)!); return computeMinSizeAxis(ijkSpacing, shapeArray); @@ -185,7 +187,6 @@ export const view2d = setup({ const withAxis = { ...currentPose }; withAxis.rotation = toRotation(image.direction, axis); - await image.scaleIndexToWorld(scale); // ??? TODO: this makes reset work... const indexToWorld = await image.scaleIndexToWorld(scale); const indexBounds = image.getIndexExtent(scale); const corners = getCorners(indexBounds); @@ -257,14 +258,18 @@ export const view2d = setup({ ], target: '.findingNewImageDefaults', }, - setSlice: { - actions: [assign({ slice: ({ event }) => event.slice })], - target: '.buildingImage', - }, - setScale: { - actions: [assign({ scale: ({ event }) => event.scale })], - target: '.buildingImage', - }, + setSlice: [ + // if buildingImage, rebuild image + { + guard: stateIn('view2d.buildingImage'), + target: '.buildingImage', + actions: [assign({ slice: ({ event }) => event.slice })], + }, + // else eventually going to buildingImage + { + actions: [assign({ slice: ({ event }) => event.slice })], + }, + ], setViewport: { actions: [ assign({ @@ -292,14 +297,21 @@ export const view2d = setup({ }, initial: 'idle', states: { - idle: {}, + idle: { + on: { + setScale: { + actions: [assign({ scale: ({ event }) => event.scale })], + }, + }, + }, findingNewImageDefaults: { invoke: { input: ({ context }) => { - const { image } = context; + const { image, scale } = context; if (!image) throw new Error('No image available'); return { image, + scale, }; }, src: 'findDefaultAxis', @@ -321,6 +333,13 @@ export const view2d = setup({ target: 'buildingImage', }, }, + on: { + setScale: { + actions: [assign({ scale: ({ event }) => event.scale })], + target: '.', + reenter: true, + }, + }, }, buildingImage: { invoke: { @@ -348,6 +367,13 @@ export const view2d = setup({ }), ], }, + on: { + setScale: { + actions: [assign({ scale: ({ event }) => event.scale })], + target: '.', + reenter: true, + }, + }, }, }, }, diff --git a/packages/viewer/src/viewport.ts b/packages/viewer/src/viewport.ts index 2d9265f3..cc2f5593 100644 --- a/packages/viewer/src/viewport.ts +++ b/packages/viewer/src/viewport.ts @@ -2,7 +2,7 @@ import { Actor, AnyActorRef, assign, sendParent, setup } from 'xstate'; import { ReadonlyMat4 } from 'gl-matrix'; import { MultiscaleSpatialImage } from '@itk-viewer/io/MultiscaleSpatialImage.js'; -import { cameraMachine, Camera, reset3d } from './camera.js'; +import { cameraMachine, Camera } from './camera.js'; import { CreateChild } from './children.js'; type Context = { @@ -48,22 +48,6 @@ export const viewportMachine = setup({ actor.send(event); }); }, - resetCameraPose: async ({ context: { image, resolution: dims }, self }) => { - const { camera } = self.getSnapshot().children; - if (!image || !camera) return; - - const aspect = (() => { - return dims[1] && dims[0] ? dims[0] / dims[1] : 1; - })(); - const bounds = await image.getWorldBounds(image.coarsestScale); - const { pose: currentPose, verticalFieldOfView } = - camera.getSnapshot().context; - const pose = reset3d(currentPose, verticalFieldOfView, bounds, aspect); - camera.send({ - type: 'setPose', - pose, - }); - }, }, }).createMachine({ id: 'viewport', @@ -104,7 +88,6 @@ export const viewportMachine = setup({ assign({ image: ({ event: { image } }: { event: SetImageEvent }) => image, }), - 'resetCameraPose', 'forwardToSpawned', ], }, @@ -114,7 +97,6 @@ export const viewportMachine = setup({ camera: ({ event: { camera } }: { event: SetCameraEvent }) => camera, }), - 'resetCameraPose', 'forwardToSpawned', ], },