mcjCycleFilter2023

The 2011 version of mcjCycleFilter (  which was updated in 2020  ) is still here:

https://sites.google.com/site/mcasualsdazscripts/mcjcyclefilter

It's good enough for curve generation/filtering on individual node parameters.

Much of the 2012 Video-Tutorial for mcjCycleFilter applies to the 2023 version

https://www.youtube.com/watch?v=4rcAHyf0lxs&ab_channel=mcasual



Introduction

This script is most usefull to help Daz Studio animators create perfectly looping animations or fix BVH animations.

It lets you select a property or a morph channel on a figure and prop, visualize the animation, smoothen the curve using low-pass filtering. You can also synthesize the animation using one of the 20 included presets. 

This new version differs from the 2011/2020 version in that it allows you to apply the resulting animation curve on a different node/property. Example, transfer the animation curve of the left arm bend channel of Gabrielle (Aiko 3) 's  to  the left arm bend channel of Hanami  ( Genesis 3 ).

History


Installing

A Zip file containing the script can be found at the bottom of this page, in the "attachments" section

Unzip this file in your Daz Contents folder, typically this means C:\Users\USERNAME\Documents\DAZ 3D\My Library

Once installed you will find the script in your library, in My Library/scripts/mCasual

Use

If you want to only modify properties on 1 node, select that bone/figure/prop/light/camera in your scene

If you want to generate or copy an animation curve from one node to another node ex: the elbow from one figure to another figure's elbow, select those 2 nodes

the First node you select will be deemed the source node. 

the Second selected node will be the destination node

You can also send the generated animation curve to the source node by un-checkmarking the "Send Output Here" checkbox.


Above you can see i selected Hanami's LeftForeArmBend as the Source and Gabrielle's lForeArm as the destination

if i un-checkmarked  the "Send Output Here" checkbox,  Gab's lForeArm's animation curves would be left alone.

In the upper left corner you can see the range of values for each curve. In this case A7's  LeftForeArmBend is not animated, it stays at -45 degrees.

the maximum/ minimum values displayed ( -46, -44 )  are  chosen this way to allow a curve to be displayed when we enable the Synthesizer.

We will be generating A7's bend channel from scratch using the Synthesizer

I selected the "Synth" option in the "Source Selector" box ( lower-left corner )

then in the "Synth" section, i selected the "Sine" function

I uncheckmarked the "Send Output Here" checkbox, so the animation curve will be applied to A7' LeftForeArmBend's "Bend" channel, the source

in the synth section you can see that this would generate a sinewave ranging from -46 to -44

But we want a wider movement, so we change min to -45 and max to 0

The Red curve ( flat line ) is the current curve for that Bend channel

The Green curve ( sinewave ) is the projected synthesized curve

but we didnt apply it yet

We Click the Apply Button and Bam, the curve was applied to the whole playrange of A7's  LeftForeArmBend's "Bend" channel

Below you can see the red  curve is no longer a flat line it's perfectly hidden by the green curve, 

After applying the curve to A7's leftForeArm i checked the "Send Output Here" checkbox to make sureI didn't disturb Gab's lForeArm Bend channel

The Cyan curve is  the current curve for the destination (  Gab's lForeArm Bend) channel . It's still a flat line so we didn't modify it at all.

In a future version i'll add a display of the Destination channel minimum and maximum values, 

why? 

because i forgot if Aiko3's lForeArm -Bend goes from -130 to 0 or 0 to 130

Now we see that Gabrielle's lForeArm joint is similar to A7's joint:  the lower the angle the more bent

There's 2 ways to transfer the animation from A7 to Gabrielle.

If we leave the synth function enabled then  a new curve will  be sent to Gab's lForeArm Bend channel regardless of A7's curve

if we turn off the synth, by selecting the "Current Values" option in the "source selector" section and press apply A7's Bend animation will be copied 

The Phase Parameter of the synthesizer

In the above image you can see that Gabrielle's lForeArm Bend curve is not the same as A7's 

it's because i left the "Synth" option in effect and typed 45 in the "Phase"  field of the "synth" section.

The Daz Studio Play-Range was set to frames 0 to 99

The "input Range Frames" and the "Output Range Frames" settings ( lower-right corner ) were not modified by us, so they are still 0 to 99.

The input range is deemed to cover angles 0 to 360 degrees

By setting the "Phase" parameter to 45 degrees, we are shifting the synthesized curve by 1/8th of the wavelength

so Gabrielle's lForeArm will bend ( go negative ) before A7's foreArm bend.

When making walk animations, you can use a phase of 180 degrees to make the left thigh  do the same thing as the right thigh but half the loop duration later.

A bit confusing, but this will become clearer below.

Mirroring a Limb Animation

In the example, i selected  Gabbie's lForeArm followed by her rForeArm so lForeArm will be the Source and the rForeArm will be the Destination

we already animated the bend channel of Gabrielle's  lForeArm ( in red )

i turned on the synthesizer and left the Synth Function  at "Current",  so the synthesizer will re-use the current waveform of the lForeArm

i set the "Phase" parameter of the synth to 180 degrees, so the rForeArm will be out of phase with the lForeArm by half the loop duration

BUT AH HA the rForeArm is bends in the other direction

so we want it to swing between 0 and +45 degrees, not -45 to 0 degrees

so in the synth parameters, we set min to 0 and max to 45 right?

nope , see below

when the lForeArm rotation is at the bottom of the red curve, it's -45 

with our misguided settings, the rForeArm rotation, the green curve would be at 45 

so both forearms would be in-phase, bending at the same time

so we have 2 choices

set min to 45 and max to 0

or

set the Phase parameter of the synth to 0 degrees

So when we want rotations of opposite limbs to be out of phase, we use a phase of 0 degrees and when we want them in-phase we use 180 degrees

What is the auto-phase parameter of the synthesizer for?

This angle is computed by mcjCycleFilter.  It is the value of the Phase parameter you can use so that the synthesized curve or the filtered curve begins at the same value as the current input curve starts. So if your actor started the play-range with the arm bent -45 degrees, using the auto-phase angle as the Synth's phase angle would make the new synthesized curve start at -45 degrees.

Filtering your animation curves

Whether the source curve comes from the selected property of the selected input node or it's being synthesized, you can squelch the high frequencies from that curve.

To enable the Filter, checkmark the checkbox labeled "Filter"


A little theory

Any waveform/curve can be seen as a sum of sinewaves, those sinewaves are a series of pure sinewaves with harmonic frequencies, different amplitudes and phases.

For example any 30-samples curve can be represented by a sum of 15 sinewaves of frequencies 1, 1/2, 1/3, ..... 1/15


How mcjCycle does it

mcjCycleFilter uses a Discrete Fourier Transform to measure the amplitude and phase shift of all those sinewaves

In this example, if The Slider labeled  "Harmonic cutoff" is set to  15, then the filter will add all those sinewaves and the output curve will be the same as before

if you set the  "Harmonic cutoff" to 1, then only the 1st low-frequency  component will make it to the output curve.


Most of the time, i set  "Harmonic cutoff" at 3 or 4 and it removes shakes from shaky animations

Below you can see that the synthesizer used the "random" function to generate a maximally noisy animation curve

after applying a filter with a harmonic cutoff of 4, we get a random but smooth animation curve we can apply to Gabrielle's mouth-open morph.


Since the sinewaves frequencies have complete (360°)  cycles fitted in your playrange, the resulting animations Loop Perfectly ( the value at the beginning of the playrange will be precisely the value at the end of your playrange ). In fact that's the main reason why i wrote mcjCycleFilter in 2011. Because i was doing walk and dance animation loops. Still am :)

in red the current animation curve for Gabbie's OpenMouth morph

in green that 'random' function of the synthesizer swinging wildly between 0 and 1  (  morphs go from 0 to 1 not 0 to 100 )

in blue the  Filtered curve that will be replace the OpenMouth animation curve. The Filter is enabled and only kept the 4 first harmonics of the random curve.

as you can see there are 4-humps curve sinewave  riding on a slow 2-humps sinewave riding on a 1-hump sinewave, and the curves are perfectly looping.


What is "Phase of Formant[1]" ?

 Above the graph, you can see the maximum and minimum values for each one of the 4 curves and "Phase of Formant[i]"

This is the phase-angle in degrees of the first sinewave with a frequency of 1 Hertz ( 1 cycle per PlayRange ) contained in the input curve.

It may help you synchronize or delay the movements of limbs in a walk or dance animation task.

It's called mcj ***CYCLE*** filter no?

Yes it is

so far we only synthesized curves and left the "Cycle" value of the Synth parameters at 1,

so if we set cycles to 2 

with the source selector  at "Synth"

and the Synth function at "Current Values"

we can make Gabbie open  and close her mouth 8 times during the playrange instead of 4 

in red, our old animation curve for the OpenMouth morph with 4 humps

in green the  2-cycles version of the input curve

Note that looping a whole figure animation is best done using bLooper (<2009)  the oldest script i ever posted here i think

https://sites.google.com/site/mcasualsdazscripts/blooper-for-d-s2-and-d-s3

and while you're at it get my SceneGraf plugin  which lets you view and edit animation curves keyframe by keyframe

https://sites.google.com/site/mcasualsdazscripts2/mcjscenegrafds45


Input Range Frames and Output Range Frames

Maybe you should leave those alone until you have used mcjCycleFilter a few times

Say our playrange is frames 0 to  99

and you change Input Range Frames to start = 0 and end = 49

and you leave Output Range Frames at start = 0 and end = 99

then the current input  curve, from frames 0 to 49 will be stretched over frames 0 to 99

One source of confusion for me is that once you change the Input Range Frames to 0 to 49

mcjCycleFilter now displays the input curve in red from frames 0 to 49

and over it in green the synthesizer output  for frames 0 to 99

then once you hit the apply button, you  still see frames 0 to 49 but with the new values

SO, set input Range Frames back to 0 to 99

and you can see your stretched curve and can relax, everything went well.

What about those Alpha and Beta Synth parameters?

I often wanted to add S-Curves to mcjCycle filter, so in 2023 i finally did it

So i added 2 new Synth functions

smooth-step and smooth-loop

smooth step ramps up from the synth's min value  to the synth's max value

the steepness of the S -curve is controlled by the Alpha parameter, 1 means a straight line , as you increase Alpha, the curve bends, it starts slowly rising, then accelerates its ascension then slows down until it reaches the max value

smooth loop ramps up from the synth's min value to the max value then ramps down to the synth's min value

the Alpha parameter controls the steepness of the ascension and Beta controls the steepness of the descent

This type of animation curve has much more character than the sine/cosine or triangle functions, looks less robotic.

Yes, You Can Do Some Basic Curve Editing  with mcjCycleFilter

 when "Source Selector" is set to "Current Values

you can 

use your mouse's right button to add key-frames 

and 

use your mouse's left button to delete them. 

( this function and the display of the keyframes will be fixed in the old mcjCycleFilter soon )

for a better control of mouse-editing one should use my sceneGraf plugin

it's quite easy to install, you drop the sceneGraf file in your Daz Studio plugins/ folder 

and sceneGraf becomes one of the Tabs you can dock in your tab-dock

The Secret For matAnim users

if you used matAnim, you know you can make material properties animatable, the UV tiling sliders let you make many special effects

So one day i don't remember when I added the UV Tiling properties of the first surface of the selected node to the list of synthesizable properties

i didn't include a "make property animatable" button to avoid confusing people not-in-the-know about matAnim.

So, you simply select your target node and its first (and often only) surface and make its tiling properties animatable using matAnim


then you get all those nifty special effects like blinking lights and animated film strips. There's no Stair  Synthesizer function but one could apply a sawtooth waveform to the H Offset parameter with the Studio timeline set to 1 frame per second apply a Sawtooth going from 0 to 1 to the Horizontal Offset surface property,  exist mcjCycle Filter, go back into  30fps mode, then use matAnim to make all those spaced out keyframes use "Constant" interpolation. In my example i applied it to the X Scale of an nVidia shader but usually it's for the  Translate  and Offset properties. 

another note: the old mcjCycleFilter probably crashes when a shader with no property  named ....Tiles or ...Offset 

i was taking for granted that shaders were all derived from DzMaterial but apparently some are not.


mcjCycleFilter only handles the following tiling properties.

The future is not now but we can always dream

Things i may add in the future