Scroll below for an in depth description of the process of creating the Nyx Rig.
Scroll below for an in depth description of the process of creating the Nyx Rig.
Each complex control system in the rig is actually several smaller control systems layered on top of one another.
The limb control system in particular is built with around 4 layers of control systems total:
- Ik/Fk Switch: In the case of the arms, an Ik/Fk switch system is implemented, with an Fk Control System working adjacently to the Ik system. The leg was made only with an Ik control system due to personal preference.
- Ribbon Layer: A ribbon spline is parented under both bones of the limb. These ribbons control both limb twist and bendy deformation at once. It does this using deformers, specifically a twist deformer and a wire deformer.
- Automated Polevector Position: The position of the foot/hand control is taken and offset such that the polevector's movement is always positioned in the proper position to maintain forward orientation.
- Automated Polevector Twist: Calculating the offset of twisting between the foot/hand controller and the hip/shoulder of the character, we apply the additional offset to the polevector, having it swing around as the limb twists, causing the polevector to always orient itself in the forward direction relative to the twist of the limb. By calculating this offset using quaternions, the system is also robustly able to avoid complications from gimbal lock.
Roll Hull
In order to create a vector-based pivot system for the foot, I needed to make it so the pivot 'rolls' as the foot is tilted due to the curvature of foot's surface. To do this, I designed a system that took the original theory of the vector-based pivot system and expanded it to use an entire NURBS surface instead of a NURBS curve. I refer to this surface as the 'Roll Hull'.
Creating the Roll Hull involved four stages:
- Mesh: Taking a copy of the foot mesh and making a convex hull from it. This is done using scripts I wrote that flatten concave geometry while leaving convex geometry alone.
- Unrefined Surface: Converting the convex mesh into a NURBS surface. This is done by converting edge loops to NURBS curves and then lofting a surface.
- Latitudinal Isoparms: Generating NURBS curves that will define the position of the latitudinal isoparms. This is done through intersecting a NURBS plane with the unrefined Roll Hull.
- Longitudinal Isoparms: Generating NURBS curves that will define the position of the longitudinal isoparms. This is done using curveIntersect nodes, defining the point along each latitudinal curve that intersects the 'shadow' of a straight curve that marches around the topmost curve.
Finally, all that's needed is to loft the surface and clean up the results.
For more information on the Roll Hulls, check out my Roll System Project. (Coming Soon)
Foot Pivot and Ball Roll
With the Roll Hull constructed, I created a foot control system with two layers that operate adjacently, the system blending between them through a user controlled attribute and the direction of the pivot.
- Arbitrary Rolling Foot Pivot: Using the pointOnSurface node, I define the foot’s pivot point along the surface of the Roll Hull. I then define a ‘target’ orientation positioned on the floor plane that moves outward as the foot tilts. The distance of this movement is equal to the arc length along the curvature of the foot. The foot is then pivoted, parented under the surface pivot and onto the target orientation on the floor plane. This in effect allows the foot to roll along the floor plane.
- Ball Roll: When the foot pivots forward, the foot will instead add ball roll to the foot, to a point determined by a user attribute. When pivoting in a direction other than forward, the system automatically fades the ball roll toward off so as to seamlessly blend between control modes.
The Spine system controls the chest, spine, and pelvis in a single Ik control spline, though with an optional user controlled attribute that causes the chest controller behave as though parented under the pelvis controller when turned on.
Other than that, the base spine system is relatively simple, with the only layers of control systems in place being:
- Ik Spline Layer: The Ik spline, driven by a NURBS curve determines the shape, curve, and twist of the system. The system twists using Maya’s native Advanced Twist Control system within the Ik spline itself. This layer also controls spine stretching, as the NURBS curve’s length is connected to the scale of the Ik spline joints, allowing it to stretch and squash based on how much the controllers are stretched or squashed with a clamp node controllable by the user determining the limits of this deformation.
- Ribbon Layer: The ribbon, skinned to the Ik spline joint chain, drives the position and orientation of the actual skin joints. The ribbon also determines the ‘squash and stretch’ effect of the spine, scaling the spine joints depending on the current length of the spline curve.
The Auto Pelvis system is built upon the base spine system with several different layers all driving the autonomous motion. The first layer is the tilt layer, in which the system calculates the proper orientation of the pelvis by using two aim matrices located on each hip aiming down at their corresponding foot.
Two locators initially positioned at both hips are each parented under the opposite hip’s aim matrix, but their position is set to not change, causing only their orientation to change.
Then, two locators initially positioned at the same orientation as the pelvis are each parented under both of the hip locators. As the hip locators rotate, the pelvis locators move to the proper orientation that we want the pelvis to end in.
Finally, the two transform matrices of these pelvis locators are blended together and the resulting averaged orientation is output to the next stage.
The Roll layer calculates the amount of hip roll by using two ‘fake’ Ik legs that moves independent of the pelvis itself so as to avoid recursion.
Two aim matrices are positioned at each hip and aim directly at the ‘fake’ knee joint.
These two orientations are then averaged out and the resulting transformation is applied to the pelvis.
The Twist layer controls the pelvis' forward orientation as well as it’s lateral translation.
This is simply done by using an aim matrix that is located at each hip vertically, located at the position of each foot laterally, and aiming at the opposite hip.
These two aim matrices are averaged together and the resulting transformation is applied to the pelvis, effectively positioning the pelvis at the ‘average’ position laterally between the feet and oriented perpendicular to the line created from one foot to the other.
As an optional layer of user controlled automation, the drag layer moves the pelvis in the direction of either foot controller if that foot controller is currently further away from the hip than the total length of the leg. This system, though technically a part of the auto pelvis system, can actually be turned on and off independently, allowing one to use this system with or without the base auto pelvis system turned on.
It does this by creating two vectors, starting at each hip and ending at each foot controller.
If the magnitude of either vector exceeds the total length of the leg, it calculates the ratio between the vector magnitude and leg's length. We then subtract 1 from the ratio (This is done to preserve smooth continuity of the pelvis' automatic motion. Math stuff).
We then apply this sum as a multiplier to the vector, which gives us the exact translational transformations that we need to position the pelvis such that the foot controller is no longer further than the total length of the leg.
Plugging these translations into a multiplyDivide node that acts like a switch (controlled by the user), we then apply the result to to the pelvis.
The result is a system that acts as a buffer of sorts for animators, alerting them when the controllers have strayed too far, recommending a direction the animator could move the pelvis to fix the issue, and masking the problem should the animator choose to leave it as is.
By default, the chest maintains it's orientation regardless of pelvis orientation due to the spine Ik control system. However, in real life, when a bipedal creature's pelvis rotates, the chest typically counteracts that rotation to aid in maintaining balance.
To automate this behavior, one could simply take the rotation values of the pelvis and apply their inverse to the chest, but this leads to issues due to gimbal lock.
Instead, I simply extract the transform matrix of the pelvis and take it's quaternion orientation.
Keeping the 'real' quaternion unchanged, I invert the X, Y, and Z quaternions.
I then apply a multiplier to the X, Y, and Z quaternions, controlled by the user through an attribute.
The end result is a gimbal lock immune counter rotation system that is fully blendable on and off.
In my experimentation, I recommend a user value of 0.5, as real bipeds typically use a combination of counter rotation and translation to maintain balance and, as such, only counter their pelvis rotation partially.
As with the chest, the head by default maintains it’s orientation independent of the chest due to the neck Ik control system.
And again, in real life bipeds, the head will typically counteract chest rotation to aid in maintaining balance.
As such, the counter chest system was also implemented for the head.
Identical in every way to the counter chest system, the only things of note to mention is that it also works with the counter chest system turned on. As such, with both counter rotation systems on, rotating the pelvis will rotate the chest, which will rotate the head.
After experimenting, it is recommend a user value no higher than 0.35, as in real life, the head counteracts chest rotation only a little, as keeping the head upright is typically more important in order to avoid blurring vision while moving. Though I also find that you only need a small amount of counter rotation for the head to make it’s movements read as organic and lifelike.
The Auto Chest system is built upon the base spine system with two different layers driving the autonomous motion.
The first layer of influence is the Head Influence layer.
Because of the Counter Head system above, the head's orientation is technically being driven by the chest's orientation and, as such, having the chest then by driven by the head would lead to recursion. To avoid this, I only have the head controller's local matrix driving the chest, and as such, only the user's manual changes to the head's orientation will be fed into the auto chest system. In other words, the auto chest system is unaffected by any autonomous movement of the head, but is affected by manual, user controlled movement of the head.
To convert the head's orientation information into a usable form for the chest, I create an aim matrix, positioned at the chest's initial location, and aim it at the top of the head.
The aim matrix's secondary axis is determined by the twist of the head controller, allowing the head to also influence the chest's twist.
As the head tilts, the aim matrix will similarly tilt, and as the head twist, the aim matrix will similarly twist.
This resulting orientation is then fed into the next layer in the auto chest system.
The second layer is the Clavicle Influence layer.
Two aim matrices located at the initial chest position are aimed at each shoulder such that whenever either clavicle is moved, the aim matrix will adjust to aim at it’s end-joint.
The transforms of each aim matrix are then averaged together.
The Clavicle Influence Layer is then blended together with the Head Influence Layer, allowing all three body parts to drive the transforms of the chest.
The Auto Clavicle is relatively simple, and only has a single control layer, though with a remapValue node to aid in refining the automated motion.
To prevent recursion, a ‘fake’ arm is built that is controlled by the same controllers are the actual arm.
Then, an aim matrix is created, positioned at the initial clavicle location and aimed at the fake elbow. To avoid flipping, the secondary aim matrix is plugged into the location of a locator that automatically moves itself, in a manner not dissimilar to the auto polevector system, such that the aim matrix is always oriented in the proper direction.
The orientation of this matrix is then plugged into a remapValue node to alter and refine the orientation. Namely, the clavicle eases to a stop past a certain point of rotation, and it rises more than it drops, mimicking the real life range of motion of human clavicles.
The last thing to note is that this system fully works with the Automated Chest system, and therefore allows the chest to be driven by the arm in the following way: The arm drives the motion of the clavicle which drives the motion of the chest. If we include the counter head system, then technically we can even have the arm affect the head as well.
— Project Name
Nyx Rig
— ROLE
Full Designer/Creator
— DATE
January 2024
As a personal project, I attempted to design, model, texture, rig, and then animate a character from start to finish. The above video showcases the rig system for the character in question, a goblin named Nyx.
The rig uses almost a dozen different automation systems I designed myself including automated pelvis, chest, clavicles, polevectors, and various countermotions.
Having learned quite a bit from the project, I am already coming up with more optimized designs for the automation systems, as well as ideas for new automation systems.