-
Notifications
You must be signed in to change notification settings - Fork 41
About
The simplex solver aims to be the most comprehensive combination system I can create. It also aims to be as general as possible, so it is structured as a library along with simple wrapper plugins that use the library.
The idea came from a technical paper in the 2013 SIGGRAPH paper titled "Simplicial Interpolation for Animating the Hulk" by Julien Cohen Bengio and Rony Goldenthal. Unfortunately, the paper was not released (at least I couldn't find it), but I was lucky enough to be present at their talk.
In their talk, they described a method of PSD wherein an artist could add a target shape for any pose. This in itself is not surprising, we've had this with the Radial Basis Function for some time. However, with RBF you have to be careful with the number and placement of the samples, otherwise you can easily get wobbling. Instead, they took each input slider and set it up to control a dimension in a hyperspace. Then, each sample point would simply be an N-dimensional point in that space. After that, the space would be "triangulated" (the simplest shape in 2D is a triangle, in 3D is a tetrahedron, and in N-dim space is called a simplex). Once that setup was done, the animator could feed the system any N-dim point, and the barycentric weights of the simplex that contained that point would be returned. So each simplex corner was associated with a shape and a weight, and that was used to drive the PSD. There were some problems though. Anything higher than 3 dimensions was difficult for an artist to grasp, and anything higher than 6 proved incredibly difficult to find obtuse simplices that would form even with special tools written to find them. All interpolation was linear, and every corner of the space must be defined. Every simplex must be tested to see if it contains the animated point.
The underlying idea was great, but I wanted something that would be easy enough for an artist in the general case, not require full definition, and allow for spline interpolation between multiple shapes.
These were my ideas that led to the current system
- Artists don't want to deal with weights in places like (0.244, 0.34, .88311), they generally want to deal with extreme weights like (1.0, 1.0, 0.0, 1.0), and only then possibly an in-between shape like (1.0, 1.0, 0.0, 0.5) However, for technical artists, the power to place a shape anywhere must still be available, but it will not be the norm
- Allowing for spline interpolation between shapes will reduce the need for many "corner" points
- An artist doesn't want to manually build a new "dimension" when a new control gets added to the rig.
After much input from my coworkers, I have arrived at this current implementation.
First, A "simple" blendshape combination system is put into play based on the minimum value of all inputs. For any shapes defined at extremes, this is all that is computed. However, if an internal point is defined, I provide a default implicit triangulation of that point's hyperspace (what I MUCH later learned were called Schlafli Orthoschemes) which is then further refined based on any other points that live in that hyperspace. This means that an internal point that only activates with 3 sliders only has to deal with tetrahedra instead of a simplex in a crazy number of dimensions. During the solve phase, if that shape is activated, we supplement the 'extremes' shape with the delta based on a barycentric solve
There is one big problem I'm left with: The simple solve uses a naiive min() approach. This can cause hitches and corners with some shapes. If you look in ControlSpace::applyMask in simplex.cpp, you'll see where I have been working on finding a fast smooth approximation of the min() function that will eliminate these corners. However, I believe it will be necessary to add a switch between the exact and the smoothed solver.