# follicle

## Maya matrix nodes – Part 3: Matrix rivet

This post is a part of a three post series, where I implement popular rigging functionalities with just using maya’s native matrix nodes.

Rivets are one of those things that blew my mind the first time I learned of them. Honestly, at the time, the ability to stick an object to the deforming components of a geometry seemed almost magical. Although, the more you learn about how geometries work in Maya, the more sense rivets start to make. The stigma around them, though, has always been that they are a bit slow, since they have to wait for the underlying geometry to evaluate and only then can they evaluate as well. And even though that is still the case, it seems that since parallel was introduced the performance has increased significantly.

It is worth trying to simplify and clean rivets up, considering how handy they are for rigging setups like:
– twist distributing ribbons
– bendy/curvy limbs
– sticking objects to geometries after squash and stretch
– sticking controls to geometries
– driving joints sliding on surfaces

and others.

When I refer to the classic rivet or the `aimConstraint` rivet, it is this one that I am talking about. I have seen it used by many riggers and also lots of lighters as well.

The purpose of this approach is to get rid of the `aimConstraint` that is driving the rotation of the rivet. Additionally, I have seen a `pointConstraint` used as well, in order to account for the parent inverse matrix, which would also be replaced by this setup. Even though we are stripping constraints, the performance increase is not very large, so the major benefit of the matrix rivet is a cleaner graph.

TL;DR: We are going to plug the information from a `pointOnSurfaceInfo` node directly into a `fourByFourMatrix` node, in attempt to remove constraints from our rigs.

Disclaimer: Bear in mind, I will be only looking at riveting an object to a NURBS surface. Riveting to poly geo would need to be done through the same old loft setup.

Limitations: Since we are extracting our final transform values using a `decomposeMatrix` node, we do not have the option to use any rotation order other than XYZ, as at the moment the `decomposeMatrix` node does not support other orders. A way around it, though, is taking the `outputQuat` attribute and pluging it into an `quatToEuler` node which actually supports different rotate orders.

### Difference between follicle and aimConstraint rivet

The locator is riveted using an `aimConstraint`. You can see there is a small difference in the rotations of the follicle and the locator. Why is that?

The classical rivet setup connects the `tangentV` and `normal` attributes of a `pointOnSurface` to the `aimConstraint`. The third axis is then the cross product of these two. But it seems like the follicle is actually using the `tangentU` vector for it’s calculations, since we get this difference between the two setups.

Choosing to plug the `tangentU` into the `aimConstraint`, instead of `tangentV`, results in the same `behaviour` as a follicle. To be honest, I am not sure which one would be preferable. In the construction of our matrix rivet, though, we have full control over that.

### Why not follicles?

As I already said, in parallel, follicles are fast! Honestly, for most of my riveting needs I wouldn’t mind using a follicle. The one aspect of follicles I really dislike though, is the fact that it operates through a shape node. I understand it was not meant for rigging, and having the objects clearly recognizable both in the outliner and the viewport is important, but in my case it is just adding up to clutter. Ideally, I like avoiding unnecessary DAG nodes, since they only get in the way.

Additionally, have you had a look at the follicle shape node? I mean, there are so many hair related attributes, it is a shame to use it just for `parameterU` and `parameterV`.

Therefore, if we could use a non-DAG network of simple nodes to do the same job without any added overhead, why should we clutter our rigs?

### Constructing the matrix rivet

So, the way matrices work in Maya is that the first three rows of the matrix describe the X, Y and Z axis and the fourth row is the position. Since, this is an oversimplification I would strongly suggest having a look at some matrix math resources and definitely watching the Cult of Rig streams, if you would like to learn more about matrices.

What this means to us, though, is that if we have two vectors and a position we can always construct a matrix out of them, since the cross product of the two vectors will give us a third one. So here is how our matrix construction looks like in the graph.

So, as you can see, we are utilizing the `fourByFourMatrix` node to construct a matrix. Additionally, we use the `vectorProduct` node set to Cross Product to construct our third axis out of the `normal` and the chosen tangent, in this case `tangentV` which gives us the same result as using the classic `aimConstraint` rivet. If we choose to use the `tangentU` instead, we would get the `follicle`‘s behaviour. Then, obviously we decompose the matrix and plug it into our riveted transform.

Optionally, similar to the first post in this series, we can use the `multMatrix` node to inverse the parent’s transform, if we so need to. What I usually do, though, is parent them underneath a transform that has it’s `inheritTransform` attribute turned off, so we can plug the world transforms directly.

It is important to note that in this case we are absolutely sure that the output matrix is orthogonal, since we know that the `normal` is perpendicular to both tangents. Thus, crossing it with any of the tangents, will result in a third perpendicular vector.

### Skipping the vector product

Initially, when I thought of building rivets like this, I plugged the `normal`, `tangentU` and `tangentV` directly from the `pointOnSurfaceInfo` to the `fourByFourMatrix`. What this means, is that we have a matrix that is not necessarily orthogonal, since the tangents might very well not be perpendicular. This results in a shearing matrix. That being said though, it was still giving me proper results.

Then, I added it to my modular system to test it on a couple of characters and it kept giving me steadily good results – 1 to 1 with the behaviour of a `follicle` or `aimConstraint` rivet, depending on the order I plug the tangents in.

What this means, then, is that the `decomposeMatrix` node separates all the shearing from the matrix and thus returns the proper rotation as if the matrix is actually orthogonal.

If that is the case, then we can safely skip the `vectorProduct` and still have a working rivet, considering we completely disregard the `outputShear` attribute of the `decomposeMatrix`.

Since, I do not understand how that shearing is being extracted, though, I will be keeping an eye on the behaviour of the rivets in my rigs, to see if there is anything dodgy about it. So far, it has proved to be as stable as anything else.

### Conclusion

If you are anything like me, you would really like the simplicity of the graph, as we literally are taking care of the full matrix construction ourselves. What is more, there are no constraints, nor follicle shapes in the outliner, which again, I find much nicer to look at.

This matrix series has been loads of fun for me to write, so I will definitely be trying to come up with other interesting functions we could use matrices for.

## Maya performance test – Follicle vs Classic rivet

The classical rivet was a really popular rigging thing a few years ago (and long before that it seems). I am by no means a seasoned rigger, but whenever I would look for facial rigging techniques the rivet would keep coming up. What is more, barely if ever people suggested using `follicle` to achieve the result, generally because the classical rivet evaluates faster. So, I thought I’d do a maya performance test to compare them.

#### Prerequisites

I will be looking into the performance of a `follicle` and a classical rivet, both on a NURBS sphere and on a poly sphere. NURBS because I tend to use a lot of ribbons and poly, because it’s a popular feature for attaching objects to meshes.

I will be using Maya 2017’s Evaluation Toolkit to run the performance test, as it gives nice output for each evaluation method, even though I cannot imagine using anything but parallel.

The way the tests are going to work is, I will create two files, each containing the same geometry with 10 rivets. In one file I will use follicles and in the other the classical setup. The deformation on the geometry will just be keyed vertices and it will be identical for each setup, so we can be sure that the only difference between the two files is the riveting setup.

Then, the test will be done in a new scene where I will reference the file to test a 100 times. For each setup I will run the evaluation manager’s performance test and take the results and compare them.

Okay, let us have a look then.

#### NURBS

##### Classical rivet setup

So, the way this one works is I just loop from 1 to 10 and I create a `pointOnSurfaceInfo` node with `parameterU` set to `iterator * .1` and `parameterV` set to .5. Then, I plug the output position directly to a locator’s `translate` attr. Additionally, the output position, normal vector and a tangent vector go into an `aimConstraint` which constraints the rotation of the locator.

##### Follicle setup

This one is fairly straightforward, I just created 10 follicles, with `parameterU` set to `iterator * .1` and `V` to .5.

##### Results

Bear in mind, `EMS` refers to serial evaluation and `EMP` is parallel.

``````NURBS surface
Classical Rivet
Playback Speeds
===============
DG  = 13.1694 fps
EMS = 11.1359 fps
EMP = 20.7469 fps
-----------------------------
Follicle
Playback Speeds
===============
DG  = 11.3208 fps
EMS = 12.6263 fps
EMP = 27.8293 fps
``````

Even though I expected the follicle to be faster I was surprised by how much. It is important to note that we have `10 * 100 = 1000` rivets in the scene, which is obviously a big number. Therefore, in a more realistic example the difference is going to be more negligible, but still `7.8fps` is quite a bit.

What is also quite interesting is that in `DG` the follicle is slower than the classic rivet. So, the stigma of the old days that the classical rivet is faster, seem to be deserved, but parallel changes everything.

#### Polygons

##### Classical rivet setup

So, when it comes to polys the classical rivet gets a bit more complicated, which I would imagine results in a larger slowdown as well. The way this setup works is, we grab 10 couples of edges, which in turn produce 10 surfaces through a `loft` node. Maintaining history, the nurbs surfaces will follow the poly geometry. So, we can perform the same rivet setup as before on the nurbs.

###### Follicle setup

On a mesh with proper UVs the follicles are again trivial to set up. We just loop 10 times and create a follicle with the appropriate `U` and `V` parameters.

##### Results
``````Polygon geometry
Follicle
Playback Speeds
===============
DG  = 1.7313 fps
EMS = 3.32005 fps
EMP = 9.79112 fps
-------------------------
Classical rivet
Playback Speeds
===============
DG  = 1.05775 fps
EMS = 1.52022 fps
EMP = 3.31053 fps
``````

As expected, follicles are again quite a bit faster. I am saying as expected, as not only do we have a riveting setup as in the NURBS case, but also there is the edges and the `loft` which add to the slowdown. I am assuming, that is why even in DG the classical rivet is still slower.

#### Conclusion

So, the conclusion is pretty clear – `follicle` rivets are much faster than classical rivets in the latest maya versions which include the parallel evaluation method.