Dual quaternion based skinning for XSI  Fernando Navarro Gil
fnavarrog at gmail dot com


Introduction
Using an envelope operator is one of the most common methods to deform a mesh using a control rig. Any character TD will give you lots of details on how to get nice deformations using these operators, their limits and the workarounds.

In this document I'll present you a new XSI envelope operator based on dual quaternion skinning. I will compare the existing and new methods and give some mathematical concepts that are useful to understand the limits and benefits of if them. Note that is a light and not very rigorous exposition, but if you are impatient and want to start playing with the new envelope, just jump to How to install and apply the new operator section.

I hope you enjoy it! :-)


How the XSI envelope operator works?
In general, an envelope operator will put together:
  • a skeleton composed of several bones (deformers).
  • a mesh that will be deformed by transforming (rotating, translating, scaling) the bones
  • a set of weights that will, o a per vertex basis, define how influential is each bone in the deformed mesh.

Once you have selected the bones, applied an envelope operator and defined its relative importance, how this data is used to build a deformed mesh? The method implemented in XSI is called linear blend skinning or skeleton subspace deformation [Lewis00]. It's based on the idea that every vertex is transformed using a weighted average of each deformer's transformation.

It can be mathematically modeled as



In the above equation v and v' represent the vertex position before and after applying the deformation, Cji is the matrix that represents the relative transformation of joint ji respect to its rest transformation and the weight wi contains a value that defines the importance of bone i in the overall result. In simple words, to get the deformed position of each vertex, we'll transform the vertex original position with a matrix that is the result of adding together the relative transformation matrix of each bone multiplied by its weight.

In XSI terms, the bone transform is contained in Kinematics.Global. The rest transform corresponds to the StaticKineState and contains the pose of the bone when the operator is applied. The weights are stored in a cluster property named Envelope_Weights. The equation assumes that all the weights assigned to a vertex sum 1 but there is no restrictions on this.





This method is flexible enough to generate good results, and has been accepted as de-facto standard. However, its simplicity is the source of its limitations. In the above image, a prism has been deformed using two bones and an envelope operator. We can see how is properly deformed near the root and effector, but but is too compressed in the area where the pink bone has been rotated. In the bottom image, the mesh collapses completely as a result of the same bone being rotated 180 degrees in the X axis. To understand the importance of this, replace that mesh with a character arm: when animated, the arm will not keep its volume and the elbow will be reduced to a point.

Note that several techniques can alleviate these problems. The simplest ones are adding extra deformers and fine tuning the weights applied to each vertex but both of them have a direct impact in the time that is needed to rig a character.

The origin of these problems is in the blending method itself. When a bone is moved, a rigid transformation (the composition of a rotation and a translation) is applied to it. If we interpolate several rigid transformations using a matrix representation, as in the above equation, the resulting matrix can or cannot be a rigid transformation. Scale and shear factors can be included in the result. That is why the mesh looks funny.


Dual quaternion based envelope operator
Different authors have found alternatives and improvements to the previous method. They are based on more complex mathematical models that usually translates to slower implementations. None of them have avoided all types of artifacts.

An simple and elegant alternative was proposed in [Kavan07]. As in the previous method, a mesh is deformed using a transformation that is calculated by mixing the transformations of each deformer. The difference is that each transformation is first converted into an equivalent dual quaternion representation and then blended together.

A dual quaternion can be seen as an extension of the traditional quaternions. If the later can represent rotations, a dual quaternion can deal with rigid transformations (rotation + translation).

Dual quaternion arithmetic has several properties that make them really attractive:
  • If we blend dual quaternions, the resulting dual quaternion will be a rigid transformation too, so these collapsing artifacts will be eliminated.
  • When two dual quaternions are interpolated, the resulting transformation will be along the shortest path between both. Points will be deformed following the "most natural path".
  • As a consequence, the mesh will deform keeping volume.
  • Operations with dual quaternions are fast, and can be based on existing quaternion libraries (in my implementation, they are based on the XSI SDK XSI::MATH::CQuaternion class). Even several implementations have been done using gpus.

Assuming that we have a method to convert matrix transformations into dual quaternions, blending several dual quaternions using a weighted average will be reduced to:



That is, we'll add a scaled version of the dual quaternion corresponding to each deformer. The scale factor will be given by the weight assigned to the deformer. After normalizing, the resulting dual quaternion needs to be converted back into matrix transformation. Looking back to the equation used by linear blending, this blended matrix will replace the expression inside the parentheses, and will be used to transform each vertex.

How this translates to a practical situation in XSI? In the image below we can see the same objects in our original example. We have used the same geometry, weights and bone rotations.





Note that the collapsing artifacts have been reduced, and the volume of the mesh is kept. Most remarkable differences can be seen in the bottom example. The polygons are deformed following natural paths, so the mesh is twisted instead of stretched.

This examples are extremely simple, but the same principles applies to more complex meshes/skeletons.


How to install and apply the new operator
Copy the file fnDualQEnvelope.dll to the Application\Plugins\ folder of your user (C:\users\<user name>\Softimage\XSI_<version>) or workgroup directories.
After restarting XSI, you will see a message that will confirm that the operator has been found:

INFO : Dual quaternion envelope v1.0 (Fernando Navarro,fnavarrog@gmail.com)

This operator has been designed to replace the existing one, so in order to use it, apply a standard envelope operator as usual: create a skeleton, assign the skeleton to the mesh, paint your weights...

After that, select the envelope operator and execute the menu option Animate > Envelope > Apply Dual Quaternion Envelope. The original one will be muted and a new fnDualQEnvelopeOp operator will be created (see the image).





Apart from that, there are no more differences: no modifications are performed in weights, clusters, etc. Since it uses the same weights as the original operator, any modifications performed on them (paint, smooth, ...), will be applied by the new operator. Either polygonal surfaces, NURBS surfaces, NURBS curves and lattices are supported.


Known limitations
  • As said before, this operator keeps the volume of the object as a side effect of the interpolation method. No explicit volume keeping techniques are implemented and extreme configurations will generate compression. However the number and importance of the artifacts will be lower than with traditional methods.
  • Since dual quaternion interpolation follows the shortest path, rotations of more than 180 degrees will flip.
  • Dual quaternion skinning is slower (according to [Kavan07] a 30% respect to linear blending). Since I don't have included serious optimizations, this implementation is not specially fast.
  • You can't delete nor freeze the original muted envelope operator. This is an XSI limitation. If you know a method to solve it while keeping the weights/clusters, I'll be glad to implement it.
  • If you want to add/delete deformers, you will have to do it on the original envelope and reapply the dual quaternion operator.
  • The operator has been tested in different versions of xsi. It should work on XSI 5.11 and later. Only a windows version is provided but it should be easily compiled for linux.
  • If you find a bug, please, email me with information to reproduce it and I'll fix it!


References
[Lewis00] Lewis, J, Cordner, M., and Fong, N. Pose space deformations: A unified approach to shape interpolation and skeleton-driven deformation. In Proceedings of ACM SIGGRAPH 2000

[Kavan07] Kavan, L., Collins, S., Žára, J., and O'Sullivan, C. Skinning with dual quaternions. In Proceedings of the 2007 Symposium on interactive 3D Graphics and Games.

http://isg.cs.tcd.ie/projects/DualQuaternions/ Ladislav Kavan web page contains the original papers, several videos and links to implementations for other packages.


Fernando Navarro, November 2007