Skip to content

Commit bac9e5a

Browse files
committed
Rec Viewer: implement rotations on arbitrary axes (issue #233)...
... while at it implement 'ping-pong' tilt animations and fix the dreaded and pole-crossing snap Add RotationAxis and AnimationMode enum (Z/X/Y) / (FULL_ROTATION/PING_PONG) Animations use Rodrigues' rotation formula to trace great-circle paths without changing the view's upVector, avoiding orientation jumps when animation stops. New features: - Auto-detect best rotation axis from current viewpoint (heuristic picks the axis most aligned with the camera viewing direction) - Ping-pong mode: oscillating back-and-forth animation over a configurable arc, w/ toggle in the Utilities menu - Shift+double-click forces legacy Z-axis rotation; plain double-click uses auto-detection - "Record Animation..." dialos shows axis choices and reflects the current animation mode (full rotation vs ping-pong) Bug fixes: - setViewMode("side") no longer silently blocks animations by locking jzy3d into PROFILE mode. Constrained view modes are automatically released - Pole-crossing fix in AView: camera smoothly wraps across elevation poles (±90°) instead of snapping to a mirrored viewpoint, by tracking pole flips and negating the up vector on odd crossings as discussed in jzy3d/jzy3d-api#214
1 parent c3abaf4 commit bac9e5a

2 files changed

Lines changed: 523 additions & 27 deletions

File tree

‎src/main/java/sc/fiji/snt/gui/cmds/RecViewerPrefsCmd.java‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public class RecViewerPrefsCmd extends ContextCommand {
5454
public static double DEF_ROTATION_DURATION = 12;
5555
/** Default frames per second for 3D viewer animations */
5656
public static int DEF_ROTATION_FPS = 30;
57+
/** Default animation mode for 3D viewer rotations */
58+
public static String DEF_ANIMATION_MODE = "Full Rotation";
5759
/** Default sensitivity setting for 3D viewer controls */
5860
public static String DEF_CONTROLS_SENSITIVITY = "High";
5961
/** Default file extension for scripts */
@@ -73,7 +75,13 @@ public class RecViewerPrefsCmd extends ContextCommand {
7375
visibility = ItemVisibility.MESSAGE)
7476
private String SUB_HEADER1;
7577

78+
@Parameter(label = "Animation mode", required = false, persist = true,
79+
description = "Full Rotation: continuous 360° sweep. Ping-pong: oscillates back and forth over the specified arc",
80+
choices = { "Full Rotation", "Ping-pong" })
81+
private String animationMode;
82+
7683
@Parameter(required = false, persist = true, label = "Rotation degrees",
84+
description = "Full Rotation: total sweep angle. Ping-pong: oscillation arc (camera rocks ±half this angle)",
7785
style = NumberWidget.SCROLL_BAR_STYLE, stepSize = "10", min = "30",
7886
max = "360d")
7987
private double rotationAngle;
@@ -138,6 +146,7 @@ public class RecViewerPrefsCmd extends ContextCommand {
138146
private void init() {
139147
if (snapshotDir == null) snapshotDir = new File(DEF_SNAPSHOT_DIR);
140148
snapshotDirChanged();
149+
if (animationMode == null) animationMode = DEF_ANIMATION_MODE;
141150
if (rotationAngle == 0) rotationAngle = DEF_ROTATION_ANGLE;
142151
if (rotationDuration == 0) rotationDuration = DEF_ROTATION_DURATION;
143152
if (rotationFPS == 0) rotationFPS = DEF_ROTATION_FPS;
@@ -148,6 +157,7 @@ private void init() {
148157

149158
private void defaults() {
150159
snapshotDir = null;
160+
animationMode = null;
151161
rotationAngle = 0;
152162
rotationDuration = 0;
153163
rotationFPS = 0;

0 commit comments

Comments
 (0)