We finished migrating from DirectXMath to the Eigen math libraries for our 3D-Game Engine last week for portability reasons. After implementing transformations with matrices as we know them, we found out about Eigen::Transform, which seemed like a really cool idea at the time.

Now, after a lot of fiddling things still don't quite work and we don't seem to have as much control over the way that Transformations are made. With Eigen::Matrix4f, you're making the multiplications directly and can change in which order they are made. Eigen::Transform appears to be way less transparent and flexible.

So we thought about reverting to our commits from last week, and head on to work with matrices again. But there are a few things we are concerned about:

  1. Saving things like translation in a 4x4 Matrix takes up more space than using Eigen::Translation

  2. Generating a new Matrix4f for the complete transformation every tick seems like a tedious process

So I wanted to know how Transform compares to regular Matrix4f in terms of speed and if my impression that Transform is not as flexible is actually true or not.

  • \$\begingroup\$ I would recommend you to do a benchmark for pure run-time performance. Personally I would use a Eigen::Transform if I start a new project and wouldn't bother to change if I already use 4×4 matrices. \$\endgroup\$ – Lærne May 1 '14 at 15:44
  • \$\begingroup\$ @Lærne For now we'll be rolling with matrices because we have more control over how they work, and understand them better. Also we kind of like euler angles, and if we decide to move to quaternions, that is easily doable. Benchmarks will probably be done in the future. \$\endgroup\$ – iFreilicht May 1 '14 at 18:53

Your first concern, regarding size(*), is a non-issue. You can note in the source that Eigen::Transform just stores a matrix of an appropriate size to transform a homogeneous coordinate in the specified dimensionality (that is, a 4x4 matrix for a 3D transformation). This appears to be because Transform is allowed to represent projections, rather than just translation/rotation/scale (which could be stored in few floats).

Your second concern, about generating a new matrix every update, is also a non-issue. Construction of a matrix in general shouldn't be that slow. Plus, you usually want to do this because persisting your transformation data (position, orientation and scaling) in different forms usually makes them easier to access and manipulate. For example, it's a lot easier to interpolate position and orientation and vectors and quaternions, respectively, than it is to try an interpolate a transformation matrix representing the combined operation.

Plus, due to floating point inaccuracies if you persist the transform as a matrix and constantly update into it, you can create rendering bugs as drift is introduced into what was originally (for example) a uniform scale portion of the matrix.

Eigen::Transform appears to exist main as a way to simplify the creation and usage of a matrix for many typical transformations. As with any such simplification, yes, it forces certain conventions on you. If those conventions don't work for you, you shouldn't use the class and should instead operate with the underlying matrices directly (which sounds like what you want to do in this case).

(*) Edit: I had assumed your reference to Eigen::Translation was a typo for Eigen::Transform, but when I went to confirm by browsing the source it turns out there is such a class. In this case, you are correct that the Translation class will be smaller than a full matrix.

  • \$\begingroup\$ Very nice answer! And thanks for pointing out the floating point issue, I did not think of that. Oh, and yes, you are right, I was talking about Eigen::Translation \$\endgroup\$ – iFreilicht May 14 '14 at 8:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.