The little coordinate system reference

I’ve been implementing an FBX 3d file format loader for bevy, and currently the most challenging part of it has been figuring out coordinate system transitions.

I’m having a lot of trouble using search engines to find references online, so I’m creating my own. Here it is: the most exhaustive reference (with pictures!) on how to convert between coordinate systems.

If you finish reading this without an answer to those 3 questions, I’m a twat.

What’s a coordinate system?

A game engine, a modelling software, or any 3D game work in 3D space. To locate something in 3D space, you need some sort of information or data. The position data is called a “coordinate”, and in 3 dimension, it is divided in 3 different scalar1 values, also called components. Software most often use the standard basis as coordinates. Each component answer the question: “how many step in this basis direction do you have to make to reach the coordinate position?” The basis of 3D space are X, Y and Z. We all agree on that. However, it turns out, beyond that, no one agrees on anything.

What are the differences between coordinate systems in different software?

You might be interested in this link as a reference of which software uses which coordinate system.

Beyond X Y and Z, you need to find what they represent. On a whiteboard, you generally draw the X axis from left to right and the Y axis bottom up.

A 2d axis drawn on a whiteboard

While, when drawing on a piece of paper on your desk, the X axis goes to the right and the Y axis forward.

Each software is free to chose what axis is up. Usually, Y is up, like on the whiteboard. But after choosing what “up” is, there is the question of choosing what is “forward” (goes out of the whiteboard perpendicularly) and what goes in the other direction of the whiteboard. (on the whiteboard, it was X)

The left/right-handed coordinate system

(If you are reading this in a public place, you may look silly while reading this section.)

To answer this question, some people use the “left/right-handed” description. Take your hands, and point your thumb, your index and middle fingers outward. In the left/right-handed system, the thumb is X, the index is Y and middle finger Z. You’ll notice that regardless of how you spin your hands, the outward fingers of both hands won’t ever go in the same direction. They may at one point end up on the same axises, but they won’t point in the same direction.

I embedded an interactive demo, which source code is available here.

The left gizmo is left-handed, while the right gizmo is right-handed. The red ball is +X, the green ball is +Y and the blue ball +Z.

(may be slightly broken on mobile)

And here is a table showing all 6 possible coordinate systems:

How to convert between coordinate systems?

Now, if you ever imported or exported a 3D model from one program to another, you probably got the opportunity to see first-hand that indeed not all software use the same coordinate system.

If you don’t want to manually rotate all the models you are importing, you gotta use some math.

It’s actually quite simple. Find in the previous table the cell with the expected coordinate, and the cell with the actual coordinates. Then write down the “up”, “forward” and “right” axis of the actual coordinates in a column on paper. Then write down the expected coordinates in a column to the right. If you expected left-handed Y up, and got right-handed Z up, it should look like this now:

  top     Z  →  Y
  forward Y  →  Z
  right   X  →  X

This means you need to go from (x,y,z) to (x,z,y), which means that your need to swap your Z and Y axis.

With matrices

You can do it with vector swizzles, but you may also want a transform. I’m not going to give rotation keys here, because I’m as clueless as you. But your software’s API let you probably create a transform based on a matrix.

A matrix is an operation on vectors, to go from one 3D vector to another 3D vector, you need a 3x3 matrix.

The kind of matrix we need is a rotation matrix, that rotates at exactly 90 degree angles.

You can think of a matrix as a table, where the columns are the “from position” and the rows the “to position”.

   fx fy fz
tx  1, 0, 0
ty  0, 1, 0
tz  0, 0, 1

So for our right-handed Z up to left-handed Y up, conversion from earlier, we would need the following matrix:

    1  0  0
    0  0  1
    0  1  0

1 scalar just means “a single number”, here we often use rational numbers,
or “float” in computer jargon.

2 A 3x3 matrix has 9 components, 3 columns and 3 rows.

Whiteboard image courtesy of geralt on pixabay.