26

I have a transformation matrix, m, and a vector, v. I want to do a linear transformation on the vector using the matrix. I'd expect that I would be able to do something like this:

glm::mat4 m(1.0);
glm::vec4 v(1.0);

glm::vec4 result = v * m;

This doesn't seem to work, though. What is the correct way to do this kind of operation in GLM?

Edit:

Just a note to anyone who runs into a similar problem. GLM requires all operands to use the same type. Don't try multiplying a dvec4 with a mat4 and expect it to work, you need a vec4.

Ziezi
  • 6,375
  • 3
  • 39
  • 49
n s
  • 1,361
  • 2
  • 12
  • 24
  • @Nicol Bolas: Why did you get rid of the GLM tag? That seems more relevant than the OpenGL one. – andand Sep 27 '11 at 19:20
  • 2
    @andand: Because the GLM he's talking about is a specific library, not "generalized linear models". But I also removed the OpenGL tag. – Nicol Bolas Sep 27 '11 at 19:26

2 Answers2

38

glm::vec4 is represented as a column vector. Therefore, the proper form is:

glm::vec4 result = m * v;

(note the order of the operands)

andand
  • 17,134
  • 11
  • 53
  • 79
  • I have tried it that way as well, and there is no difference. gcc is telling me that there is no matching * operator that takes a matrix and a vector. – n s Sep 27 '11 at 19:59
  • 1
    Nevermind, the problem was that I was trying to multiply a float-based matrix with a double-based vector, which GLM doesn't like. Thanks for your help. – n s Sep 27 '11 at 20:03
  • but what is the expected behavior of `v * m`? glm does allow 3x1 to multiply 3x3... – Summer Sun Oct 08 '19 at 11:35
  • Not sure... I haven't tried it. You could do so and see what happens. But my guess is that since such a multiplication is mathematically nonsensical, the GLM developers are under no obligation to have it operate in a predictable or defined way. – andand Oct 09 '19 at 04:04
  • may I get an explanation why you need to have the ( mat * vec ) vs ( vec * mat ) to work correctly? – killer Nov 17 '19 at 21:07
  • 1
    @killer Matrix multiplication is not commutative. The glm developers chose to orient the matrices such that the transformation is on the LHS of the * operator while the vector(s) to which the transformation applies is on the RHS of the * operator. In theory, they could have defined it the other way, though there's a convention in linear algebra to do it this way. They also could have tried to write the code to figure it out based on the location of the vector and then morph the matrix so things work correctly, but this would likely have resulted in a substantial performance hit. – andand Nov 17 '19 at 23:12
  • 1
    @killer A more complete description of the math behind this is available at https://en.wikipedia.org/wiki/Matrix_multiplication – andand Nov 17 '19 at 23:17
  • the order has to be this way because the matrix is 4x4 and the column vector is 4x1 (column-major so counts rows in each column first) such that we have inner dimen match (4 matrix columns x 4 vector rows) making the matrix multiplication possible and the output would be 4 rows x 1 column vector, correct? – CCJ Jul 21 '20 at 21:53
11

Since GLM is designed to mimic GLSL and is designed to work with OpenGL, its matrices are column-major. And if you have a column-major matrix, you left-multiply it with the vector.

Just as you should be doing in GLSL (unless you transposed the matrix on upload).

GraphicsMuncher
  • 4,583
  • 4
  • 35
  • 50
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • I don't think that this terminology is correct. Row/column majority is a computational term that reflects grouping of memory ranges. It has nothing to do with algebra – johannes_lalala Jan 18 '22 at 02:14
  • @johannes_lalala A^T * v^T = u^T <- column major v * A = u <- row major You get the same results, you just work with the transpositions of the original vectors and matrices – Maksymilian K Nov 05 '22 at 14:49
  • @MaksymilianK I understand what the answer is trying to say. It's just that it doesn't distinguish 'row' and 'row major'. These are different concepts. In math, there is no 'major', just rows and columns. The sentence "if you have a column-major matrix, you left-multiply it with the vector." doesn't make any sense from a math perspective and is wrong from a computer-library perspective. What matters here is not how the matrix is stored in memory, but that glm vectors always denote columns. – johannes_lalala Nov 07 '22 at 00:10