Rapunzel, Rapunzel, let down your.. verlet physics simulation?

Recently I was commissioned to create motion graphics for Northwest Childrens Theater to be used in a production of Rapunzel. The set features a large projection screen for scene-setting rather than having physical set pieces (the play is a pop-rock musical and most of the set resembles a stadium concert stage). Among the challenges of creating dynamic animated content, a major aspect of the show is to display Rapunzel's hair as it's deployed from the tower window. http://vimeo.com/35366140

The script calls for the hair to be let out and pulled back up many times so I didn't want to use a single animation as it would become quite repetitive after seeing it for the second or third time. Like the rest of the motion content in the play I decided it'd have to be a dynamic system rather than a pre-rendered video.  Using processing, I hacked out several tests before I had what I wanted.  Once I was happy with the motion I integrated the resulting code into the larger eclipse project that I had been working on for the rest of the performance.  Here's a little review of where I started and the progression from concept to final implementation.

Before writing code I spent a few minutes drawing out what I was aiming for.  My rough idea was to position a bunch of image segments along a bezier curve.  By adjusting the offset of each segment along the curve I could then animate the hair to make it look like it was being lowered from the window.


Before writing code I spent a few minutes drawing out what I was aiming for. My rough idea was to position a bunch of image segments along a bezier curve. By adjusting the offset of each segment along the curve I could then animate the hair to make it look like it was being lowered from the window.

concept sketching

Test 1 : Segmented bezier spline

The first test was to get a series of connected nodes moving along a bezier spline. This would later become the basis for drawing a series of hair segments aligned along the path.

bezier segments

Test 2: Images aligned along a bezier spline

Next, I added some code to draw images at each point in the segmented path. The angle of each image is calculated via atan2 using the coordinates of the target point and the neighboring point. The results worked well but started to look funny when the curve was more extreme since the joints between each image became very obvious.

images on bezier

Test 3: Drawing a single textured mesh

The previous technique worked when motionless but when animated it looked sort of like links in a chain rather than a contiguous braid of hair. I also wanted to be able to use a single image of hair rather than ask the illustrator, Caitlin Hamilton, to draw a bunch of individual segments. This turned out to be easier than I thought since I already had the code done to figure out the angles of each segment. Vertices are positioned perpendicularly on each side of a segment and the mesh is drawn from end to end as a single quad strip.

At this point I felt like I was getting close to finished, but the motion of the hair really didn't feel right. I added some random movement to the bezier control points so the hair would appear to sway, but the extending motion along the path had an unnatural and sort of creepy look to it. This lead to something I thought of in my initial brain storming, but had dismissed as overkill.

bezier mesh

Test 4: Verlet physics simulation!

The last test was more of a complete re-do than an iterative development. Rather than use a bezier curve, I decided to go for an actual physics simulation of linked nodes. Thanks to toxiclibs this was a fairly simple task, and fortunately I was able to use a bunch of the existing code to calculate segment angles and build the textured mesh for rendering. As soon as I saw it in motion it was obviously the superior solution.

This final test worked great and I quickly set about integrating it into the performance tool. The deploy/retract animation is achieved by raising and lowering the top end point of the verlet particle string. There are also some invisible constraints which guide the particles making it look like they’re moving out and over the window sill (shown as red shapes in the above screen shots). It sure seemed like overkill when I though of this but I’m really glad I gave it a try. The results are exactly what I was shooting for in the beginning, and after lots of testing I’m fairly sure the physics won’t glitch out and ruin the show.  

verlet particle chain

data over time

First, a little history: When I was in my teens my friends and I used to play around on our computers with a program called "deluxe paint animation" which was, at the time, was a quite powerful graphics and animation tool for the PC.  Not only did it provide basic painting capabilities but it also included some cutting edge animation tools like motion tweening, morphing, and so on.  All of this ran at 320x200 pixels with an eyeball popping 256 color fixed palette.

delux paint animation

The other day while cleaning out a closet my brother came across an old floppy disk which, according to the label, held part of an animation project made by one of our close friends.  As amazing as it was to find the disk, the file was corrupt and couldn't be read; all attempts to view the now 20 year old animation failed.  It was part one of a science fiction saga titled "Porth" that our friend Cory had made (when he was fifteen) by stretching the animation tool to the absolute limits. In addition to being an interesting technical challenge, it was worth putting some effort into saving this file for nostalgia alone.

porth floppy

Many years ago I wrote a Pascal library to decode PCX images, and I had a hunch that the ANM format might use a similar run-length encoding scheme.  Upon recieving the corrupted file from my brother I set about scouring the internet for details of the ANM file format which Delux Paint Animation used for storing animated sequences.

After digging through some long abandoned forums and various geocities-styled nooks of the web, I came across some crusty old C source that claimed to decode ANM files. I'm not fluent in C but I figured it was at least a place to start.  It was clear that my assumption about the encoding method was correct.  After a couple hours of head scratching I managed to decipher the code enough to figure out the details of the data format.  Rather than start with a file I knew to be corrupt, I used an old EA Sports ANM file that I found online to test my code before delving into the digital archaeology project that my brother had unearthed.

ea sports animation

After a few hours of digging into the corrupt file with a hex editor, I had most of the original content playing back in all of it's pixelated glory. No crashes, just a handful of garbage frames introduced by reliance on a flimsy physical media never meant for long term archival data storage.

I was able to hack around the busted frames and managed to salvage most of the original file.  Unfortunately the animation encoding scheme works based on the delta between frames so there's still some visual corruption but I saved most of the content.  Here's the resurrected chapter of the Porth saga saved from a pile of corrupt bytes.

multi-touch projection table

A few weeks ago I spent some time building an FTIR multi-touch table.  I thought I'd post some pictures to share how it turned out and mention a few of the things I learned along the way.  It's still definitely a work in progress but I wanted to document it before I forget the details.  My motivation for doing this was to have access to a large scale multi-touch interface for design and prototyping purposes.  Plus it's fun to play with and I like to build stuff.

tuio table

For this screen I decided to go with the FTIR method since it's compact and I think it will allow for some interesting physical configurations that other methods, not being as self-contained, wouldn't support.  It also seemed like a reasonably simple project and had low material costs which were both important factors as this would be simply used for prototyping things in my home workshop.

Here's how it turned out:

As far as materials go, I got a chunk of 3/8" thick cast acrylic from TAP plastics, a sheet of velum, ~100 infrared LEDs, a tube of clear silicone sealant and a PlayStation 3 USB camera.  Those items along with miscellaneous wood bits and some wire were all I needed for the project.

Things I Learned

Nothing about the project was terribly difficult, but there were some stumbling points that I could have avoided if I had known a few key things.  Maybe they will help you too!

Thing 1 - Acrylic Edges

The edge finish of the acrylic makes a big difference, the clearer the better.  Rough saw cut edges scatter the IR light and will really dim the touch points.  I used varying grits of sandpaper down to about 350, then I buffed it with a polishing wheel.  You'll want to end up with an edge you can see through like glass, and should look sort of like a "hall of mirrors" effect when you peer into it edge-wise.  It's hard to take a photo of this effect, but the following picture should illustrate what I mean.

polished acrylic edge

Thing 2 - Visible Light Filter

From my initial readings online I tried using a piece of the film from an old floppy disc.  This works to reduce visible light, but also blocks significant amounts of the IR which makes the touch points very dim.  I tried a piece of exposed film negative which made a dramatic difference.  There's more visible light getting through but the signal to noise ratio is really good and I'm getting excellent tracking now.

Thing 3 - Camera Position

Even though CCV has calibration for the camera, it doesn't seem to handle keystone distortion well at all.  I was unable to get good registration if the PS3 camera wasn't lined up very precisely with the screen.  I find it hard to imagine that I'm the only one who had trouble with this, maybe I'm just doing something wrong in CCV?  Anyhow, it was frustrating enough that I made my own calibration utility that sits as a shim between CCV and my own projects, correcting the TUIO coordinates on the fly.

building a bench - part 2

It's always nerve wracking to post something as "part 1" because of all the expectations for the follow-up, but now the pressure is off because here's part 2! My decision to change the design from flat bar to square tube ended up working out well.  I feel like the bulk of the square tube is a better visual balance to the extremely sturdy bench top.  Also it forced me to keep practicing at welding and figure out how to make nice 90 degree corners consistently.

The legs started with a trip to a steel yard (a place I have never before found a need to visit).  I left with a couple of four foot sections of square tube and a feeling that I was really over-building the legs.  Not being accustomed to working with metal, I chose 3/16" wall thickness for the square tube which I now realize is completely overkill.  After buying the metal I cut the smaller leg pieces using a horizontal band saw.  I think I'd just do the cuts by hand with a grinder and cut-off wheel next time, it was kind of a pain to reconfigure the band saw for the 45 degree cuts.  It's a learning process..

The practice joints I welded came out better than I was expecting so I moved on to the actual leg pieces without too much fear of wasted stock.  The process of making the two legs went reasonably smoothly.  It took quite a bit longer than I would have liked, but that's often the case when working with unfamiliar tools.  The legs are screwed into the bottom of the bench via some angle iron brackets (shown here as I prepared to weld them in place).

leg in progress

All in all, I'm really happy with the results.  The first leg ended up about 1/4 inch narrower at the top due to heat shrinkage on the inside of the miter joint (that's my theory anyway) but it's not noticeable so I don't mind.  The important part is that I got them both level so the bench sits without rocking.

My guess is that the finished piece weighs in around 80 pounds and you could probably park a bus on it, but it looks great and is just what I wanted.


building a bench - part 1

I've been meaning to build a bench for quite some time.  First it was going to be entirely made from maple but then TechShop imploded and I lost my access to a wood shop.  Since then the design has changed several times.  Upon enrolling in welding and metal working classes at the local community college, I changed the frame to be mostly square tube steel.

planed wood close-up

Then I realized that unless I wanted to waste a lot of money on materials while learning how to weld nice 90 degree corners, I should reconsider the frame.  The second and third design borrow heavily from an article about a reclaimed fence post bench

The second design relied on making sixteen precise bends in some flat bar stock.  Let's just say I ended up with some oddly bent flat bar and no bench legs.  The third and final design is once again going to rely on square tubing and right angles, but will require much less precision and should work just fine.

Despite the learning experiences and road blocks of the legs, the bench seat is looking great.  It's made up of seven two by fours that I bought at the Rebuilding Center.  They are old wall studs (really old.. one had a square nail in it and they actually measure 2" by 4") set on edge and laminated together with excessive amounts of wood glue and lots of clamping.

After I had a solid slab of wood I hand-planed it flat and have applied many coats of tongue oil finish.  It's silky smooth to the touch now and is looking fantastic.  For the metal work and assembly, I've taken the plunge and signed up for a full membership at ADX so I'll be doing the welding and finish work there soon.