I’m writing a small matrix library to understand matrix transformations. Everything is working well up to the point where I translate THEN scale - the polygons seem to not get scaled “in place”, because translations are being done before scaling. This is the correct behavior for the matrix operations, but I want to create a function that lets me scale “in place”.
Is there some way to have transformations applied to an object work in its own local coordinate system? For example:
class Polygon {
Matrix4x4 m_lcl; // relative matrix?
ApplyTransform(Matrix4x4 m)
{
// Somehow manipulate the input matrix
// so it works "in place"?
}
I would, but I can’t figure out how to do just that -
I’m binding my left mouse click to a transform matrix of (5,5,0), and my right mouse click to a scale of (3,3,0). So when I left mouse click a few times, my vertices are already translated - then when I right click, the scale is applied but it’s already been affected by the translation -
Now that I think about it again, should I do something like this:
class Polygon {
Vertex m_vertices[n];
Matrix m_matrix;
ApplyTranslate(Matrix m)
{
// Post multiply? Translations always at the back?
m_matrix = m_matrix * m;
}
ApplyRotate(Matrix m)
{
// Pre multiply? Rotations always at the front?
m_matrix = m * m_matrix;
}
ApplyScale(Matrix m)
{
// Pre multiply? Scales always at the front?
m_matrix = m * m_matrix;
}
};
Is that what you mean? Therefore translation multiplications are always done at the end?
^Just so. Using the homogeneous coordinate representation of translations, you can even combine all three steps into a single matrix easily enough, effectively getting what you’re looking for.
If you set up transformations so that the new coordinate system axes are stored as columns then you have do the vertex transformation as M * v, v being a column vector representing the vertex position.
In this case if you combine some matrices they will be applied in reverse order. E.g. M = S * T will result in the translation being done before the scale, i.e. the translation will get scaled as well.
This is the way OpenGL does it, so you better use this if you want to be consistent. OpenGL also normally expects matrices in column-major order in memory (i.e. as a series of column vectors), which is an entirely separate issue.
You can also do it the other way round, storing the axes as rows of the matrix. In this case all the multiplications need to be reversed, i.e. you use v * M, and if you want to translate then scale you use M = T * S.