Page 1 of 1

Layers Rotate Into View As Camera Approaches.

Posted: November 18th, 2007, 9:54 am
by Atomic
Hi All,

I am trying to make an expression to achieve a certain effect.

Imagine a comp 720x480, a solid 3D layer 160x600 and a camera.

I move the anchor point of the solid to the bottom of the solid. Now I can rotate the X axis and make it lay flat from the bottom.

I want to put a bunch of these little solds in my comp and have them automatically rotate from flat to 90 degrees straight up as I move the camera through a 3D comp. So the solids are distributed in z-space. I also want them to stay up for a certain amount of thime as the camera passes through, then rotate back down as if the camera has pushed them down as it moved through it.

The entire rotation sequence, if thought of as key frames might be like this. While camera is far, x rotate -90. As camera approaches, rotate up to 0. Hold zero for a short/adjustable amount of time, then as camera passes the layer's z-position, rotate back down to 90.

This is kind of like a popup book. With the popups happening as the camera approaches.

My first thought as to adapt the y-orient expression on Dan's site. So I have this code that is linked to two slider controls..

Code: Select all

delta = toWorld(anchorPoint) - (thisComp.activeCamera.toWorld((thisComp.layer("Camera 1").position)*thisComp.layer("Adjustment Layer 1").effect("Distance")("Slider")));
radiansToDegrees(Math.atan2(delta[1],delta[2]))-thisComp.layer("Adjustment Layer 1").effect("Offset")("Slider")
It kind of works, but not when I start disrtibuting my solids in z-space.

I'm wondering if anyone has made this effect before, or knows how I could adapt the expression?

Thanks

Posted: November 18th, 2007, 1:45 pm
by Dan Ebberts
I think it's going to be trickier than it seems. You can't just base it on distance. You might be able to do it with a combination of distance from the camera and whether it's in front of or behind the camera. But if you wait until it's behind the camera, the camera won't see the layer rotate back to horizontal. Does that matter?

Dan

Posted: November 18th, 2007, 2:50 pm
by Atomic
Dan,

No it does not matter.

I got this idea from watching some footage I made with my camcorder.

It was the end of summer and there is green grass and dead leaves on the lawn. I put my camcorder in the grass and drove it around the lawn like a kid would do with a tonka truck. This produced a neat effect. The leaves would be laying flat, and as the camera approached, they would lift up and remain in front of the camera for a few moments till they were dragged back under as the camera moves on.

I want to do that with footage layers.

I guess my question now would be:

How can I get the distance the camera is from a layer?

I think from there, I could craft something. As the camera get's within a certain range, I could begin rotation, call this the approach range. As the camera closes into a new range I could implement the hold. As I leave the hold range and begin exiting via the approach range, I would rotate in the opposite direction. If the camera is outside the approach range then the rotation would simply be 90 degrees. So I think I could get by with a 3 state switch.

Posted: November 18th, 2007, 4:04 pm
by Dan Ebberts
Something like this might work:

Code: Select all

beginApproach = 250;
beginHold = 200;
endHold = 150;
endApproach = 100;

C = thisComp.activeCamera;
d = length(C.toWorld([0,0,0]),toWorld(anchorPoint));
r = Math.min(ease(d,beginHold,beginApproach,90,0),ease(d,endApproach,endHold,0,90));
value + r;

But this calculation is entirely based on distance from the camera. If what you want is to trigger a rotation at a certain distance, it's a lot more complicated. Basically you have to figure out how long it's been since the triggering event, which means looping back in time frame-by-frame to figure out which state you're in and how long you've been there.

Dan

Posted: November 19th, 2007, 11:23 am
by Atomic
This kind of works, but there is no hold.

Code: Select all

startRot = 500; // Start rotate 500 pixels from camera.
endRot = 1500;  // End rotate 1500 pixels from camera.
C = thisComp.activeCamera.toWorld([0,0,0]);
P = toWorld(anchorPoint);
d = length(C,P);
linear(d,startRot,endRot,180,0)