Opthon, a fully “math based” rig

Guest post by Jorn Boven/
Opthon, a fully “math based” rig
Recently I’ve slowly started to understand some math principles used in rigging, and to put those newly learned skills, I decided build a rig with a few strict rules to follow
- All of the rigging mechanics will be made using matrix and vector math – No other objects then the character mesh, and the controllers
- Fully in vanilla Maya, so no custom code
- Experiment with new kinds of setups
This resulted into Opthon, a fully “math based” rig:
When I posted it online, most people were interested in the BDK system, so let me talk a little more about it:
BDK stands for Bi-Directional Kinematic, a hybrid between FK and IK behaviour.
It works by “parenting” the FK behavior under the IK behavior (or the other way around). This setup has some important implications.
The biggest is that FK behavior ends up in IK space (or vice versa). This means that when FK and IK are active at the same time, both systems are influencing the controller, which can be confusing.
And even with BDK, you still need space switching. For example, if you want the hand to behave like a world-space IK control, you’ll still need to switch its space to world.
A significant upside, however, is that for shots using both FK and IK, you can just keep working with the same controllers the whole way through, which makes it a lot easier to manage.

How It Works
(This assumes you’re familiar with the matrix workflow.)
The BDK setup comes down to this: build a regular IK system > extract FK transformations > add it back onto the controllers.
We start by creating an independent world matrix. This is a world matrix that is not composed using the OffsetParentMatrix from the controller, so that later on, we can plug stuff back into the OffsetParentMatrix without running into cyclic dependencies. Take the Matrix and multiply it by the incoming connection to the OffsetParentMatrix.
![[Independent world matrix]](https://www.riggingdojo.com/wp-content/uploads/2025/08/Independed_World_Matrix.jpg)
Independent world matrix
With that in place, we can move on to the IK setup. I’m using a custom solver based on the Law of Cosines because it makes extracting data easier compared to a standard Maya IK handle. Whichever method you use, an IK system will always use: Upper arm length, Lower arm length, and the shoulder-to-hand length. These lengths should all be calculated using independent world matrices.
![[Law of Cosine]](https://www.riggingdojo.com/wp-content/uploads/2025/08/HQ_Law_of_Cosine.gif)
Law of Cosine
![[Custom IK solver]](https://www.riggingdojo.com/wp-content/uploads/2025/08/IK_Solver.jpg)
Custom IK solver
Next comes the FK behaviours. First, we want the lower arm controller to be a child of the upper arm. We take the upper arm’s Matrix (which is already independent) and remove the translation using a pick matrix. Then, together with the matrices used for the IK behaviour, we feed it into the multMatrix that drives the lower arm’s OffsetParentMatrix.
![[Lower controller BDK matrix]](https://www.riggingdojo.com/wp-content/uploads/2025/08/FK_To_Lower.jpg)
Lower controller BDK matrix
Finally, we want the Hand controller to be a child of the Lower arm controller. To make that happen, we have to construct two vectors:
• The Hand controller’s world position.
• The Hand controller’s world position multiplied by the Upper and Lower Arm controller’s Matrix.
The difference between these two gives us the FK transformation. We then add that transformation back into the OffsetParentMatrix of the Hand controller
![[Purple = World - Red = World + FK transformations]](https://www.riggingdojo.com/wp-content/uploads/2025/08/FK_Matrix.gif)
Purple = World – Red = World + FK transformations
![[Upper controller BDK matrix]](https://www.riggingdojo.com/wp-content/uploads/2025/08/FK_Transformation_setup.png)
Upper controller BDK matrix
Outro
I hoped to have given you an overview of the concept behind BDK. There’s still plenty of room for improvement, both in the technical setup and the overall user experience. If you’d like to build something similar yourself, or if you have ideas on how to improve this setup, feel free to reach out. I’d be happy to chat and exchange ideas!
Please reach out to me on Linkdin: https://www.linkedin.com/in/jornboven/
