This video is speed ramped to show the process of laying in a surface emitter and demonstrating the use of the script. For now the script is looking for nParticle1 which is the default name Maya gives a nParticle, I’ll fix this so that its any particle selected.
Life got a little tied up with TV and being lazy but I found myself at Siggraph in LA for a week and then in San Francisco visiting a good friend who helped me write this script a few days later. This was enough motivation to get back in-front of my computer again.
A while back I was working for a games studio and there was talk of a chemistry game. Whether it will be made or not I don’t know, but I started thinking about ideas for graphics or animated logos. The first thing that came to mind was millions of beakers all bubbling away. Beakers and collisions are simple with particles that are set to collide with passive objects, but what about bubbles that bounced off each other or the beaker, and what if they could get stuck together and react with air, turbulence, and all other physical attributes? What if you could click a button and make thousands of them at once? The idea only took a few seconds to come up with, the script a few weeks longer.
This script actually turned into 1 of 3 scripts because of a few other ideas that could be used off the initial idea. I’ll post about the other two scripts in the coming days and how I modified the code slightly to get the changes.
I thought I would start this as an inner monologue of how I went through solving the issues for the script. The first issue was how to create lots of dynamic bubbles quickly. Placing an emitter inside of a beaker and emitting with the walls set to passive got a lot of the behavioral characteristics of the bubbles, as well as interactions with the beaker surface. Next was capturing that information so that I could use it later. This is where I had to get some help with the script because my understanding of dictionary’s with python was a bit limited. I knew that I could emit a particle and capture it’s world space information on every frame, but how do I do that with a possible 1000+ particles at once all being birthed and killed off on random frames? It was actually a lot easier than I thought once I learned about the keys method. Afterwards it was just a matter of using a sort method to order all of the data. Have a look at keys here and sort here.
Once all the data is organized you can begin creating curves and locators. The curves were created based on the location of each particle in world space on each frame it existed, and once I had all the positions I could draw the curve through those vectors. Vectors are just x, y, z values in a 3D system. The next step was to create a motion path on the curve using the birth and death of the particle as the curves guide. By recording the frame data into the dictionary I could pull the vector data out at each frame and snap a locator to the created motionpath (as you need a transform object in the pathAnimation command). This is really the meat of the script, afterwards all we are doing is creating the spheres and the nCloth objects and placing them in a folder to keep our outliner clean.
So how do we create spheres with quads? Create a cube and add some subdivisions and apply a sculpt deformer, but don’t forget to kill all the history because there is a lot of node baggage that comes with this. How do we snap that quad-sphere to the location of our locators? xform is a handy command to find objects in world space and since one locator is created in each iteration of our loop – and there is a variable for that locator – we know which one to snap it too. Let’s make them all cloth, so add magical nCloth. Well now our bubbles aren’t connected to the original ball anymore and they fall. You won’t actually see the original ball unless you display the input mesh, it’s naturally hidden to keep the user from getting confused. How do we fix this? There is an attribute called inputMeshAttract on the nCloth shape layer and it has a value of 0 to 1, 0 being 0% and 1 being 100%. In the script I set this attribute to .7 initially, and 10 frames later to .4. I found that there wasn’t enough initial pull on the bubble to get it’s velocity moving in the right direction, so I give it a bit of a shove.
What these numbers are literally saying is start by pulling our sphere with 70% of the force in the direction of our curve and allow 30% of the dynamic attributes to control the rest. This gives us more user control but with the subtle drag attributes you would naturally get from an bubble like object. When we reduce the value to 40% we’re relinquishing the control of the user and allowing 60% of the forces that are applied to the sphere to be dynamic, this is much sexier. 😉
These attributes are a good start but now the bubbles smash up against the wall, sometimes so hard they crumple into odd pieces of unrecognizable geometry. Rigidity fixed a lot of these issues – in the video you will also notice that I added internal pressure of .2 into each bubble to allow it to fight back. One of the biggest issues when the bubble is birthed is the chance that it’s in a location overlapping another nCloth bubble. I tried playing with interpenetration with force fields and push and pull settings, some of which worked, but it often sent one of the opposing particles in a violent path across the screen. Setting the collide strength down to zero then increasing it to it’s full value several frames later fixed this issue completely. Other attempts at fixing this were scaling the transform component of the input bubble so that there was almost zero chance of overlap, but this didn’t work at all. With that in mind I thought scaling components such as the vertices might be a better choice. This had no affect either, which was odd but maybe it’s a value that nCloth ignores. Finally I got tired of always being able to see the bubbles and wanted them to pop on and off when the original particle birthed and died, so I set the visibility of the bubbles to the respective frames.
In the end there were a few minor changes made to the nCloth, but it’s all subjective at that point. Thanks to my good friend Chris Jones (Chech him out on github) for all his patience while my brain figured out what he was talking about 🙂 If you would like to play around with the particleToBubble script you can find it here. I will post soon about particleToCurve which is just a section of this script, and also about particleToTube.