Creative COW SIGN IN :: SPONSORS :: ADVERTISING :: ABOUT US :: CONTACT US :: FAQ
Creative COW's LinkedIn GroupCreative COW's Facebook PageCreative COW on TwitterCreative COW's Google+ PageCreative COW on YouTube
ADOBE AFTER EFFECTS:HomeForumBasicsExpressionsTutorialsPodcastsAE TechniquesCreative Cloud DebateFAQ

Expression to make a boat "ride" on top of generated waves?

COW Forums : Adobe After Effects Expressions

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Share on Facebook
Max PalmerExpression to make a boat "ride" on top of generated waves?
by on May 10, 2012 at 8:50:52 pm

So what I want to do is pretty simple. I have an animation of a man rowing a boat, and under neath I have a plain solid rectangle with some wiggle expressions on a wave warp effect, which create a nice random wave effect.

Is there an expression I can use to make it so that the boat bobs up and down a little bit in sync with the waves?

Thanks.



Return to posts index
Reply   Like  

Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 10, 2012 at 10:39:05 pm

If the waves are consistent then you can just set 2 keyframesat the top and bottom then set the following expression:

(might have to play with ease settings on keyframes)

loopOut(type = "pingpong")

Dan Fredley


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 10, 2012 at 11:02:20 pm

Unfortunately, it's not. The animation is seeded so that it has a natural random feeling.


Return to posts index
Reply   Like  


Dan EbbertsRe: Expression to make a boat "ride" on top of generated waves?
by on May 10, 2012 at 11:10:51 pm

It might be possible to calculate the wave height at any point and time. What are your wave warp settings and expressions? What's the layer number of the wave layer?

Dan



Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 10, 2012 at 11:40:52 pm

Dan- first off, love your site. I've used the examples several times, and it was actually my first go-to place when trying to figure this particular problem out. Thanks!

Here is a screenshot of my wave setup. I made a small expression with a wiggle, part of which is pickwhipped to a null with some keyframes on it. The reason I did this is so that I could increase the waves later in the animation (a storm will happen).



Return to posts index
Reply   Like  

Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 12:46:42 am

change the sampleLayer to your water layer and then try applying the following to the boat position.

L = thisLayer;
targetPosition = L.toWorld(L.anchorPoint);
sampleLayer = thisComp.layer(thisComp.numLayers);
for (i=0; i<thisComp.height;i++) {
alphaCheck = sampleLayer.sampleImage(sampleLayer.fromWorld([targetPosition[0],i]), radius = [.5,.5]);
if (alphaCheck[3]&lt;1) {
continue;
} else {
alphaPosition = [0,i];
break;
}
}
newWorldPos = L.fromWorld(L.toWorld(alphaPosition));
[value[0],newWorldPos[1]]


Dan Fredley


Return to posts index
Reply   Like  


Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 12:49:57 am

actually try this--expression got screwed up somehow during copy/paste

L = thisLayer;
targetPosition = L.toWorld(L.anchorPoint);
sampleLayer = thisComp.layer(thisComp.numLayers);
for (i=0; i<thisComp.height;i++) {
alphaCheck = sampleLayer.sampleImage(sampleLayer.fromWorld([targetPosition[0],i]), radius = [.5,.5]);
if (alphaCheck[3]<1) {
continue;
} else {
alphaPosition = [0,i];
break;
}
}
newWorldPos = L.fromWorld(L.toWorld(alphaPosition));
[value[0],newWorldPos[1]]



L = thisLayer;
targetPosition = L.toWorld(L.anchorPoint);
sampleLayer = thisComp.layer(thisComp.numLayers);
for (i=0; i<thisComp.height;i++) {
alphaCheck = sampleLayer.sampleImage(sampleLayer.fromWorld([targetPosition[0],i]), radius = [.5,.5]);
if (alphaCheck[3]<1) {
continue;
} else {
alphaPosition = [0,i];
break;
}
}
newWorldPos = L.fromWorld(L.toWorld(alphaPosition));
[value[0],newWorldPos[1]]


Dan Fredley


Return to posts index
Reply   Like  


Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 12:58:14 am

Let's try this one more time:

L = thisLayer;
targetPosition = L.toWorld(L.anchorPoint);
sampleLayer = thisComp.layer(thisComp.numLayers);
for (i=0; i < thisComp.height;i++) {
alphaCheck = sampleLayer.sampleImage(sampleLayer.fromWorld([targetPosition[0],i]), radius = [.5,.5]);
if (alphaCheck[3] < 1) {
continue;
} else {
alphaPosition = [0,i];
break;
}
}
newWorldPos = L.fromWorld(L.toWorld(alphaPosition));
[value[0],newWorldPos[1]]


Dan Fredley


Return to posts index
Reply   Like  
+1

Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 1:13:56 am

just noticed you have a shape layer. You'll need to precomp the shape layer with the slider or use a solid instead

Dan Fredley


Return to posts index
Reply   Like  


Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 1:00:01 pm

That works! Amazing. Thank you SO much. My last thing I need to do is find a way to make the boat rotate slightly as it bobs, so in other words, when it bobs up the boat rocks back, and when it bobs back down, it rocks forward. Is that easy to do?


Return to posts index
Reply   Like  

Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 1:35:08 pm

I wrote a better expression in case the boat layer reaches the edge of the composition. I suggest precomping the boat and water layer in a 2x wide comp to animate the boat across a full comp otherwise the expression won't work past the edge of the main comp. I hope that makes sense:

Final position expression:

target = thisComp.layer("Controller").effect("Boat")("Layer");
targetWorldPos = target.toWorld(target.anchorPoint);

sample = thisComp.layer("Controller").effect("Ocean")("Layer");

for (i = 0; i < height; i++){
if (sample.sampleImage([clamp(targetWorldPos[0],0,thisComp.width), i], [0.5, 0.5], true)[3] > 0){
top = [0,i];
break;
} else {
top = [0,thisComp.height];
}
}

newWorldPos = target.fromWorld(target.toWorld(top));
[value[0],newWorldPos[1]]


To be able to rock the boat:

Final rotation expression:

target = thisComp.layer("Controller").effect("Boat")("Layer");
targetWorldPos = target.toWorld(target.anchorPoint);

sample = thisComp.layer("Controller").effect("Ocean")("Layer");
offset = -10;

for (i = 0; i < height; i++){
if (sample.sampleImage([clamp(targetWorldPos[0]+offset,0,thisComp.width), i], [0.5, 0.5], true)[3] > 0){
top = [0,i];
break;
} else {
top = [0,thisComp.height];
}
}

newWorldPos = target.fromWorld(target.toWorld(top));
offsetPos = [target.position[0]+offset,newWorldPos[1]];

for (i = 0; i < height; i++){
if (sample.sampleImage([clamp(targetWorldPos[0],0,thisComp.width), i], [0.5, 0.5], true)[3] > 0){
top = [0,i];
break;
} else {
top = [0,thisComp.height];
}
}

targetWorldPos = target.fromWorld(target.toWorld(top));
boatPos = [target.position[0],targetWorldPos[1]];

radians = Math.atan2(boatPos[1] - offsetPos[1],boatPos[0] - offsetPos[0]);
radiansToDegrees(radians);


This is going to be really slow to calculate. You should bake all of these expressions. Then after you bake the rotation put this expression on it otherwise it will be really choppy:

Final baked rotation expression:

smooth(.5,10)

Dan Fredley


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 1:38:26 pm

Actually the expression you gave me earlier works exactly the way I want. He will only be moving about halfway across the screen. Now, I just have to add the rotation expression.

Thank you for writing this for me- I'd like to learn expressions better, but the syntax is hard for me to swallow, and I have no experience with anything similiar, such as javascript.

How do I go about baking an expression? (if it's too hard to explain, I'll just google it.) Is that the same as pre-rendering a comp?

Again, thank you!


Return to posts index
Reply   Like  


Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 1:41:07 pm

To bake expressions:

Select the property you would like to bake and go up to Animation>Keyframe Assistant>Convert Expression to Keyframes.

Dan Fredley


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 1:51:52 pm

Very cool. Thanks again!


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 2:00:27 pm

Ah, one sec. The rotation expression you wrote is for if I were to pre-comp the boat and waves, which I'm not doing. I can't figure out how to take that expression and make it apply to the boat layer that I already have the position expression working on.

Is this rotation expression meant to be applied directly to the boat layer's rotation property? Or is it meant to be applied to the wave layer, and thus targets the boat layer instead?


Return to posts index
Reply   Like  


Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 2:05:18 pm

Apply the rotation expression to the boat rotation. You'll have to change the "target" variable by pickwhipping the boat layer and the "sample" variable by pickwhipping the ocean layer.

Dan Fredley


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 3:43:20 pm

Did that, but now it says "target.toWorld" is undefined. I've been combing through the script, and messing with this a bit, and I can't figure it out.


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 3:49:01 pm

This is how I have it. All I did was change the target, and sample variables.

target = transform.rotation; targetWorldPos = target.toWorld(target.anchorPoint); sample = thisComp.layer("Waves"); offset = -10; for (i = 0; i &lt; height; i++){ if (sample.sampleImage([clamp(targetWorldPos[0]+offset,0,thisComp.width), i], [0.5, 0.5], true)[3] > 0){ top = [0,i]; break; } else { top = [0,thisComp.height]; } } newWorldPos = target.fromWorld(target.toWorld(top)); offsetPos = [target.position[0]+offset,newWorldPos[1]]; for (i = 0; i &lt; height; i++){ if (sample.sampleImage([clamp(targetWorldPos[0],0,thisComp.width), i], [0.5, 0.5], true)[3] > 0){ top = [0,i]; break; } else { top = [0,thisComp.height]; } } targetWorldPos = target.fromWorld(target.toWorld(top)); boatPos = [target.position[0],targetWorldPos[1]]; radians = Math.atan2(boatPos[1] - offsetPos[1],boatPos[0] - offsetPos[0]); radiansToDegrees(radians);


Return to posts index
Reply   Like  


Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 3:53:10 pm

The target variable is wrong--you should place the whole expression on the boat rotation not assign the variable "target" to the rotation.

It should read something like this according to your layer name:

target = thisComp.layer("Boat");

You can also just write:

target = thisLayer;

By the way, the offset is for going right to left. If the boat is going from left to right it might be better to change it to 10 instead of -10.

Dan Fredley



Return to posts index
Reply   Like  

Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 4:05:21 pm

Here's my AE CS5.5 rendition for reference:

BoatWaveWarp

Dan Fredley


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 4:22:15 pm

Ah, unfortunately they haven't bumped us up to CS5.5 or CS6 here.

So all the errors have gone away, but the boat's rotation property doesn't seem to be effected in any way. I've been scouring through this, rearranging variables and things to see if I can get it to work, but I can't make sense of it enough to figure it out.

target = thisLayer;
targetWorldPos = target.toWorld(target.anchorPoint);
sample = thisComp.layer("Waves");
offset = -10;

for (i = 0; i &lt; height; i++){ if (sample.sampleImage([clamp(targetWorldPos[0]+offset,0,thisComp.width), i], [0.5, 0.5], true)[3] > 0){ top = [0,i]; break; }
else { top = [0,thisComp.height]; } }

newWorldPos = target.fromWorld(target.toWorld(top));
offsetPos = [target.position[0]+offset,newWorldPos[1]];

for (i = 0; i &lt; height; i++){ if (sample.sampleImage([clamp(targetWorldPos[0],0,thisComp.width), i], [0.5, 0.5], true)[3] > 0){ top = [0,i]; break; }
else { top = [0,thisComp.height]; } }

targetWorldPos = target.fromWorld(target.toWorld(top));
boatPos = [target.position[0],targetWorldPos[1]];
radians = Math.atan2(boatPos[1] - offsetPos[1],boatPos[0] - offsetPos[0]); radiansToDegrees(radians);


Return to posts index
Reply   Like  


Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 4:25:24 pm

Upload your project and I'll take a look.

Dan Fredley


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 4:37:19 pm

Actually before I do that, what I just noticed is that the rotation actually works once the animation gets to a point where the waves move higher on the screen. I'll play with this a bit more, now that I know that.


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 5:28:36 pm

This is frustrating the heck out of me. I want to remove the comp height/width check from the code above, but I'm not sure which variables to remove or change. I keep running into errors.


Return to posts index
Reply   Like  


Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 11, 2012 at 6:25:07 pm

Alright- I give up. Here's my file, without all the dependencies.

4125_max.aep.zip

As you can see, the rotation effect doesn't start working until the height of the wave comp's alpha reaches around 180px.


Return to posts index
Reply   Like  

Dan FredleyRe: Expression to make a boat "ride" on top of generated waves?
by on May 13, 2012 at 9:49:54 am

It looks like you switched to using the turbulent displacement effect instead of the wave warp effect. After making a few tweaks to the expression it seems that the TD effect is too choppy and it wreaks havoc on the rotation as the expression uses visible pixels to determine the angle of the wave at the position of the boat.

So, unfortunately I would recommend just animating the rotation by hand. It's not a long animation so adding some rocking back and forth in sync with the waves wouldn't be that difficult. I could come up with this convoluted way of using the wave warp to calculate the rotation for the first part then switch to calculating rotation from the TD layer, but it's probably easier to just do by hand.

The expression works a lot better on wave warp which typically has "smoother" waves making it easier for the expression to calculate a smooth angle transition from frame to frame. Hope that makes sense.

Dan Fredley


Return to posts index
Reply   Like  

Max PalmerRe: Expression to make a boat "ride" on top of generated waves?
by on May 14, 2012 at 12:57:23 pm

Totally makes sense. I had completely forgotten I switched the wave effect, but not that I would have figured out the issue anyway.

Thanks for the suggestion, and all the help!


Return to posts index
Reply   Like  

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
Share on Facebook


FORUMSTUTORIALSFEATURESVIDEOSPODCASTSEVENTSSERVICESNEWSLETTERNEWSBLOGS

Creative COW LinkedIn Group Creative COW Facebook Page Creative COW on Twitter
© 2014 CreativeCOW.net All rights are reserved. - Privacy Policy

[Top]