Motion based animation like leaves or ornaments on a tree.

What type of scripts do you need?

Moderator: byronnash

Post Reply
esbowman
Posts: 10
Joined: February 25th, 2009, 1:34 pm

Hi guys. I'm pretty green on scripting and I'm reaching out to you for ideas/help.

In brief this is what I'm trying to create. Imagine leaves or ornaments on a tree that sway back and fourth based on the rotation of the tree trunk. I want to basically animate a null (the trunk of the tree) and when the rotation stops I want the pictures/video (leaves) to slowly resolve until they are static. Then when I rotate the tree (null) again, they should start to sway based on the rotation direction until I stop the rotation again. I feel this is going to require a lot more math than I'm capable of, and more expression knowledge than I have. For a better visual of what I'm trying to create, please see this youtube video. It's the menu interface of the game Zenbound, and the little tags hanging off the tree are really what I'm trying to create. (Only pay attention to the menu from 9seconds - 19 seconds in this video):

http://www.youtube.com/watch?v=CRVN0mfV7MA

All help and recommendations are greatly appreciated. I suppose I could animate this all by hand, but I have multiple spots I need to create, so creating a rig of some sort seems to make sense this time.

Thanks so much!
kobyg
Posts: 128
Joined: December 7th, 2007, 10:11 am

Try this expression:

Code: Select all

restLength = 200;
damp = .97;
leader = thisComp.layer("leader2");
g = 0.5;
ks = 2;

fDur = thisComp.frameDuration;
currFrame = Math.round(time / fDur);

p2 = position.valueAtTime(0);
v2 = 0;
for (f = 0; f <= currFrame; f++){
  t  = f*fDur;
  p1 = leader.position.valueAtTime(t);
  delta = p2 - p1;
  nDelta = normalize(delta);
  a = ks * nDelta * (length(delta) - restLength) * fDur - [0,g,0];
  v2 = (v2 - a) * damp;
  p2 += v2;
}
p2
This expression is based on Dan Ebberts's "Elastic Connection" expression from:
http://www.motionscript.com/design-guide/elastic.html
Where I added a gravity factor (g) to the expression.
"leader2" is a layer positioned where you want the "rope" to be attached to.

If you are using parenting in order to rotate the "tree",
put a solid/null layer at the desired loaction on the "tree" and parent it to the tree. name that solid "leader".
Then create another solid/null, name it "leader2" and give it the position expression:

Code: Select all

leader = thisComp.layer("leader");
leader.toWorld(leader.anchorPoint.valueAtTime(time))
Check out the attached project file, and play with the parameters of the expression.

Koby.

p.s.: this is not really a "rope" behaviour, it is actually a "spring" behavior.
But the behaviour is very similar to what you wanted.
To prevent oscilations at the beginning of the animation, place the object at distance equal to the "restLength" parameter in the above expression (that will prevent the spring from contracting).
If you are watching my projectfile, check the "distance" text layer, it calculates the distance between the "Card" layer and the "leader" layer.
Attachments
Spring Pendulum Expression.zip
(7.91 KiB) Downloaded 803 times
esbowman
Posts: 10
Joined: February 25th, 2009, 1:34 pm

this is genius. So close to perfect for what I need, and I greatly appreciate it.

I have a couple of questions:

1) what does the variable "ks" do exactly?

2) If I wanted the "Card" layer to not spin around on the y-axis so much, what would I do? I see that you have an expression for the orientation, and from my limited understanding, it looks like it is "looking at" the layer "leader" for it's orientation. I guess I just don't understand what part of the expression is controlling the speed of the rotation for this card layer.

Again, thanks so much for helping me with this and replying so quick.
kobyg
Posts: 128
Joined: December 7th, 2007, 10:11 am

1. ks is the "spring constant". larger value makes the spring "stronger", thus making smaller and faster oscilations of the spring.
2. yes, the orientation is set to look at the leader, and then rotated by 90 deg at the xRotation. You can change both of them as you desire. You can for instance try this expression for the orientation:

Code: Select all

leader = thisComp.layer("leader");
ang = lookAt(leader.toWorld(leader.anchorPoint), position);
[ang[0],ang[1]/2,ang[2]] 
That would make the angle smaller at the Y-orientation.
Giving a "real" physical expression to the orientation is much more complicated...

Koby.

p.s.: This was quite challenging, but I loved the idea and the challenge ! :-)
esbowman
Posts: 10
Joined: February 25th, 2009, 1:34 pm

Thanks for the quick reply, and explanations. That helps.

I tried your updated code for the orientation. The expression you added does not affect the Y-axis rotation like I expected. For some reason the third value is what is controlling the spin, and adding your expression controls what I assume is the z axis. I don't understand why, but it's like the 3D axis is altered from the "look at" portion of the expression.

So I think I'm going to do something like this.

Code: Select all

leader = thisComp.layer("leader");
ang = lookAt(leader.toWorld(leader.anchorPoint), position);
[ang[0],ang[1],effect("spin ctrl")("Slider")] 
I guess the only disadvantage is that I would need to manually animate the rotation for each card or ornament on the tree. Is there an easy way to have my slider control be an influence on the overall rotation. For example the spin is automated as you have in the expression, but depending on a value of 1-10 or 1-100 it would slow or speed up the rotation? I hope that makes sense.

This just might be one of those cases where I need to keyframe it manually, and I'm fine with that. This has me soo much closer to where I need to be.
kobyg
Posts: 128
Joined: December 7th, 2007, 10:11 am

You could try this:

Code: Select all

[ang[0],ang[1],ang[2]*effect("spin ctrl")("Slider")] 
so when "spin ctrl"=1 it would give you the full spin angle from my original expression,
and smaller "spin ctrl" values will decrease the angle, until "spin ctrl"=0 that would make it 0.
so with keyframing this "spin ctrl" you could decrease the angle as desired (or increase it with values bigger than 1).

Koby.
esbowman
Posts: 10
Joined: February 25th, 2009, 1:34 pm

NICE!

The only issue I have now is that the rotation pops for some reason right before it rests. I've attached my AEP file, and I'm using version CS3.

Can you take a look?

As always, I'm so grateful for the help you're providing.
Last edited by esbowman on October 18th, 2009, 12:40 pm, edited 1 time in total.
esbowman
Posts: 10
Joined: February 25th, 2009, 1:34 pm

sorry...it wouldn't take an aep file. zip is here now.
Attachments
Spring Pendulum Expression.aep.zip
(8.45 KiB) Downloaded 757 times
kobyg
Posts: 128
Joined: December 7th, 2007, 10:11 am

Yes, I see it now...
I forgot that the 3 values of the orientation are interconnected with each other, and there is the continuity point at 360, where it jumps back to 0, thus if you change only one value at that point you would mess the continuity of the orientation...
Bottom line is: You should not change only one of the orientation values... so don't use the multiplication expression I gave you before, just use the original expression, and use the yRotation instead in order to achieve your desired rotation (with keyframes).
Let me know if you managed to achieve the motion you want using the yRotation.

Koby.
Navstar
Posts: 68
Joined: February 16th, 2009, 12:41 pm

You know, this might be an example where Motion 4's behaviors might work better than a bunch of complex expressions.
kobyg
Posts: 128
Joined: December 7th, 2007, 10:11 am

what do you mean by "motion 4's" ... ?
Post Reply