# [ODE] Are the rotation matrices returned by dBodyGetRotation Column or row major

Jon Watte (ODE) hplus-ode at mindcontrol.org
Tue Oct 30 10:03:55 MST 2007

```Yeah, that's good. "Row vector" vs "Column vector" is an age-old
computer graphics question (kind of like left-handed vs right-handed).
In "pure math" and most mechanics texts, you'll find that the vector
goes on the right of the matrix, as a column. Matrices are then applied
to the vector right-to-left. Thus, the expression:

P R S v

This would apply first a scale to v, then a rotation to v, then a
position (translation) to v. In this notation, the translation
components of a matrix live in the fourth column (because matrices are
multiplied row-into-column).

In historical computer graphics, including DirectX, the vector instead
goes on the left, as a row vector (row into column). The same expression

v S R P

This means that the vertex v is first scaled, then rotated, then
translated. In this case, the translation part lives in the fourth row.

Both OpenGL and DirectX expect the matrix to contain the translation
values in offsets 12, 13 and 14 in memory, though (for a 4x4 matrix), so
this difference in convention is often lost on people who are not paying
attention, because in-memory layout "works." This is because DirectX
uses row major matrices, and OpenGL uses column major matrices, so the
storage conventions "cancel out" for a single matrix (but the ordering
convention is still different).

ODE, on the other hand, doesn't have a specified ordering, although it
seems column vector on left when you read it. However, in that case, ODE
is row major, so the memory layout is the transpose of how both OpenGL
and DirectX expect the matrix in memory.

See, another question for the FAQ :-)

Cheers,

/ h+

Remi Ricard wrote:
> Hi Jon,
>
>> That depends on whether you consider yourself row vector, or column
>> vector, convention.
>>
>> The matrix is actually a 3x4 matrix, with the fourth values being
>> undefined. Those four values live at offset 3, 7 and 11 when indexed
>> as an array, and would contain the translation values if the matrix
>> was a "real" 3x4.
>>
>> If you consider yourself column vector on the right, it will return
>> ABCxDEFyGHIz, which is row major, which is the reverse of what you'd
>> use in OpenGL (which is also column vector on the right).
>> If you consider yourself row vector on the left, it will return
>> ADGxBEHyCFIz, which is column major, which is the reverse of what
>> you'd use in DirectX (which is also row vector on the left).
>>
>> I don't know how many times I've explained this on this list -- can
>> someone who knows how to update the documentation please copy & paste
>> the question and explanation to the introductory chapter of the docs?
>>
>
>
> Can you verify it everything is OK
>
> Since I'm not sure what you mean by right of left.
>
> Remi
>
>
>
```