Finally, there is time to write down some of the sentences we spoke during our talk at the FMX! I´m going to start with the part about animating strands, because it covers many of the things we learned about ICE during the production of Loom.
First of all, ICE seems to be understood by most people as a simulation environment. But what makes it so special for us is actually the fact that you can drive the movement of particles (and strands) without relying on simulation but being independent from the timeline. Of course, with kinematics being supported in Softimage 2011, ICE will step a little bit further away from being understood as a simulation tool. And like I said during the talk: Houdini users might laugh about us being so excited about things they have been doing with their tool of choice for years, but having a kind of “baby Houdini” inside the software we produce our movies with is nothing but totally awesome.
Simulating your animation often seems to be a fast way to move your stuff around, but when it comes to tweaking and staying in control, things often become more and more complex, frustrating, unstable and thus time consuming. There were many things, we first tried to solve with a simulated ICE tree, but the more we became familiar with the way ICE works, the more we moved towards finding unsimulated solutions for our tasks. We are still making movies, so we always have just to make things look like they were real- if we can fake it for the benefits of control, it´s more than fine! Although there are many many particles and strands involved in Loom, there is almost no simulation used.
One of the more difficult tasks was to make strands grow from a certain position to a given goal with having full control over the way they take as well as the timing of the animation. What made the tasks difficult is, there were almost 4000 strands involved, so there had to be a solution to handle both animation and performance. Simulating the whole thing brought us exactly what I mentioned above: long simulation times, no timeline scrubbing, and growing complexity for control.
So here is how we did it the unsimulated way- it´s not big science, but a really easy and flexible setup with awesome performance:
Assuming you already have your point- filled pointcloud, first of all, you define your goal (start is already defined with your point position). Building a linearly interpolated array with your point position and goal position as start and end values gives you a set of strand positions. The larger your array is, the more subdivisions you have in your strand.
Having your linear strand ready, you would now start to model the way your strands take from start to end. For that, you need to be able to edit different positions on your strand separately. You can do this by just piping your strand positions array through a FCurve. With what comes out of the FCurve node, you can now vary whatever value you want along your strand. In terms of driving the position of the strand, we used mostly just blend nodes- with the FCurve driving the blend value between the existing strand position and the position (or direction) you want the strand to take on its way.
Making your strands grow is also really easy: you just delete values from your strand positions array starting with the last value in the array (your goal position). You can do this very easily by just using another array for the values you want to delete. When it comes to animating the growth, the modulate by volume node gives you a good tool to vary and drive it.
Of course, what you get with this (really easy) setup so far is pretty linear movement. The fantastic turbulence node can help with this, just insert it wherever needed…! If you´re trying to vary values based on strand positions, be sure to pipe the strand position attribute in the position slot of the turbulence node. Otherwise, all strand positions will get the same value based on the according point position.
In case you are dealing with a large number of strands and have trouble rendering: by default, the geometry generated is super high tessellated. To decrease tessellation, you can use the undocumented attributes shaperesolutionu and shaperesolutionv. You need to pipe an integer into your set data node, before ICE will recognize it. This does not work for segments.
That´s it! Really easy, I would say and far from the complexity you get trying to simulate that thing… Hope I managed to write this down in an understandable way- if there are any questions, feel free to make use of the comments or write an email!