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.
glm::vec4 is represented as a column vector. Therefore, the proper form is:
glm::vec4 result = m * v;
(note the order of the operands)
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).
Related
Edit: it is "backwards" to me - I may be missing some intuition
Given a glm transform function such as glm::translate, the two parameters are first a matrix m and then a vector v for translation.
Intuitively, I would expect this function to apply the translation "after" my matrix transform, i.e. multiplying an object by the returned matrix will first apply m followed by the translation v specified.
This intuition comes from the fact that one usually builds a transformation in mathmetical order e.g. first compute a scale matrix, then apply rotation, then transform etc. so I would think the function calling order would be the same (i.e. given a matrix, I can simply call glm::translate to apply a translation which happens after my matrix's transform is applied)
However, as mentioned in this thread, that is not the case - the translation is applied first, followed by the matrix m passed in.
I don't believe this has anything to do with column major/row major convention and notation as some threads suggest. Is there a historical reason for this? It just seems a bit backwards to me and I would probably rewrite the functions unless there's a good enough reason for it.
This intuition comes from the fact that one usually builds a transformation in mathmetical order
But there is no such thing as a mathematical order. Consider the following: v is an n-dimensional vector and M a n x n square matrix. Now the question is: which is the correct multiplication order? And that depends on your convention again. In most classic math textbook, vectors are defined as column vectors. And then: M * v is the only valid multiplication order, while v * M is simply not a valid operation mathematically.
If v is a column vector, then it's transpose v^T is a row vector and then v^T * M is the only valid multiplication order. However, to achieve the same result as before, say x = M * v, you have to also transpose M: x^T = v^T * M^T.
If M is the product of two matrices A and B, what we get here due to the non-commutative way of matrix multiplication is this:
x = M * v
x = A * B * v
x = A * (B * v)
or, we could say:
y = B * v
x = A * y
so clearly, B is applied first.
In the transposed convention with row matrices, we need to follow (A * B)^T = B^T * A^T and get
x^T = v^T * M^T
x^T = v^T * B^T * A^T
x^T = (v^T * B^T) * A^T
So B^T again is applied first.
Actually, when you consider the multiplication order, the matrix which is written closest to the vector is generally the one applied first.
I don't believe this has anything to do with column major/row major convention and notation as some threads suggest.
You are right, it has absolutely nothing to do with that. The storage order can be arbitrary and does not change the meaning of the matrices and operations. The confusion often comes from the fact that interpreting a matrix which is stored column-major as a matrix stored row-major (or vice-versa) will just have the effect of transposing the matrix.
Also, GLSL and HLSL and many math libraries do not use explicit column or row vectors, but use it as it fits. E.g., in GLSL you can write:
vec4 v;
mat4 M;
vec4 a = M * v; // v is treated as column vector here
vec4 b = v * M; // v is treated as row vector now
// NOTE: a and b are NOT equal here, they would be if b = v * transpose(M), so by swapping the multiplication order, you get the effect of transposing the matrix
Is there a historical reason for this?
OpenGL follows classical math conventions at many points (i.e. the window space origin is bottom-left and not top-left as most window systems do work), the old fixed function view space convention was to use a right-handed coordinate system (z pointing out of the screen towards the viewer, so the camera looking towards -z), and the OpenGL spec uses column vectors to this day. This means that the vertex transform has to be M * v and the "reverse" order of the transformations applies.
This means, in legacy GL, the following sequence:
glLoadIdentity(); // M = I
glRotate(...); // M = M * R = R
glTranslate(...); // M = M * T = R * T
will first translate the object, and then rotate it.
GLM was designed to follow the OpenGL conventions by default, and the function glm::mat4 glm::translate(glm::mat4 const& m, glm::vec3 const& translation); is explicitely emulating the old fixed-function GL behavior.
It just seems a bit backwards to me and I would probably rewrite the functions unless there's a good enough reason for it.
Do as you wish. You could set up fnctions which instead of psot-multiply do a pre-multiplication. Or you could set up all transformation matrices as transposed, and post-multiply in the order you consider "intuitive". But note that for someone following either classical math conventions, or typical GL conventions, the "backwards" notation is the "intuitive" one.
I'm learning about shader, and I've come across the following GLSL code:
vec3 color = cos(vec3(.5,.3,.4));
How do I compute the cosine of a vector vec3(.5,.3,.4)?
In GLSL most of the functions are overloaded and the argument can be a vector. Operations and functions may operate component wise. In case of cos, the cosine is computed for each component of the vector and the result is stored in a new vector:
The expression statement
vec3 color = cos(vec3(.5,.3,.4));
can be read as
vec3 color = vec3(cos(.5), cos(.3), cos(.4));
I can't use my matrix in my OpenGL shader; this is giving me an error:
glUniform4f(matLocation, mat[0], mat[1], mat[2], mat[3]); // glm mat4
no suitable conversion function from "glm::tvec4<float, glm::highp>" to "GLfloat" exists
I don't entirely understand why it's giving me this error message, and as usual, Googling doesn't give me any good results. Why would it want me to convert matrices to floats?
glUniform4f only updates a vec4 with four float values, so you need glUniformMatrix4fv which takes a pointer to an array of 16 float values glm can provide with glm::value_ptr.
mat[n] only yields the nth column, a vec4; thus the compilation error.
Im trying to understand how matrix transformations work in opengl/glsl, and Im wondering how to make a single 4x4 id-matrix that has the potential for every scale/rotation/translation.
So, after all the binding and whatnot, im only uniform/inputting 1 matrix to designate its location/spin.
This idea seems correct to me, but I cant figure out how to make the object move without distorting it. It rotates just fine, and it scales as well.
But idk how to apply the translation to the id matrix, if that makes sense. In any case, this is my relevant code:
//update matrix
glUniformMatrix4fv(transform, 1, GL_FALSE, glm::value_ptr(ident));
//spin according to z
void object::spinz(float a) { ident = glm::rotate(ident, a, glm::vec3(0.0f, 0.0f, 1.0f)); }
this will modify my
glm::mat4 ident();//id matrix
but when i try giving it translation:
void object::translate(float x, float y, float z);
the method itself will only distort the object/matrix/result
ident += glm::vec4(x, y, z, 0);
what am I doing wrong? Should I even try to only have 1 uniform input?
Solution: the idea for translation is just wrong. A correct one would look more like this: (but the main thing is doing it seperately for each object)
glm::mat4 test = glm::translate(glm::mat4(1.0f), glm::vec3(x, y, z));
finaluniformmatrix *= test;
Or basically make a unique translation matrix, that I then multiply with the overall projection*view matrix.
edit: a cheaper translation is:
matrix[3][0]=x;matrix[3][1]=y;matrix[3][2]=z; //where xyz are xyz coordinates.
ps: why am I getting downvotes for this? This is me finding out (some time ago) that you need a unique identity matrix for rendering seperate objects, and not just the same matrix for everything. (like mixing up projection, view, identity, by adding them for each object)
You can use a number of individual matrix operations, and multiply them together to turn them in to a single matrix that specifies the entire operation. Any number of 4x4 matrices can be multiplied and the order IS important.
Also be wary of non uniform scale and rotation, which can sometimes have the effect of "sheering" the object.
You can fairly simply build translation, rotation-x, rotation-y, rotation-z and scale 4x4 matrices and multiply them together to create a single matrix.
http://www.flipcode.com/documents/matrfaq.html#Q11
http://www.flipcode.com/documents/matrfaq.html#Q41
I'm not sure about the code you are using tho - I'd suggest only using 4x4 matrix and multiply operations to begin with and work from there.
I want to extract the three first values of a Vector4 type in Eigen, into a Vector3 type. So far I am doing it in a for-loop. Is there a smarter way to do it?
The .head() member function returns the first n elements of a vector. If n is a compile-time constant, then you can use the templated variant (as in the code example below) and the Eigen library will automatically unroll the loop.
Eigen::Vector4f vec4;
// initialize vec4
Eigen::Vector3f vec3 = vec4.head<3>();
In the Eigen documentation, see Block operations for an introduction to similar operations for extracting parts of vectors and matrices, and DenseBase::head() for the specific function.
The answer of #Jitse Niesen is correct. Maybe this should be a comment on the original question, but I found this question because I had some confusion about Eigen. In case the original questioner, or some future reader has the same confusion, I wanted to provide some additional explanation.
If the goal is to transform 3d (“position”) vectors by a 4x4 homogeneous transformation matrix, as is common in 3d graphics (e.g. OpenGL etc), then Eigen provides a cleaner way to do that with its Transform template class, often represented as the concrete classes Affine3f or Affine3d (as tersely described here). So while you can write such a transform like this:
Eigen::Matrix4f transform; // your 4x4 homogeneous transformation
Eigen::Vector3f input; // your input
Eigen::Vector4f input_temp;
input_temp << input, 1; // input padded with w=1 for 4d homogeneous space
Eigen::Vector4f output_temp = transform * input_temp;
Eigen::Vector3f output = output_temp.head<3>() / output_temp.w(); // output in 3d
You can more concisely write it like this:
Eigen::Affine3f transform; // your 4x4 homogeneous transformation
Eigen::Vector3f input; // your input
Eigen::Vector3f output = transform * input;
That is: an Eigen::Affine3f is a 4x4 homogeneous transformation that maps from 3d to 3d.
Yeah, because you know the size is static (3 elements) you should unroll the loop and copy them explicitly. This optimization might be performed by the compiler already, but it can't hurt to do it yourself just in case.