This scene required generating the movement of thousands of objects in a very specific way, the basic idea was to build the gazebo out of small parts falling from the sky. Since animating all off these objects by hand was clearly not the best and most flexible idea, we decided to do a python script that would handle the motion of each piece based on the final desired position. The final motion script can be seen here
The basic Math
My approach consists of two simple and predictable algorithms,
one that controls the fall (Z axis) and one that controls the translation (X and Y axis) of the object. For the Z movement I've used the free fall formula that we all learned in school: (Wikipedía and Google are great tools for people with bad memory/math skills like me)
z = (- 0.5 * Gravity * Time ** 2) + (Initial_Velocity * Time) +
You can see the relevant function in line 87 of the script. So using a free fall formula gave me nice, believable Z Loc values to start with; now for the translation part a simple 2D linear extrapolation formula was used, it works like this:
First find out the range between a and b with a subtraction
Now divide the range in some large value, lets say 100
This gives us 100 equally spaced steps between positions a and b. For example if we want to find out the middle position we do
And offsetting the value of a
The same can be done for any other value between 0 - 100:
(b - a) / 100 * 85 + a = 8.8
The cool thing about this is that we can use values greater than 100 to get extrapolation, lets say using a value of 175:
(b - a) / 100 * 175 + a = 16
In the script I'm using this to get the X Loc and Y Loc values of each object out of their final desired position (b) and the center of the gazebo (a) which I get from an empty object that I can even animate with oscillating movements to get interesting effects, chek lines 68 and 78 for final implementation.
Python comes with a module called 'random' which is great for easily adding variation to the results of each run of the formulas, its actually not really random but pseudo random, which means it takes a given seed number that you can specify and it'll generate many numbers out of that, and if you later give it the same seed and asque for the same thing, it will generate the exact same numbers. This characteristic is great because it allows us to keep things fully predictable as I mentioned before. If you go bak to the Loc and Rot functions you will see how random generated numbers are used to give variation to the results. Line 39 shows how to set a different random seed for each object that will stay the same in time, avoiding jittering in the object's movement.
Maquíng it fit
Prior to running the main script, I've saved all object's rest positions into good old Game-Engine properties using this one time use script
. It alos sabes a starting time offset value for each object. The example I'm sharing here was used for the roof; it sets the start time according to a distance from center formula as you can see in line 38 and that's why the roof's tiles start falling into position from the outer part to the center. I'm alos using a little bit of random generators here. So this script uses lots of random numbers and different formulas and we still need to control the final or rest position of every object so that the whole bunch correctly builds the gazebo; this is when the predictable formulas and pseudo-random generators save the day. The trik is to predict were the object is gonna be at the end of the movement and to offset the entire motion accordingly so that when it actually reaches the rest position you have it right were you wanted it. In lines 96-98 and 113-115 I'm calling the location and rotation formulas but I'm feeding them the time value of 100 which marks the end of the movement (like seeing into the future!) Then in lines 130-135 I simply subtract this value to the results of the real time formulas and I have all objects magically landing right in the center of the world. Finally I add the location values previously saved in each object with the secondary script and now they land in the desired position!
Smoothing the movement:
For now the formulas used, especially the extrapolated translation one, return a linear movement which produce a very mechanical motion. However it feels nicer to have a "slow out" or deceleration right before each piece reaches its rest position. This is what IPO curves do best so I've used one to control all formula's time range. Chek line 52 for the function that gets the current value of a curve simply named "IPO", and if you chek the returns of all the rotation and moving functions you'll see how this value is used there to remap the otherwise linear time range.
Now that you understand how it works you can try it your self with these instructions:
- 1- Add game engine properties to the objects, storing their rest location and alos a start time offset; this is done with the second script that works on selected objects. The Start property is then set by different formulas that you can write for any specific case.
- 2- Add your objects to a group named "Main", when ever you want to disable their animation just remove the objects from this group.
- 3- Add the main script as a ScriptLink triggering on "FrameChange" and scrub trough the frames!
- 4- You need a "Time" curve in an Empty object on an IPO called simply "IPO" going from (0, 0) to (100, 10); this controls the interpolation of each piece so you can add "slow out" effects, etc
- 5- You need another Empty object named "Center" in the center of the scene or in the center of the build effect, you can animate this object to achieve nice oscillating movements
- 6- Run animation with Alt A or timeline
Credits: Wow Factor produced by martestudio.com
Render by Oliver 'imshadi' Zúñiga
Special thanks to Joshua 'aligorith' Leung and Geoffrey 'briggs' Bantle for developing tools necessary to finish this shot.
You can watch the final shot here: http://zanqdo.com/tmp/Rancho.mov
(Please Do not Direct Link).
by Daniel Salazar