Skip to content
Snippets Groups Projects
Commit 1fa05d89 authored by Tobias Pietzsch's avatar Tobias Pietzsch
Browse files

animate transform when recalling bookmarks.

parent 823b20f0
No related branches found
No related tags found
No related merge requests found
......@@ -14,12 +14,21 @@ import javax.swing.KeyStroke;
import net.imglib2.realtransform.AffineTransform3D;
import bdv.viewer.InputActionBindings;
import bdv.viewer.ViewerPanel;
import bdv.viewer.animate.RigidTransformAnimator;
public class BookmarkEditor
{
private boolean active = false;
static enum Mode
{
INACTIVE,
SET,
RECALL_TRANSFORM,
RECALL_ORIENTATION
}
private Mode mode = Mode.INACTIVE;
private boolean setBookmark = false;
private volatile boolean initialKey = false;
private final ViewerPanel viewer;
......@@ -61,25 +70,49 @@ public class BookmarkEditor
@Override
public void keyTyped( final KeyEvent e )
{
if ( active && e.getKeyChar() != 'b' && e.getKeyChar() != 'B' )
if ( mode != Mode.INACTIVE )
{
final String key = String.valueOf( e.getKeyChar() );
if ( setBookmark )
{
final AffineTransform3D t = new AffineTransform3D();
viewer.getState().getViewerTransform( t );
bookmarks.put( key, t );
animator.fadeOut( "set bookmark: " + key, 500 );
viewer.requestRepaint();
}
if ( initialKey )
initialKey = false;
else
{
final AffineTransform3D t = bookmarks.get( key );
if ( t != null )
viewer.setCurrentViewerTransform( t );
animator.fadeOut( "go to bookmark: " + key, 500 );
final String key = String.valueOf( e.getKeyChar() );
switch ( mode )
{
case SET:
{
final AffineTransform3D t = new AffineTransform3D();
viewer.getState().getViewerTransform( t );
final double cX = viewer.getDisplay().getWidth() / 2.0;
final double cY = viewer.getDisplay().getHeight() / 2.0;
t.set( t.get( 0, 3 ) - cX, 0, 3 );
t.set( t.get( 1, 3 ) - cY, 1, 3 );
bookmarks.put( key, t );
animator.fadeOut( "set bookmark: " + key, 500 );
viewer.requestRepaint();
}
break;
case RECALL_TRANSFORM:
{
final AffineTransform3D t = bookmarks.get( key );
if ( t != null )
{
final AffineTransform3D c = new AffineTransform3D();
viewer.getState().getViewerTransform( c );
final double cX = viewer.getDisplay().getWidth() / 2.0;
final double cY = viewer.getDisplay().getHeight() / 2.0;
c.set( c.get( 0, 3 ) - cX, 0, 3 );
c.set( c.get( 1, 3 ) - cY, 1, 3 );
viewer.setTransformAnimator( new RigidTransformAnimator( c, t, cX, cY, 300 ) );
}
animator.fadeOut( "go to bookmark: " + key, 500 );
}
break;
default:
break;
}
done();
}
done();
}
}
} );
......@@ -89,14 +122,13 @@ public class BookmarkEditor
{
if ( animator != null )
animator.clear();
if ( active )
done();
done();
}
public synchronized void initSetBookmark()
{
active = true;
setBookmark = true;
initialKey = true;
mode = Mode.SET;
bindings.addInputMap( "bookmarks", inputMap, "bdv", "navigation" );
if ( animator != null )
animator.clear();
......@@ -107,8 +139,8 @@ public class BookmarkEditor
public synchronized void initGoToBookmark()
{
active = true;
setBookmark = false;
initialKey = true;
mode = Mode.RECALL_TRANSFORM;
bindings.addInputMap( "bookmarks", inputMap, "bdv", "navigation" );
if ( animator != null )
animator.clear();
......@@ -119,7 +151,8 @@ public class BookmarkEditor
public synchronized void done()
{
active = false;
mode = Mode.INACTIVE;
initialKey = false;
bindings.removeInputMap( "bookmarks" );
}
}
......@@ -536,6 +536,13 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis
transformChanged( transform );
}
public synchronized void setTransformAnimator( final AbstractTransformAnimator animator )
{
currentAnimator = animator;
currentAnimator.setTime( System.currentTimeMillis() );
requestRepaint();
}
/**
* Switch to next interpolation mode. (Currently, there are two
* interpolation modes: nearest-neighbor and N-linear.
......
package bdv.viewer.animate;
import net.imglib2.realtransform.AffineTransform3D;
import net.imglib2.util.LinAlgHelpers;
import bdv.util.Affine3DHelpers;
public class RigidTransformAnimator extends AbstractTransformAnimator
{
private final double[] qStart;
private final double[] qDiff;
private final double[] tStart;
private final double[] tDiff;
private final double scaleStart;
private final double scaleDiff;
private final double cX;
private final double cY;
public RigidTransformAnimator( final AffineTransform3D transformStart, final AffineTransform3D transformEnd, final double cX, final double cY, final long duration )
{
super( duration );
this.cX = cX;
this.cY = cY;
qStart = new double[ 4 ];
Affine3DHelpers.extractRotation( transformStart, qStart );
qDiff = new double[ 4 ];
final double[] qEnd = new double[ 4 ];
final double[] qTmp = new double[ 4 ];
Affine3DHelpers.extractRotation( transformEnd, qEnd );
LinAlgHelpers.quaternionInvert( qStart, qTmp );
LinAlgHelpers.quaternionMultiply( qTmp, qEnd, qDiff );
scaleStart = Affine3DHelpers.extractScale( transformStart, 0 );
final double scaleEnd = Affine3DHelpers.extractScale( transformEnd, 0 );
scaleDiff = scaleEnd - scaleStart;
tStart = new double[ 3 ];
for ( int d = 0; d < 3; ++d )
tStart[ d ] = transformStart.get( d, 3 ) / scaleStart;
tDiff = new double[ 3 ];
for ( int d = 0; d < 3; ++d )
tDiff[ d ] = transformEnd.get( d, 3 ) / scaleEnd - tStart[ d ];
}
@Override
protected AffineTransform3D get( final double t )
{
final double[] qDiffCurrent = new double[ 4 ];
final double[] qCurrent = new double[ 4 ];
LinAlgHelpers.quaternionPower( qDiff, t, qDiffCurrent );
LinAlgHelpers.quaternionMultiply( qStart, qDiffCurrent, qCurrent );
final double[][] m = new double[ 3 ][ 4 ];
LinAlgHelpers.quaternionToR( qCurrent, m );
final double scale = scaleStart + t * scaleDiff;
for ( int r = 0; r < 3; ++r )
{
m[ r ][ 3 ] = tStart[ r ] + t * tDiff[ r ];
for ( int c = 0; c < 4; ++c )
m[ r ][ c ] *= scale;
}
m[ 0 ][ 3 ] += cX;
m[ 1 ][ 3 ] += cY;
final AffineTransform3D transform = new AffineTransform3D();
transform.set( m );
return transform;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment