FORUMS: list search recent posts

# Auto secondary movement (inertia/overshoot) in children layers

FAQ   •   VIEW ALL
 Auto secondary movement (inertia/overshoot) in children layers on Feb 22, 2016 at 11:09:11 am

Hi. I've been searching for this for a while without any results, so I've decided to try my luck here - I always end up on cow anyway, when I'm researching AE :P

I have a character to animate, that has a lot of dangling accessories on the head and body. My question is, is it possible to have those show inertia (basically sort of a rotation overshoot animation) using an expression, when the parent layer moves?

The (obvious) idea is to not have to do those manually, so I can work on my main animation more easily. Any input is welcome. Thanks.

 Re: Auto secondary movement (inertia/overshoot) in children layerson Feb 24, 2016 at 10:07:30 pm

i think i got something here:
i did it only considering lateral movement, so you wouldnt see any inertial rotation for y axis movements.
but it works well with dangling things...
here is the code:

```//inertial children n = 0; amp = .04; freq = 2.0; decay = 3.0; ppos=thisLayer.parent.transform.position; parv=clamp(ppos.velocity[0]/10,-90,90) if (ppos.numKeys > 0){ n = ppos.nearestKey(time).index; if (ppos.key(n).time > time){ n--; } } if (n == 0){ ppos.velocity[0] t = 100; }else{ t = time - ppos.key(n).time; } if (n > 0){ v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10)*-1; parv + v[0]*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t); }else{ parv } ```

 Re: Auto secondary movement (inertia/overshoot) in children layerson Feb 26, 2016 at 2:25:20 pm

WOW man, this works great. I'm just getting into expressions and I'm constantly amazed of what they can achieve. Also, there's some serious math going on in there that I would've never figured out by myself.

But I did manage to add some randomness so all dangly things don't move at once and in the same measure, and that makes it look even better and really brings the character to life in no time (which is a rasta character with hanging jewelry and dreadlocks btw) and cuts down a LOT on secondary animation time, which is now pretty much automatic, thanks to you :D

Later I'll hook up the randomness and other variables to sliders and that'll make my work even easier throughout the process.

Thank you for your tremendous help!

 Re: Auto secondary movement (inertia/overshoot) in children layerson Feb 26, 2016 at 2:45:37 pm

forgot to say: you can adjust the parameteres to make small differences:
amp = this is how much of an overshoot will happen (higher = stronger)
freq= frequency of the swings ( higher = quicker swings)
and decay = how long before they come to a stop (higher = stops faster)

by tweaking those three you should be able to add enough variance.. also i made a slight tweak:
here is the revised one. let me know if it works well

```//inertial children n = 0; amp = .04; freq = 2.0; decay = 3.0; ppos=thisLayer.parent.transform.position; parv=clamp(ppos.velocity[0]*amp,-90,90) if (ppos.numKeys > 0){ n = ppos.nearestKey(time).index; if (ppos.key(n).time > time){ n--; } } if (n == 0){ ppos.velocity[0] t = 100; }else{ t = time - ppos.key(n).time; } if (n > 0){ v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10)*-1; parv + v[0]*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t); }else{ parv }```

 Re: Auto secondary movement (inertia/overshoot) in children layerson Feb 26, 2016 at 2:54:00 pm

Ps: the "serious math" wasn't figured out by myself too :)
I took the famous Inertia bounce expression ( I think it was made by Dan Ebberts, orinally)
and just modified to suit your needs :)

 Re: Auto secondary movement (inertia/overshoot) in children layerson Feb 28, 2016 at 11:24:04 am

I have come across the original inertia bounce script myself, but I didn't know how to access the parent's keyframe data, didn't even know if it's possible. The variables are pretty self-explanatory, I got that part.

I still haven't had enough time to work on this properly, but I added a little something to the code to delay the reaction of some of the parts by a few frames (20 in my example), to sort of simulate their weight. I don't know however if this is the right way to go about it, or maybe there is a better way?

`v = ppos.velocityAtTime((ppos.key(n).time - thisComp.frameDuration*20) - thisComp.frameDuration/10)*-1;`

 Re: Auto secondary movement (inertia/overshoot) in children layerson Feb 28, 2016 at 11:32:46 am

changing the "v" variable might give you wrong/weird results..

try changing the "parv" variable instead to below: ( although 20 is a bit overkill)

although in my opinion the best way to simulate wheight is the freq variable. heavier items should just have lower values.

i haven't tested this tweak, se let me know if it works :)

`parv=clamp(ppos.velocityAtTime(time- thisComp.frameDuration*20)[0]*amp,-90,90)`

 Re: Auto secondary movement (inertia/overshoot) in children layerson Mar 8, 2016 at 10:26:11 am

Hey.
I've been neglecting this project because I didn't have any time, but now I'm back on it :)

You're right, the existing variables are more than enough for what I need, so I'm pretty much gonna keep the code as you wrote it, it works great. I only lowered the clamp values so the children don't reach a horizontal state ~45-60 degrees is plenty.

Thanks again for your help, I learned a lot and I ended up using bits and pieces for other things too, like a few positions and scales.

 Re: Auto secondary movement (inertia/overshoot) in children layerson Mar 8, 2016 at 10:44:38 am

yeah man, keep experimenting! that's how i lost my fear of expressions :).

an unnecessary idea: you could use the parent's "y" velocity and use it as a modifier, after the main expression gets calculated, you add/remove a bit of rotation depending on the vertical speed (positive or negative). i have something on my mind already but it would be a cool exercise to fry your brain a little and learn more =)

if you do actually decide do to it, and have any problems, ill be here to help.

All the best!

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 25, 2016 at 10:59:08 pm

Ack... Several hours spent trying to figure this out so far, but it's time to ask: How do I make this work!?

I've been applying this expression to the position field, with an error message popping up saying "expression result must be of dimension 2, not 1."

You said something about this code being more for "x" motion, such as for dangling objects, so I tried separating the x,y dimensions of the parent and child objects involved, but I'm not getting any kind of desirable results. There's not error messages, but the child layer isn't bouncing at all. It's just nudging the landing position of the layer.

Anyway, I'm moderately used to using basic expressions, but I'm feeling really dumb for not being able to figure this out. Can you explain exactly where I should be trying to apply this expression for it to work properly?

Do you have any ideas for a more general/universal "parental inertial bounce" expression that can be used directly on the "position"?

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 25, 2016 at 11:33:07 pm

hi Jake,
the message error that you are getting is because the expression outputs a rotation value (one number ) while the position takes two values (x and y)
the expression takes velocity and makes into rotation, so it has to go into the "rotation" property, and causes a inertial rotation, not a "bounce"
what kind of movement are you trying to add to the child layers?

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 25, 2016 at 11:43:33 pm

if all you want is postional oveshoot ( like the original bounce), you can try this:
i haven't got AE open at the moment, so if it does not work let me know.

```//inertial children bounce n = 0; amp = .04; freq = 2.0; decay = 3.0; ppos=thisLayer.parent.transform.position; if (ppos.numKeys > 0){ n = ppos.nearestKey(time).index; if (ppos.key(n).time > time){ n--; } } if (n == 0){ ppos.velocity[0] t = 100; }else{ t = time - ppos.key(n).time; } if (n > 0){ v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10)*-1; value + v[0]*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t); }else{ value }```

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 1:48:31 pm

Just as a side note, I modified this line:

`v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10)*-1;`

to...

`v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10)*1;`

By changing the -1 at the end to a positive value, that got things closer to what I needed. It seems with a negative value, the velocity curve (and bounce response) is more like its falling at a constant speed and bouncing off of a hard surface like a rubber ball when it reaches the end position--at least, on the first bounce. With a positive value, it seems to let the children follow through past the end position, dissipating their "inertia" on the other side of the axis, like they are buoyant objects that fell into water, or like the children are tethered to the parent via loose springs on an imaginary Z axis.

```if (n > 0){ v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10)*1; value + v[0]*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t); }else{ value }```

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 1:53:02 pm

well spotted. i think this *-1 was still left over from the other expression, and unnecessary for yours. more so, you dont even need to multiply it by 1, as this does absolutely nothing =DDD

below you'll find those lines revised.

```if (n > 0){ v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10); value + v[0]*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t); }else{ value }```

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 2:41:51 pm

Fair enough. I will probably leave it in anyway so that it is easier for me to remember what value to change if I DO want a collision type bounce.

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 2:44:48 pm

Oh crap. So, this works great on the x axis, but it doesn't do anything on the y axis. I don't understand the code well enough to understand why. Any ideas on getting this code to work in both (or even 3) axis simultaneously?

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 2:56:05 pm

try this:

```//inertial children bounce n = 0; amp = .04; freq = 2.0; decay = 3.0; ppos=thisLayer.parent.transform.position; if (ppos.numKeys > 0){ n = ppos.nearestKey(time).index; if (ppos.key(n).time > time){ n--; } } if (n == 0){ ppos.velocity t = 100; }else{ t = time - ppos.key(n).time; } if (n > 0){ v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10)*-1; value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t); }else{ value }```

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 2:57:40 pm

sorry, i forgot aobut the -1

here is the correct version:

```//inertial children bounce n = 0; amp = .04; freq = 2.0; decay = 3.0; ppos=thisLayer.parent.transform.position; if (ppos.numKeys > 0){ n = ppos.nearestKey(time).index; if (ppos.key(n).time > time){ n--; } } if (n == 0){ ppos.velocity t = 100; }else{ t = time - ppos.key(n).time; } if (n > 0){ v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10); value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t); }else{ value }```

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 3:11:11 pm

Like a boss! Thank you! This has been really helpful in learning how to reference other layers' properties properly. I was actually able to figure out how to make it work on an older version of the classic "bounce" expression BEFORE someone added in the amp variable,

```freq = 3; decay = 5; ppos=thisLayer.parent.transform.position; n = 0; if (ppos.numKeys > 0){ n = ppos.nearestKey(time).index; if (ppos.key(n).time > time) n--; } if (n > 0){ t = time - ppos.key(n).time; amp = ppos.velocityAtTime(ppos.key(n).time - .001); w = freq*Math.PI*2; value + amp*(Math.sin(t*w)/Math.exp(decay*t)/w); }else value```

...but I couldn't figure out how to make it work on the version of the expression that I had WITH the amp variable. Thanks for letting me pick your brain a bit!

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 27, 2016 at 11:06:42 am

These are great and I too have been looking for something like this for ages, thanks!!!

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 2:02:57 am

RE:Rotation

Ah, that's what I was afraid of. I'm looking for a way to attach a lot of objects to a null, or other parent object, and I want them to have inertial bounce based on the movement of the null. Kind of the same idea add what you have here, but instead of rotational manifestation, I just need good old fashioned directional inertial bounce, for lots of objects all tied to one parent.

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 7:08:15 am

this last expression that posted should do it! just drop it on the "position"

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 26, 2016 at 1:01:49 pm

Yes, indeed it did! Looking over the code, I can sort of see what I was doing wrong with my attempts. I understand the flow and logic of it, I just don't understand the correct "grammar" of AE Java when it goes beyond just referencing the layer where the code originated--and I stumble my way through that anyhow. Thank you!

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 27, 2016 at 11:22:01 am

anyways, just for the sake of people that end up on this thread in the future, i've collated the most revised versions below, so that people can use the right ones without having to re-read the whole thread.

(these are 2 different expressions, use the one that suits your needs)

```//inertial children bounce (apply on "position") n = 0; amp = .04; freq = 2.0; decay = 3.0; ppos=thisLayer.parent.transform.position; if (ppos.numKeys > 0){ n = ppos.nearestKey(time).index; if (ppos.key(n).time > time){ n--; } } if (n == 0){ ppos.velocity t = 100; }else{ t = time - ppos.key(n).time; } if (n > 0){ v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10); value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t); }else{ value } //inertial children rotation (apply on "rotation", for dagling things like earrings, dreadlocks, pendants etc) n = 0; amp = .04; freq = 2.0; decay = 3.0; ppos=thisLayer.parent.transform.position; parv=clamp(ppos.velocity[0]*amp,-90,90) if (ppos.numKeys > 0){ n = ppos.nearestKey(time).index; if (ppos.key(n).time > time){ n--; } } if (n == 0){ ppos.velocity[0] t = 100; }else{ t = time - ppos.key(n).time; } if (n > 0){ v = ppos.velocityAtTime(ppos.key(n).time - thisComp.frameDuration/10)*-1; parv + v[0]*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t); }else{ parv } ```

 Re: Auto secondary movement (inertia/overshoot) in children layerson Apr 27, 2016 at 3:13:15 pm

Thanks again, having a play with this :)

Two things i'd like to try if i can get my head around it and/or if even possible:
* modifying to make it operate in world space to make chains of dangling things :)
* making it so that it doesn't clamp at 90°, ie so that the thing can spin right round and dangle up if the object is descending... don;t actually know if that makes any sense vs how the expression works tho.

Will post any edited versions i manage to do anything interesting with, tho maybe you or someone else might have an easy answer to the above? :)