Skip to content

Conversation

@dsehnal
Copy link
Member

@dsehnal dsehnal commented Aug 9, 2025

Description

  • Hash-based StateTransform.version
  • More robust animation loop that prevents animation skips during shader compilation
  • Add Hsl color space
  • Support StateAnimation in PluginState
    • Data model
    • Animation loop
    • Autoplay
    • UI
  • MVS Animation node (controls duration, camera behavior, autoplay, ...)
  • MVS Transition node
  • MVS Animation logic
    • Interpolate scalar
    • Interpolate vector
    • Interpolate rotation
    • Interpolate transform matrix
    • Interpolate color
    • Easing functions
  • MVS Changes
    • Add transform.rotation_center param
    • Make canvas.background_color optional parameter
  • MVS Stories example

Python MVS PR: molstar/mol-view-spec#89

1CBS_state-snapshots.4.mp4

Actions

  • Added description of changes to the [Unreleased] section of CHANGELOG.md
  • Updated headers of modified files
  • Added my name to package.json's contributors
  • (Optional but encouraged) Improved documentation in docs

@dsehnal dsehnal mentioned this pull request Aug 10, 2025
4 tasks
@dsehnal dsehnal requested review from corredD and midlik August 10, 2025 14:17
@dsehnal dsehnal mentioned this pull request Aug 8, 2025
68 tasks
@dsehnal dsehnal marked this pull request as ready for review August 10, 2025 15:10
@dsehnal dsehnal requested a review from arose August 10, 2025 15:11
@zachcp
Copy link
Contributor

zachcp commented Aug 11, 2025

This looks amazing!

@dsehnal
Copy link
Member Author

dsehnal commented Aug 12, 2025

@corredD I had to rename from/to to start/end because from is a reserved keyword in Python.

@corredD
Copy link
Collaborator

corredD commented Aug 12, 2025

the kind: 'transform_matrix' is really great, can I use it to do a spin animation with multiple turn ?

@dsehnal
Copy link
Member Author

dsehnal commented Aug 12, 2025

the kind: 'transform_matrix' is really great, can I use it to do a spin animation with multiple turn ?

@corredD I've added frequency and alternate_direction params to support this (see the update code/video)

@corredD
Copy link
Collaborator

corredD commented Aug 12, 2025

the kind: 'transform_matrix' is really great, can I use it to do a spin animation with multiple turn ?

@corredD I've added frequency and alternate_direction params to support this (see the update code/video)

this is excellent! Can you show me how to use it for a full turn rotation ? I am sorry I can't figure out how to do it. I couldn't make 0 to 2pi to be interpolated. If I trick with 2pi - 0.1 it will interpolate on the shortest path.

@dsehnal
Copy link
Member Author

dsehnal commented Aug 12, 2025

@corredD its not possible to do the 4 rotations... the quaternion interpolation will always do the shortest path.

Seems like we need the ability to interpolate axis/angle combo as well. Will have a look tomorrow. Getting more and more complicated :)

@corredD
Copy link
Collaborator

corredD commented Aug 12, 2025

@dsehnal I found a solution that worked for me, I attached the patch file
patchrotation.patch

@dsehnal
Copy link
Member Author

dsehnal commented Aug 13, 2025

@corredD Thanks, I've included the changes to work for both rotation_ and transform_matrix and added some caching.

Copy link
Collaborator

@midlik midlik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is super cool.

It's a big chunk of changes. The part that i was able to understand, looks good.
See a few comments.

Comment on lines +51 to +52
// Uncomment this to make 2nd frame render much faster
// It will cause shader compilation to happen during the 1st snapshot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By chance, is there any way of detecting which shaders will be needed during the whole animation and pre-compiling them, so the users don't need to use hacks like this?

I understand this might be too much to want, just bringing up the idea.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this with Alex. In theory it might be possible to compile them ahead of time.


const Vec3Interpolation = {
..._Common,
start: OptionalField(nullable(list(float)), null, 'Start value. If unset, parent state value is used. Must be array of length 3N.'),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a type Vector3, you can use it instead of list(float)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This supports flat lists of vectors, so you can pass 6 numbers to it for example.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then pls don't call it Vec3Interpolation.

If we can interpolate custom-length vectors, that means we can interpolate mesh shapes, which will look cool :)
(not sure about a use-case though)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still vec3 interpolation, it can just interpolate multiple vectors at the same time.

..._Common,
start: OptionalField(nullable(list(float)), null, 'Start value. If unset, parent state value is used. Must be array of length 3N.'),
end: OptionalField(nullable(list(float)), null, 'End value. Must be array of length 3N. If unset, only noise is applied.'),
spherical: OptionalField(bool, false, 'Whether to use spherical interpolation.'),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do i understand correctly that spherical interpolation mean interpolation via the surface of a sphere rather than via a straight line?
What is the use-case for this?
Is it sufficient to have the center of the sphere always [0,0,0], or does the use-case require parametrization for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// if there is a blocking operation, e.g., shader compilation
// The drawback of this is that sometimes the animation will take
// longer than intended, but hopefully that's a reasonable tradeoff
private properTimeT: number = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fair enough in the UI. Freezing seems better then freezing+skipping.
But when i export animation, the timing will be exact, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is just for the UI-driven animations.

const interpolateHcl2 = Hcl.zero();

/** Linear interpolation between two colors in HCL space */
export function interpolateHcl(c1: Color, c2: Color, t: number): Color {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this used anywhere, so i guess it's more for the future.
I'm wondering if interpolation in HCL is superior to RGB.

Anyway, this implementation is wrong, as hue is a cyclical property. See ugly case below (#ff8800-#ff0088):

Screenshot 2025-08-13 at 13 47 04

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, i'm very sceptical about HCL in general.
It tries to tell me that all colors in the first row are the same hue. The same for the second row.
And also that colors in each column have the same CL and only differ in H.

Screenshot 2025-08-13 at 13 40 09

(first rows = hcl(270, 100, 0-100), second row = hcl(300, 100, 0-100))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add HSL implementation as well then? Perhaps that could be better?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added HSL.

@midlik
Copy link
Collaborator

midlik commented Aug 13, 2025

I'm wondering: how does easing work in combination with alternate_direction? E.g. does quad-in become quad-out on the way back?

@midlik
Copy link
Collaborator

midlik commented Aug 13, 2025

I'm wondering: how does easing work in combination with alternate_direction? E.g. does quad-in become quad-out on the way back?

Is easing actually implemented? I cannot find the code.

@dsehnal
Copy link
Member Author

dsehnal commented Aug 13, 2025

I'm wondering: how does easing work in combination with alternate_direction? E.g. does quad-in become quad-out on the way back?

It reverses the time. It's t = ...0.98, 0.99, 1, 0.99, 0.98..., so it will be symmetric version of the "normal direction"

Is easing actually implemented? I cannot find the code.

There was existing port of D3 easing the codebase before.

@dsehnal
Copy link
Member Author

dsehnal commented Aug 13, 2025

Gonna merge this now and do fixes in a separate PR if needed.

@dsehnal dsehnal merged commit f165cc4 into master Aug 13, 2025
1 check passed
@dsehnal dsehnal deleted the mvs/animations-v1 branch August 13, 2025 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants