Skip to content

Commit a88342b

Browse files
authored
Add the "Rate" multiplier parameter to the Animation Time node (#3685)
1 parent 568831b commit a88342b

4 files changed

Lines changed: 43 additions & 16 deletions

File tree

editor/src/messages/portfolio/document_migration.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,6 +1632,20 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
16321632
}
16331633
}
16341634

1635+
// Upgrade the "Animation" node to add the "Rate" input
1636+
if reference == DefinitionIdentifier::ProtoNode(graphene_std::animation::animation_time::IDENTIFIER) && inputs_count < 2 {
1637+
let mut node_template = resolve_document_node_type(&reference)?.default_node_template();
1638+
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
1639+
let _ = document.network_interface.replace_inputs(node_id, network_path, &mut node_template);
1640+
1641+
document
1642+
.network_interface
1643+
.set_input(&InputConnector::node(*node_id, 0), NodeInput::value(TaggedValue::None, false), network_path);
1644+
document
1645+
.network_interface
1646+
.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::F64(1.), false), network_path);
1647+
}
1648+
16351649
// Migrate from the old source/target "Morph" node to the new vector table based "Morph" node.
16361650
// This doesn't produce exactly equivalent results in cases involving input vector tables with multiple rows.
16371651
// The old version would zip the source and target table rows, interpoleating each pair together.

node-graph/nodes/gcore/src/animation.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,28 @@ fn real_time(
3030
component: RealTimeMode,
3131
) -> f64 {
3232
let real_time = ctx.try_real_time().unwrap_or_default();
33+
3334
// TODO: Implement proper conversion using and existing time implementation
3435
match component {
3536
RealTimeMode::Utc => real_time,
3637
RealTimeMode::Year => (real_time / DAY / 365.25).floor() + 1970., // TODO: Factor in a chosen timezone
3738
RealTimeMode::Hour => (real_time / 1000. / 3600.).floor() % 24., // TODO: Factor in a chosen timezone
3839
RealTimeMode::Minute => (real_time / 1000. / 60.).floor() % 60., // TODO: Factor in a chosen timezone
39-
4040
RealTimeMode::Second => (real_time / 1000.).floor() % 60.,
4141
RealTimeMode::Millisecond => real_time % 1000.,
4242
}
4343
}
4444

4545
/// Produces the time, in seconds on the timeline, since the beginning of animation playback.
4646
#[node_macro::node(category("Animation"))]
47-
fn animation_time(ctx: impl Ctx + ExtractAnimationTime) -> f64 {
48-
ctx.try_animation_time().unwrap_or_default()
47+
fn animation_time(
48+
ctx: impl Ctx + ExtractAnimationTime,
49+
_primary: (),
50+
#[default(1)]
51+
#[unit("/sec")]
52+
rate: f64,
53+
) -> f64 {
54+
ctx.try_animation_time().unwrap_or_default() * rate
4955
}
5056

5157
/// Produces the current position of the user's pointer within the document canvas.

node-graph/nodes/graphic/src/graphic.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use vector_types::GradientStops;
1313
/// This node associates the ID of the network's parent layer to every element of output data.
1414
/// This technical detail may be ignored by users, and will be phased out in the future.
1515
#[node_macro::node(category(""))]
16-
pub async fn source_node_id<I: 'n + Send + Clone>(
16+
pub async fn source_node_id<T: 'n + Send + Clone>(
1717
_: impl Ctx,
1818
#[implementations(
1919
Table<Artboard>,
@@ -24,9 +24,9 @@ pub async fn source_node_id<I: 'n + Send + Clone>(
2424
Table<Color>,
2525
Table<GradientStops>,
2626
)]
27-
content: Table<I>,
27+
content: Table<T>,
2828
node_path: Vec<NodeId>,
29-
) -> Table<I> {
29+
) -> Table<T> {
3030
// Get the penultimate element of the node path, or None if the path is too short
3131
// This is used to get the ID of the user-facing parent layer node (whose network contains this internal node).
3232
let source_node_id = node_path.get(node_path.len().wrapping_sub(2)).copied();
@@ -41,16 +41,16 @@ pub async fn source_node_id<I: 'n + Send + Clone>(
4141

4242
/// Joins two tables of the same type, extending the base table with the rows of the new table.
4343
#[node_macro::node(category("General"))]
44-
pub async fn extend<I: 'n + Send + Clone>(
44+
pub async fn extend<T: 'n + Send + Clone>(
4545
_: impl Ctx,
4646
/// The table whose rows will appear at the start of the extended table.
4747
#[implementations(Table<Artboard>, Table<Graphic>, Table<Vector>, Table<Raster<CPU>>, Table<Raster<GPU>>, Table<Color>, Table<GradientStops>)]
48-
base: Table<I>,
48+
base: Table<T>,
4949
/// The table whose rows will appear at the end of the extended table.
5050
#[expose]
5151
#[implementations(Table<Artboard>, Table<Graphic>, Table<Vector>, Table<Raster<CPU>>, Table<Raster<GPU>>, Table<Color>, Table<GradientStops>)]
52-
new: Table<I>,
53-
) -> Table<I> {
52+
new: Table<T>,
53+
) -> Table<T> {
5454
let mut base = base;
5555
base.extend(new);
5656

@@ -61,14 +61,14 @@ pub async fn extend<I: 'n + Send + Clone>(
6161
/// Performs an obsolete function as part of a migration from an older document format.
6262
/// Users are advised to delete this node and replace it with a new one.
6363
#[node_macro::node(category(""))]
64-
pub async fn legacy_layer_extend<I: 'n + Send + Clone>(
64+
pub async fn legacy_layer_extend<T: 'n + Send + Clone>(
6565
_: impl Ctx,
66-
#[implementations(Table<Artboard>, Table<Graphic>, Table<Vector>, Table<Raster<CPU>>, Table<Raster<GPU>>, Table<Color>, Table<GradientStops>)] base: Table<I>,
66+
#[implementations(Table<Artboard>, Table<Graphic>, Table<Vector>, Table<Raster<CPU>>, Table<Raster<GPU>>, Table<Color>, Table<GradientStops>)] base: Table<T>,
6767
#[expose]
6868
#[implementations(Table<Artboard>, Table<Graphic>, Table<Vector>, Table<Raster<CPU>>, Table<Raster<GPU>>, Table<Color>, Table<GradientStops>)]
69-
new: Table<I>,
69+
new: Table<T>,
7070
nested_node_path: Vec<NodeId>,
71-
) -> Table<I> {
71+
) -> Table<T> {
7272
// Get the penultimate element of the node path, or None if the path is too short
7373
// This is used to get the ID of the user-facing parent layer-style node (which encapsulates this internal node).
7474
let source_node_id = nested_node_path.get(nested_node_path.len().wrapping_sub(2)).copied();

node-graph/nodes/vector/src/vector_nodes.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,9 +1226,16 @@ async fn instance_map(ctx: impl Ctx + CloneVarArgs + ExtractAll, content: Table<
12261226
}
12271227

12281228
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
1229-
async fn flatten_path<I: 'n + Send>(_: impl Ctx, #[implementations(Table<Graphic>, Table<Vector>)] content: Table<I>) -> Table<Vector>
1229+
async fn flatten_path<T: 'n + Send>(
1230+
_: impl Ctx,
1231+
#[implementations(
1232+
Table<Graphic>,
1233+
Table<Vector>,
1234+
)]
1235+
content: Table<T>,
1236+
) -> Table<Vector>
12301237
where
1231-
Graphic: From<Table<I>>,
1238+
Graphic: From<Table<T>>,
12321239
{
12331240
// NOTE(AdamGerhant):
12341241
// A node-based solution to support passing through vector data could be a network node with a cache node

0 commit comments

Comments
 (0)