2
\$\begingroup\$

I am implementing a skeleton system for my latest game. I am using my own linear algebra classes which already have some optimisations, such as separate transformPoint and transformVector functions which avoid some multiplications by 0 or 1. It is working well so my question is not HOW to implement skeletal animation.

My question is how to optimise the matrix multiplications. At the moment there are several full 4x4 multiplications and 1 inverse per bone. I need the inverse because this is not just for skinning but also physics and stuff. But there are many 0s and 1s in the homogeneous matrices which can be optimised out. Also, I want to be able to specify the degrees of freedom for each joint, and in which order they are calculated, so for example, a shoulder joint could rotate yaw then pitch, or pitch then yaw. The result would be different. Should I have a separate matrix constructor for each permutation, which I believe is 15?

I assume this is a common issue with skeletal systems, so is there a standard method for this? How do engines normally optimise forward kinematic calculations?

I calculate all the matrices for the bones, starting at the root and working outwards. Note: my bones are in an array that is sorted by heirarchy depth so a bone's parent's matrices will already have been computed.

Please note: this is not a questions about skinning, I have no problem with that.

\$\endgroup\$
4
  • \$\begingroup\$ Are you using SIMD? Other than that, cutting some floating point instructions is hardly a measurable performance gain on modern CPUs, given a resonable number of skeletons. You might want to profile before you spend too much time on it. \$\endgroup\$ Commented Jun 4, 2013 at 14:07
  • \$\begingroup\$ Not sure if you already do it, you didnt mention it: You can, most of the time, get rid of a full inverse matrix calculation, as long as the matrix is affine, or even better just a rotation matrix, this stackoverflow answer explains it. \$\endgroup\$ Commented Jun 4, 2013 at 14:14
  • \$\begingroup\$ Yes, I had heard of the inverse optimisation, but I wasn't sure if my matrices are always affine. I guess they are when doing only rotations and translations, right? \$\endgroup\$
    – DaleyPaley
    Commented Jun 5, 2013 at 4:24
  • \$\begingroup\$ Yes, if M=R*T, then M^-1 = T^-1 * R^-1. Multiply the individual inverses in reverse order. R^-1 is the transpose of R, T^-1 has simply the negated translate vector, instead of {x, y, z} its {-x, -y, -y}. I will make it a clearer answer later. \$\endgroup\$ Commented Jun 5, 2013 at 6:03

1 Answer 1

1
\$\begingroup\$

for the different matrix constructors: no it's easier to do a chained invocation matrix = Matrix4d.identity().rotateYaw(yaw).rotatePitch(pitch).translate(attachPoint);, and each of these rotate operations can be optimized (and the inverse calculated along side it)

the bottom (0 0 0 1) row can be optimized out easily by not even storing them (assume all matrices are homogenous) and using a more general algorithm for the perspective matrix of the camera

\$\endgroup\$
1
  • \$\begingroup\$ That's a good idea. I was keeping a full 4x4 matrix because I have functions to interface directly with OpenGL, but you are right, that stuff deserves specialised functions. Cheers. \$\endgroup\$
    – DaleyPaley
    Commented Jun 5, 2013 at 4:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .