Question

From the sources of android.opengl.Matrix.translateM(float[] m, int mOffset, float x, float y, float z):

/**
 * Translates matrix m by x, y, and z in place.
 * @param m matrix
 * @param mOffset index into m where the matrix starts
 * @param x translation factor x
 * @param y translation factor y
 * @param z translation factor z
 */
public static void translateM(
        float[] m, int mOffset,
        float x, float y, float z) {
    for (int i=0 ; i<4 ; i++) {
        int mi = mOffset + i;
        m[12 + mi] += m[mi] * x + m[4 + mi] * y + m[8 + mi] * z;
    }
}

The question is about this line (or the entire for-loop):

m[12 + mi] += m[mi] * x + m[4 + mi] * y + m[8 + mi] * z;

Why x, y and z components of translate parameters are multiplied to the source matrix components here? Shouldn't it be simple this (this lines replace the entire for-cycle):

m[12 + mi] += x;
m[13 + mi] += y;
m[14 + mi] += z;

Background of the problem:

I am doing some 2d game in OpenGL ES 2.0. I whant to scale and move some object there. While I simple move it:

Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, x, y, 0);

all goes fine. As soon as I do scaling before moving - at this time moving translations:

Matrix.setIdentityM(mModelMatrix, 0);
Matrix.scaleM(mModelMatrix, 0, xScaleFactor, yScaleFactor, 1);
Matrix.translateM(mModelMatrix, 0, x, y, 0);

are in fact multiplied by scaling :(

Was it helpful?

Solution

OpenGL is column-major, the proper order for Scaling, Rotation and Translation is actually Translation * Rotation * Scaling. In D3D and any row-major matrix library, Scale * Rotate * Translate would be correct. You have to think about things from right-to-left when you use column-major matrices.

Alternatively, you could transpose each matrix before multiplication - it is usually simpler just to follow the canonical order for column-major matrix multiplication though. Note that this applies to things like Position * Model * View * Projection (D3D / row-major) as well, in GL (column-major) the proper order is Projection * View * Model * Position.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top