Skip to content

Commit

Permalink
Add info_match_since() amd info_match_until()
Browse files Browse the repository at this point in the history
  • Loading branch information
rewbs committed Jul 20, 2023
1 parent 9c7ee03 commit 44ccd5f
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 4 deletions.
81 changes: 81 additions & 0 deletions src/FunctionDoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,23 @@ const FunctionDoc = () => {
]
}],
},
{
category: "Context variables",
name: "**final_frame**: the last frame",
examples: [{
keyframeOverrides: [
{ frame: 0, translation_z_i: 'final_frame', },
{ frame: 99, },
],
},
{
description: "Make something happen half-way through the animation, regardless of the length.",
keyframeOverrides: [
{ frame: 0, translation_z: 0, translation_z_i: 'if (f < final_frame/2) L else (L+sin(p=2b, a=20))', },
{ frame: 99, translation_z: 100 },
],
}],
},
{
category: "Context variables",
name: "**prev_computed_value**: Value computed at the previous frame.",
Expand Down Expand Up @@ -783,6 +800,70 @@ const FunctionDoc = () => {
}
]
},
{
category: "Info matching",
name: "**info_match_since()**: frames since previous match",
function_ref: functionLibrary.info_match_since,
examples: [
{
keyframeOverrides: [
{ frame: 0, info: "bassdrum 1", translation_z_i: 'info_match_since("bassdrum")' },
{ frame: 15, },
{ frame: 30, },
{ frame: 45, info: "bassdrum 2", },
{ frame: 60, info: "bassdrum 3", },
{ frame: 75, },
{ frame: 90, info: "bassdrum 4", },
{ frame: 99, },
]
},
{
description: "Hold a value for half a beat after every matching keyframe",
keyframeOverrides: [
{ frame: 0, info: "bassdrum 1", translation_z_i: 'if info_match_since("bassdrum")<0.5b 100 else 0 ' },
{ frame: 15, },
{ frame: 30, },
{ frame: 45, info: "bassdrum 2", },
{ frame: 60, info: "bassdrum 3", },
{ frame: 75, },
{ frame: 90, info: "bassdrum 4", },
{ frame: 99},
]
}
]
},
{
category: "Info matching",
name: "**info_match_until()**: frames until next match",
function_ref: functionLibrary.info_match_until,
examples: [
{
keyframeOverrides: [
{ frame: 0, info: "bassdrum 1", translation_z_i: 'info_match_until("bassdrum")' },
{ frame: 15, },
{ frame: 30, },
{ frame: 45, info: "bassdrum 2", },
{ frame: 60, info: "bassdrum 3", },
{ frame: 75, },
{ frame: 90, info: "bassdrum 4", },
{ frame: 99, },
]
},
{
description: "Hold a value for half a beat before every matching keyframe",
keyframeOverrides: [
{ frame: 0, info: "bassdrum 1", translation_z_i: 'if info_match_until("bassdrum", 10)<0.5b 100 else 0' },
{ frame: 15, },
{ frame: 30, },
{ frame: 45, info: "bassdrum 2", },
{ frame: 60, info: "bassdrum 3", },
{ frame: 75, },
{ frame: 90, info: "bassdrum 4", },
{ frame: 99},
]
}
]
},
{
category: "Beats and seconds",
name: "**Units**: ",
Expand Down
1 change: 1 addition & 0 deletions src/parseq-lang/parseq-lang-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ export class VariableReferenceAst extends ParseqAstNode {
return cubicSplineInterpolation(ctx.definedFrames, ctx.definedValues, ctx.frame);
case 'f':
return ctx.frame;
case 'final_frame':
case 'last_frame':
return _.maxBy(ctx.allKeyframes, 'frame')?.frame ?? 0;
case 'b':
Expand Down
34 changes: 30 additions & 4 deletions src/parseq-lang/parseq-lang-functions-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const functionLibrary: { [key: string]: ParseqFunction } = {
description: "Returns the frame number of the next keyframe that matched the regex, or -1 if none.",
argDefs: [
{ description: "regex", names: ["regex", "r"], type: "string", required: true, default: "" },
{ description: "default if no next match", names: ["default", "d"], type: "string", required: false, default: -1 }
{ description: "default if no next match", names: ["default", "d"], type: "number", required: false, default: -1 }
],
call: (ctx, args) => {
const pattern = String(args[0]);
Expand All @@ -71,7 +71,7 @@ const functionLibrary: { [key: string]: ParseqFunction } = {
description: "Returns the number of frames between the previous and next match (equivalent to `info_match_next()-info_match_prev()`), or `-1` if not between matches.",
argDefs: [
{ description: "regex", names: ["regex", "r"], type: "string", required: true, default: "" },
{ description: "default if not between matches", names: ["default", "d"], type: "string", required: false, default: -1 }
{ description: "default if not between matches", names: ["default", "d"], type: "number", required: false, default: -1 }
],
call: (ctx, args) => {
const pattern = String(args[0]);
Expand All @@ -85,15 +85,41 @@ const functionLibrary: { [key: string]: ParseqFunction } = {
description: "Returns a number between 0 and 1 reprenting how far the current frame is along the gap between (equivalent to `(f-info_match_prev()/info_match_gap())`, or `-1` if not between matches.",
argDefs: [
{ description: "regex", names: ["regex", "r"], type: "string", required: true, default: "" },
{ description: "default if not between matches", names: ["default", "d"], type: "string", required: false, default: -1 }
{ description: "default if not between matches", names: ["default", "d"], type: "number", required: false, default: -1 }
],
call: (ctx, args) => {
const pattern = String(args[0]);
const prevMatch = frameOfPrevMatch(ctx, pattern);
const nextMatch = frameOfNextMatch(ctx, pattern)
return (nextMatch && prevMatch) ? (ctx.frame - prevMatch.frame) / (nextMatch.frame - prevMatch.frame) : Number(args[1]);
}
}
},

"info_match_since": {
description: "Returns the number of frames since the previous keyframe that matched the regex, or an overridable fallback defaulting to `-1` if no next match. Equivalent to `f-info_match_prev()`.",
argDefs: [
{ description: "regex", names: ["regex", "r"], type: "string", required: true, default: "" },
{ description: "default if not between matches", names: ["default", "d"], type: "number", required: false, default: -1 }
],
call: (ctx, args) => {
const pattern = String(args[0]);
const prevMatch = frameOfPrevMatch(ctx, pattern);
return (prevMatch) ? (ctx.frame - prevMatch.frame) : Number(args[1]);
}
},

"info_match_until": {
description: "Returns the number of frames until the next keyframe that matches the regex, or an overridable fallback defaulting to `-1` if no next match. Equivalent to `info_match_next()-f`.",
argDefs: [
{ description: "regex", names: ["regex", "r"], type: "string", required: true, default: "" },
{ description: "default if not between matches", names: ["default", "d"], type: "number", required: false, default: -1 }
],
call: (ctx, args) => {
const pattern = String(args[0]);
const nextMatch = frameOfNextMatch(ctx, pattern)
return (nextMatch) ? (nextMatch.frame - ctx.frame) : Number(args[1]);
}
},

}

Expand Down

0 comments on commit 44ccd5f

Please sign in to comment.