Showing posts with label shrinkwrap. Show all posts
Showing posts with label shrinkwrap. Show all posts

Friday, 26 November 2010

Rigging the Sidewinder Desert Snake


The desert snake basically has a continuous sine wave running throughout its body, apart from the tail and the head which are partially free - the head tends to stay fairly level but still inherits some of the rotation from the body wheras the tail flips loose.  For the continuous sine wave, rather than using a wave modifier on a curve and relying on keying the speed (clumsy at best - I'd rather key the offset but then with speed set to 0 the wave disappears and further adjusting wave width during the animation isn't possible, unless you choose to scale the curve to change the wave width but then you get into more problems!) I drew a simple sine wave with a path, arrayed it many times, curve deformed it into a circle then applied the circular curve deform and set the path to be cyclic (on U).  I then converted my circular wavy path to polygons and extruded it out (with shift-Z to constrain scale to X and Y only).  I built a simple FK armature each of whose bones began and ended on the wavy surface, running round with a slight circular bend.  Below the start and end of each bone I put an empty which was shrinkwrapped with Z project to the wavy surface.  Each bone then has a track to constraint aimed at the empty nearest its tail.

I then use a second of chains of bones to convert this wavy (but curved) motion into a wave in a wave in a leaning plane (roughly the XZ plane rotated 45 degrees about Y) by copying only their local X rotation and making sure the bones in my second chain have their Z axes pointing towards the vector (0,1,1).  Then a third chain of bones tracks to the tail of its double in the second chain with maintain Z up set.  A fourth chain is used to add a user specified rotation in the world Z to each bone (for example a curve in the snake).  This has to be done in a separate chain containing copies of the third chain's bones rotations as rotating any bone in the third chain disrupts all of its children's track to constraints!)

A final few bones are used to add non-automated animation to the head and tail.  The width and height of the waves can be controlled by scaling (the parent of) the large rotating wavy disk in the world X or Z axis (there are some empties in between with maintain volume constraints to move the chain of empties which the first chain tracks to into the right position), and the rate of progress of the wave down the snake's body is controlled by rotating the wavy disk.

Now down to animating, at long last.


Saturday, 13 November 2010

Boundaries for Python Boids and Using the NLA for Animation Layers



Thanks to Campbell's bug fix for the shrinkwrap constraint, my python coded boids (not blender's built in types) can now stay constrained to a surface, albeit very slowly.  The execution of my python code is pretty rapid, considering the number of adjacencies which need to be taken into account, and I have some tidy ups planned which should make it even faster.  The downside is that I need the code to know the visual location (not actual location) of each boid after shrinkwrapping, and then apply this to the actual location.  Logically if I did object.location=object.matrix_world.copy().translation_part() you would expect this to update the visual location.  However it seems that (somewhat sensibly) blender doesn't always update constraints after every line of python which could make the visual location of an object differ from its actual location.  Trying to tell blender to update the world matrix to reflect changes in the object's location seems to be the main problem, especially when the object has keys (so just setting the current frame won't work).  The best option seems to be to key the location (and oddly enough using object.keyframe_insert('location') doesn't update the matrix, but ops.anim.keyframe_insert(....) does, but is much much slower) then read back the matrix.  This unfortunately is extremely slow, but does seem to work.

UPDATE: documented a workaround inspired by some of Bassam's suggestions.

Some python work which on the other hand has been more successful is a workaround to use NLA strips as animation layers (in the same way they would work in maya).  To use the script key the base animation in and then snowflake the action in the NLA window.  Then add a new NLA strip on a higher layer and set the mode to additive (to do this you'll probably have to create an action with a garbage key which you can later delete, link the action to the object then snowflake it).  Set your new top layer NLA strip to add mode then tab into it (tweak mode as its now called).  Start posing and whenever you want to insert a key use this script http://www.pasteall.org/16791/python instead of the 'I' key.  This makes sure that the new keys are relative to the layer below.  In good news aligorith confirmed that this behaviour will soon be built into blender and you won't need my script for much longer!