View Full Version : Variable speed looping animation sequence? Help with bird flight needed...

11-01-2007, 12:34 PM
It's been quite a while since I've posted, but am kinda stuck on a problem and would really love to get some help.

I'm working on animating a flock of birds; a single bird is animated (either with bones or morph maps or MDD, I've tried them all), attached to a particle via FX_Link, and then cloned 29 times (for a final total of 30 birds). This works rather well, but comes off looking more like a swarm of bats than a flock of birds. Partly because the particle setup (particle emitter and path wind) is rather simple, and partly because the flapping is all wrong... I've taken a look at various motion studies and online references, and have tried to fix some of the major issues (wing tip motion, the up/down, front/back nature of the wing cycle, etc.). Unfortunately, a big part of bird flight is the whole relationship of flapping and gliding. I've tried various solutions, but so far nothing is working for me!

Because FX_Link can generate keyframes, I'm able to access flight path position data, and so long as the object has "align to path" or "align to velocity" enabled, I'm also able to access rotational values.

(see attached Layout.gif)

There are three basic areas that I would like to address in my animation:
body movement - head looks forward, tail steers a little
(this is easily, though simplistically, accomplished with bones)
wing flapping - wings beat harder and faster as bird climbs or accelerates movement, slows to a glide when bird slows or angles downward
wing followthrough - "arm" wing reaches forwards at start of downstroke, pulls back on upstroke. "hand" wing extends on downstroke, folds on upstroke
(might be a bone following solution, but no luck quite yet)

The following are solutions I've tried so far (well, the top three seemed-promising-but-still-failed ideas).

1. Morphs controlled by speed: I set up my wing flap morphs and attached them to the colour inputs of keys in a gradient using the nodal displacement editor. Odd, I know, but I've used this to great effect before... the gradient blends between each morph shape rather fluidly, and all you have to do to control a complete timeline of morphs is use a 0-1 scalar input. Very easy, great results. Unfortunately, I need the flapping animation to loop. This is fixed in part by including pre-roll and post-roll in the gradient (so 0 and 1 are blending with the end and beginning of the motion), but looping an input is still a problem. Also a problem is getting the speed, velocity, and climb of the flight pattern to control the speed and/or depth of the flapping. I was able to use the DP Kit Item Info node to determine location differences based on time offset, but wasn't able to find any way of controlling a loop via this function (Pom's Counter node isn't counting per frame, it's per object... I felt like an idiot after trying a couple hours to get it to increase a value every frame based on the "intensity" of the distance being traveled).

(see attached MorphNodes.gif)

I still haven't found a way to animate a cycle of 0 to 1 (and repeating 0 to 1, not bouncing between the two; saw wave, not sine wave) with the animation speed based on some sort of scalar input (ostensibly the speed, velocity, and amount of climb in the flight path combined into an easy to use value that determines the flapping needed by the bird to fly to wherever the path goes next in the timeline). This is one of my favorite non-working solutions just because I love editing displacements in a nodal environment. :D Lightwave nodes rock! Now if only Newtek can extend this to EVERYTHING... I can skip expressions (see #3) altogether. Sadly, nodal morphs are also quite slow... so they don't work, AND you can't scrub the time line.

2. MDD controlled by similar means: using a baked flapping motion repeated either via motion mixer (which I've never been able to figure out, and couldn't get to work right for this project) or nodes. In the displacement node editor, the DP Kit MDD Pointer node takes time inputs, not speed of playback, and when animating the speed manually (though in theory this would be perfect, since envelop controls would allow for expressions), it doesn't blend between frames! I end up with stop-motion animation when the flapping slows down to a glide.

In theory, a MDD file could be the solution... I just haven't found a way to control the speed via scalar or expression inputs, while blending properly between the baked keyframes (necessary when slowing the frame rate to a gliding position). I'm not sure why this isn't working, though I'm assuming it very well could be the solution, and I just did something stupid. The biggest drawback, even if I get this working, is that it doesn't allow for adjustments to the the strength or depth of the flapping, something that's easier in the next attempt...

3. Bone motion controlled via Expressions: calculating velocity, climb, etc. to drive a sine wave that thusly controls the first wing bone. Each successive wing bone then derives their motion from the parent, either following behind (to create the necessary extension and folding of the wing), or following and reacting (to create the forward and back motion also necessary for flight simulation). I was able to get the sine wave to work, but it's "looping" weird in that it doesn't zig-zag; it "waves". Points where the flight path velocity reverses, either speeding up or slowing down, the sine wave will dimple at one edge of the spectrum, causing a "flap" that just twitches at the top or bottom of the wing animation "loop". Also, I've been unable to get vector speed working (tried following the Builder instructions, no luck), only per-channel velocity. Thus, the flapping stalls when the bird no longer moves up and down (Y axis velocity), which is bad when it's still moving on the X and Z axis. To make it even worse, I'm having no luck in driving successive bone animations, as the sine wave up-down motion isn't translating well to front-back motions (offset by time, of course). I'm not sure why this isn't working, as in theory it should (wing goes up, wing goes forward in response, offset by [x] many frames, wing goes down, wing goes back [x] many frames later, etc.). Somehow, the wing is going forward and backward twice twice every up and down cycle... very strange.

Here's the sine wave calculation (all other motions were controlled by the Follower modifier):
sin(((([Bird 002b.Position.Y, Time + .4]-[Bird 002b.Position.Y])/(0.4)+0.2)*150))*((([Bird 002b.Position.Y, Time + .4]-[Bird 002b.Position.Y])/(0.4)+0.2)*250)+-10

(see attached ExpressionResults.gif)

If there's a way to make expressions work, it'd also be possible to drive the two wings semi-independently, making turning movements that much more realistic (where the wing inside the path's curve will fold a little more and flap shallower, maybe controlled by modifiers to the flapping loop based on relative X movement offset forward in time?). At least with a bone setup, the tail and head can behave with reasonable intelligence. I have the head bone set up to follow the body, looking ahead by half a second or more, and the tail is similar, steering the body movement like a rudder (time offsets are an awesome thing, though of course bird tails are faaaar more responsive than a simple rudder, but at least the model isn't static in this case). Unfortunately, the wing movement still doesn't work well...

Well, this is a massive post, my apologies. I've done flocks of birds before for matte paintings, but I'm tired of semi-creepy swarms of almost-bats. :P If there's any solution to be had, especially if the resulting animation is procedurally generated, I'd love to find it...

Here are a few of my references:

11-01-2007, 01:39 PM
I have some good results with MDD Pointer node and
random offset or varying speed,
first get an loop animation, end frame = first frame,
input a scalar as time with an envelope with a key
at 25 or 30 with 1.0 (second) and offset repeat behavior,
check also repeat motion in MDD Pointer,
then you can add a random node
(Trueart node library, don't know for Mac)
or objecID for offseting the time or varying speed
by multiplying the scalar node for time by another
constant scalar node + noisychannel (low speed).


Note:the random node will input different number
for each cloned object.


11-01-2007, 02:34 PM
...Was wrong, the random node is in Pomfried node pack,
works well to multiply the time (constant scalar time)
and get various speed for each cloned object,
the range of the random number must be decreased.


11-01-2007, 02:49 PM
Denis - Thanks so much! That's good to know... I'll keep it in mind for future projects, especially if the MDD doesn't need any more adjustment than randomized speeds.

Unfortunately, it doesn't solve the bird flight problem, where the speed needs to be varied over the life of the animation, not just per-item. I've made some headway in automated wing animation (animating all subsequent wing bones based only on the P animation of the first parent), so all that's left is the whole flapping-based-on-motion-path thing. I'll post a quicktime as soon as I can get a decent render finished.

11-01-2007, 03:30 PM
The noisychannel in a constant scalar for
multiplying the current scalar time node do
a variation of speed over time, but it
needs also to have a different offset for
each object/bird, with the addition of another
random node.
This way you can get different speed and
different variation of speed over time
for each cloned object.
But there are more test to do to find
good random and noisychannel settings.


11-01-2007, 04:42 PM
Ah, I see now, sorry about that! I'm assuming I can place a vector scaler of some sort between the MDD node and the displacement input to affect the amount of animation being applied? I'll have to try this out sometime.

I've been able to get the wings animated via simple inputs, so may try yet to use a sine wave to control wing beats... we'll see. The attached render is still kinda rough, and a bit too slow, really. But it uses just two channels (wing left P and wing right P are currently keyframed, to be replaced by procedural beat pattern, hopefully) to animate the wings, and everything else is based on the motion path (currently keyframed, to be replaced by particle animation).

11-02-2007, 05:13 AM
...Really not convinced by my previous idea,
but found this one:

Using Item Info node from DP_Kit, which has
a Time offset as input, the basic time comes
from X Position channel of a Null with variations,
the length of each bird position is used as offset,
but we could use something else,

Need more work for realistic flock.

11-02-2007, 05:21 AM
Denis, that is gorgeous. Love your work.


11-02-2007, 09:13 AM
Very cool! Unfortunately, MDD Pointer from the DP Kit is crashing Lightwave upon motion file loading... both CFM and UB versions too. I'll keep trying, but it looks like my time for this project is drawing to a close. :(

11-02-2007, 09:48 AM
Could this scene be tested under OSX or UB with DP_Kit
installed, please report if Layout crash.


11-02-2007, 01:36 PM
I've tested the scene in both 9.3 PPC (full version), and 9.3.1 UB (latest beta, released yesterday?). Neither version can find an MDD file when loading a scene; I've had this trouble with all of my own files, and again with this test. I'm able to open the displacement node editor, edit the MDD node, find and select the previously lost MDD file in the file dialog, and close the window. However, Lightwave crashes as soon as the viewport updates; usually triggered by moving in the timeline one frame forward or backward. This is consistent across both PPC and UB versions of Lightwave, both 9.3 and 9.3.1.

Tested on: Dual 2.5Ghz PPC Macintosh, 2.5Gb RAM, dual displays, ATI 9600 XT with 128Mb RAM, running OS X 10.4.10.

11-02-2007, 02:25 PM
Denis sent me the scene to check on OSX, and I can replicate the issue.
I also think I know what's going on (the windows that gets shown when the file isn't found gives a big clue).