Open tpietzsch opened 8 months ago
During manual transformation, the incrementalTransform of the fixed sources is update whenever the viewer transform changes: It is set to the inverse of the incremental viewer transform wrt when the manual transform was started.
This is what happens here, right?
Allow me to ask the obvious question: why was this not implemented such that, during manual transform editing mode, the keys that would normally change the viewer transform now change the transforms for the moving sources?
For example, during transform editing mode, remove the actionMap that would change the viewer transform and replace it with an actionMap that would change the moving sources?
Or.... I guess TransformEventHandler3D
is where the viewer transform is modified upon keyboard actions, is it? Would it be an option to add a method setTargetTransform( AffineTransform3D )
to TransformEventHandler3D
where on would temporarily put the incremental transform of the sources to be modified during the manual transform editing, and then once done, one puts back the viewer transform?
So something like:
TransformEventHandler3D.setTargetTransform( incrementalTransform )
TransformEventHandler3D.setTargetTransform( viewerTransform )
Allow me to ask the obvious question: why was this not implemented such that, during manual transform editing mode, the keys that would normally change the viewer transform now change the transforms for the moving sources?
Hmm, because that seemed least intrusive. There is no complexity added to the "normal" BDV transform + rendering flow(which is already complicated enough). Now it looks like it's time to add something, after all, but at least I tried :-)
Regarding your suggestion with the TransformEventHandler3D
: Maybe something like that would be good. However, there are a few things to consider: There is also TransformEventHandler2D
. In general this is user-configurable. You can specify a custom TransformEventHandlerFactory
with ViewerOptions
or BdvOptions
. So the TransformEventHandler
interface would need to be changed. And there should be default
implementations for the new methods, so that user implementations don't break. But yes, this may be the best way to do it.
During manual transformation, the fixed sources visibly wobble when the transforming sources are moved somewhat fast.
Explanation
The reason for this lies in how manual transformation mode is implemented:
Actually, it is kind of a visual fake.
TransformedSource
has anincrementalTransform
and afixedTransform
. Both are concatenated to the transform of the underlyingSource
.During manual transformation, the
incrementalTransform
of the fixed sources is update whenever the viewer transform changes: It is set to the inverse of the incremental viewer transform wrt when the manual transform was started. This leads to the fixed sources appearing as if they are not moving, but actually they are moving wrt the global coordinate frame. The transforming sources are fixed wrt to the global coordinate frame, but appear to be moving (with the viewer transform).When the manual transform is ended, everything is baked into the fixedTransform of the moving sources, the incremental transforms are set to identity, and the viewer transform is reset to what it was at the start of the manual transform.
Now, this reversal of incremental viewer transform into the incremental transforms follows the viewer transform, which is moving faster than the rendering can catch up. Basically, every frame is rendered with a snapshot of the viewer transform at the start of the frame. Some time into the rendering, the actual viewer transform may have already moved on. Therefore, the incrementalTransform of the fixed sources may not match the viewer transform snapshot used for rendering.
Possible solutions:
1.) Tell the TransformedSource the viewer transform snapshot during painting, so that it can invert it right there. This must be done carefully, because
incrementalTransform
maybe used by others for other purposes (I think by BigStitcher, for example?). So probably: allow to setfrozenTransform
. If that is null,incrementalTransform
is used. Otherwise, the on-the-spot inversion is done.2.) Add another type of
transformListener
to ViewerPanel. Currently there aretransformListeners
andrenderTransformListeners
. We could addpreRenderTransformListeners
. I like this better.3.) Actually, I fear that both above solutions will fall short when the
TransformedSource
is shown in multiple viewers at the same time. For example to implement orthogonal views with multipleViewerPanel
s. The current way of faking fixed vs moving sources will probably wreak absolute havoc there. So the best solution is probably to completely revise how that works. But how?