Edit page History How do I edit this website?

3D Animation Script

3D Animation Script

   
Summary: Scripted 3D animations for the ClearVolume 3D viewer plugin
Author: Nico Stuurman
License: BSD
Platforms: All platforms supported by Micro-Manager
Requires: ClearVolume plugin; optionally ffmpeg for MP4 export

Overview

The 3D Animation Script dialog, accessible from the ClearVolume 3D viewer, lets you write scripts that drive the viewer through a series of camera movements, zoom changes, clipping adjustments, and channel property changes across a defined number of frames. Animations can be previewed interactively, exported as an ImageJ stack, or encoded as an MP4 movie using ffmpeg.

The scripting language follows the one described in:

Wan et al. (2019) “The 3Dscript animation language.” Nature Methods 16, 1179–1180.

Further documentation for the script language is available on the 3Dscript website and the 3Dscript wiki.

Opening the

In the ClearVolume Insepctor panel, click the Script… button

Dialog Controls

Control Description
Animation script Text editor for the animation script. Supports monospaced editing with tab indentation.
Save… / Load… Save the current script to a .cvs file, or load one from disk. The last used directory is remembered between sessions.
Frames per second Playback and capture rate (1–120 fps).
Total frames Total number of frames to render.
Export to Preview — play the animation live in the viewer without capturing. ImageJ stack — collect each frame into an ImageJ window. Movie (ffmpeg) — encode the frames as an MP4 file via ffmpeg.
Restore viewer state after animation When checked, the viewer is returned to exactly the state it was in before the animation started (rotation, zoom, clipping, channel properties). Useful when using Preview mode to test a script.
Output file (.mp4) File path for the MP4 output (visible only when Movie (ffmpeg) is selected).
Run / Stop Start or abort the animation.
Help Opens this page.

Script Language

Time intervals

Every instruction must be associated with a time interval. Two forms are supported:

From frame 1 to frame 120:
- action one
- action two

At frame 60:
- action three

A line ending with : acts as a header shared by all immediately following lines that start with -. A line without : combines the interval and a single action on the same line.

Frame numbers are zero-based. The Total frames spinner in the dialog sets how many frames are rendered in total.

Comments

Lines starting with # are ignored:

# This is a comment

Actions

All keywords are case-insensitive.

Rotation

rotate by <degrees> degrees horizontally
rotate by <degrees> degrees vertically
rotate by <degrees> degrees around <ax> <ay> <az>

Rotates the camera incrementally over the interval. The total rotation across the full interval is <degrees>. For example, to spin the volume one full turn over 120 frames:

From frame 1 to frame 120:
- rotate by 360 degrees horizontally

Translation

translate horizontally by <amount>
translate vertically by <amount>
translate <dx> <dy> <dz>

Zoom

zoom by a factor of <factor>

Positive values zoom in; negative values zoom out. The value is accumulated as a delta each frame, so a factor of 1 moves the camera by 1 unit per frame over the interval.

Clipping / bounding box

change front clipping to <value>
change back clipping to <value>
change front/back clipping to <value>
change bounding box min x to <value>
change bounding box max x to <value>
change bounding box x to <min> <max>

Also supported for axes y and z. Values are in the range −1 to 1.

Channel intensity

Channels are numbered from 1 (matching the Micro-Manager UI).

change channel <c> min intensity to <value>
change channel <c> max intensity to <value>
change channel <c> intensity gamma to <value>
change channel <c> intensity to <min> <max> <gamma>

Intensity values are normalised in the range 0–1.

Channel color

change channel <c> color to <r> <g> <b>

Color components are in the range 0–255.

Channel weight

change channel <c> weight to <value>

Interpolates a weight value (0–1). Because ClearVolume controls channel visibility as a boolean, values above 0.5 show the channel and values at or below 0.5 hide it.

Channel visibility

change channel <c> visibility to on
change channel <c> visibility to off

Also accepts true/false and show/hide in place of on/off.

Time point

change time to <n>
change time from <a> to <n>

Moves to time point <n> (1-based, matching the Micro-Manager UI). This action is intended for time-lapse datasets and lets you animate through the T axis of a multi-time-point acquisition.

In a From frame A to frame B block the time point is linearly interpolated and rounded to the nearest integer each frame, so it steps discretely through the dataset. Easing keywords apply and control the stepping rate (e.g. ease-in-out dwells longer at the beginning and end of the sweep).

With the to <n> form, interpolation starts from the time point currently displayed in the viewer when the animation begins. With the from <a> to <n> form, interpolation always starts at <a> regardless of the viewer state.

In an At frame N block the time point jumps immediately to <n>.

Example — sweep through 10 time points while rotating the volume:

From frame 1 to frame 120:
- rotate by 360 degrees horizontally
- change time from 1 to 10

If Restore viewer state after animation is checked, the viewer returns to the time point it was showing before the animation started.

A script function can also supply the time point dynamically. For example, to hold each time point for 12 frames before stepping to the next:

From frame 1 to frame 120:
- change time to timeFn

script
function timeFn(t) {
    // Steps through time points 1–10, holding each for 12 frames.
    return floor((t - 1) / 12) + 1;
}

Easing

Any action line may end with an easing keyword that controls the speed curve of the interpolation:

Keyword Behaviour
(none) Linear (constant speed)
ease Smooth S-curve (less dramatic than ease-in-out)
ease-in Starts slow, then accelerates
ease-out Starts fast, then decelerates
ease-in-out Slow start and slow end

Example:

From frame 1 to frame 120:
- rotate by 360 degrees horizontally ease-in-out

Script functions

An optional script block at the end of the script text may define JavaScript functions. Any numeric parameter in an action line can be replaced by the function’s name; the function is called with the current 1-based frame number as its argument and its return value is used as the parameter for that frame.

Available math shims (matching ImageJ macro syntax): sin, cos, tan, asin, acos, atan, atan2, sqrt, exp, log, abs, floor, ceil, round, pow, min, max, PI, E.

From frame 1 to frame 120:
- rotate by 360 degrees horizontally ease-in-out
- zoom by a factor of zoomFn

script
function zoomFn(t) {
    // Returns a per-frame zoom delta.
    // Absolute position = 0.1 + 2.9 * sin(PI * (t-1) / 119)
    // ranges from 0.1 at t=1, peaks at 3.0 near t=60, returns to 0.1 at t=120.
    // The delta is the derivative of that curve.
    var pos  = 0.1 + 2.9 * sin(PI * (t - 1) / 119);
    var prev = 0.1 + 2.9 * sin(PI * (t - 2) / 119);
    return pos - prev;
}

In the example above the zoom follows a smooth arc from 0.1× up to 3.0× and back while the volume rotates. Note that when a script function is supplied, the easing keyword has no effect on that parameter — the function controls the value directly. Because zoom by a factor of accumulates a delta each frame, zoomFn returns the difference between the desired absolute position at frame t and at frame t − 1.

Complete Example

# Rotate 360° while pulsing zoom (0.1x → 3.0x → 0.1x) and gradually
# revealing the volume by opening the front clip.

From frame 1 to frame 120:
- rotate by 360 degrees horizontally ease-in-out
- zoom by a factor of zoomFn

From frame 1 to frame 60:
- change front clipping to -0.5

From frame 61 to frame 120:
- change channel 1 max intensity to 0.9 ease-out

At frame 60:
- change channel 2 visibility to on

script
function zoomFn(t) {
    // Smooth arc: 0.1 at t=1, peaks at 3.0 near t=60, returns to 0.1 at t=120.
    var pos  = 0.1 + 2.9 * sin(PI * (t - 1) / 119);
    var prev = 0.1 + 2.9 * sin(PI * (t - 2) / 119);
    return pos - prev;
}

Exporting with ffmpeg

Select Movie (ffmpeg) from the Export to drop-down, specify an output .mp4 file path, and click Run. The plugin renders each frame using the OpenGL renderer, writes lossless PNG frames to a temporary directory, then invokes ffmpeg with the H.264 codec (libx264, yuv420p, medium preset) and cleans up the temporary files automatically.

ffmpeg must be installed and locatable on your system. On the first export the plugin will prompt you to locate the ffmpeg binary if it cannot find it automatically.