Bug in raymath.h ( raylib 1.7 )

for opengl column major matrices this function is wrong , ( your declaration of Matrix struct is ok )

RMDEF Matrix MatrixTranslate(float x, float y, float z)
{
Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
x, y, z, 1.0f };

return result;
}

it should be

RMDEF Matrix MatrixTranslate(float x, float y, float z)
{
Matrix result = { 1.0f, 0.0f, 0.0f, x,
0.0f, 1.0f, 0.0f, y,
0.0f, 0.0f, 1.0f, z,
0.0f, 0.0f, 0.0f, 1.0f };

return result;
}

I was doing this lesson :
https://learnopengl.com/#!Getting-started/Transformations
( In practice part )

Vector3 vec = {1.0, 0, 0};
Matrix mat = MatrixTranslate(1.0, 1.0, 0);
VectorTransform(&vec, mat);
printf("x = %f y = %f z = %f\n", vec.x, vec.y, vec.z);

my result was
vec.x = 1.0
vec.y = 0.0
vec.z = 0.0

his vector
vec.x = 2.0
vec.y = 1.0
vec.z = 0.0

so I dig a little and find that little bug , after corection result is identical
vec.x = 2.0
vec.y = 1.0
vec.z = 0.0

thx...




Comments

  • ok I just realised that there is a MatrixTranspose function so
    maybe( probably ) no bug at all , no need for change x,y,z elements to last column,
    new code snipet is :

    Vector3 vec = {1.0, 0, 0};

    Matrix mat = MatrixTranslate(1.0, 1.0, 0);
    MatrixTranspose(&mat);

    VectorTransform(&vec, mat);

    printf("x = %f y = %f z = %f\n", vec.x, vec.y, vec.z);

    with correct output:

    x = 2.0 y = 1.0 z =0.0

    but why then Matrix struct is column major and what is the right math order
    when dealing with matrices ?

    btw I am using raymath.h as standalone header
  • Hello dancho!

    Thank you very much for the feedback and thanks for your tests. Actually, there is a related issue on raylib github: https://github.com/raysan5/raylib/issues/291

    https://learnopengl.com/#!Getting-started/Transformations is agreat reference to start with matrix math, and there are correct on the math. But the current implementation of all that math is done using GLM math library, a bigger and more complex math library than raymath.

    So, what's the difference? Well, it's a matter of how actual data is aligned in memory. My matrix struct is defined as "column-major", at least that's the convention but the truth is that Matrix is just a vector like: m0, m4, m8, m12, m1, m5, m9, m13, m2, m6, m10, m14, m3, m7, m11, m15;

    For that reason, all transformations should be transposed to get back the right Matrix in raymath form.

    Please, correct me if I'm wrong. Maybe after dealing a lot with Matrix I just messed things up...



  • hey raysan,
    it may be a good idea to put some notification in the header file about this or in the wiki , I was aware that matrix struct is column major and so I assumed that matrices math is based on that convetion but math in the raymath is row orientation ,
    ( nothing wrong with that , the result is same , just maybe some consistently between matrix struct and functions on memory layout )...
    and one should be aware of this when sending matrix to shader...
    so I will continue with learnopengl tutorials ( as my free time allows me ) and report here any issues...

    thx
  • hey raysan,
    there are couple more quirks in the coordinate systems lesson,
    ( btw he is using right - hand system as default )

    his model matrix ( c++ with glm )
    glm::mat4 model;
    model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));

    so model is rotated around x and tilted back ( notice minus 55.0f)

    model matrix in c with raymath
    Matrix model = MatrixRotate((Vector3){1.0f, 0, 0}, 55.0f * DEG2RAD);

    so I have to drop minus of the rotation angle for the model to
    be tilted back to -z axis otherwise ( with minus ) it would tilt forward...

    projection matrix in c with raymath
    Matrix projection = MatrixPerspective(45.0f, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1, 100.0);
    MatrixTranspose(&projection);
    shaderSetMatrix(basicShader, "projection", MatrixToFloat(projection));

    first, it would be useful to know if the fov has to be in rad or in deg without to look in function declaration ( so all angles have to be one or other type ),
    second, projection matrix is transposed twice to make this lesson to work,
    with MatrixTranspose and MatrixToFloat functions,
    ( and I have to guessing that ) ,
    so maybe you should review the way raymath is organised ( with Victor maybe , he is pro ) , because the result of the math is good , but path to there is sometimes confusing...

    thx

  • Thank you very much for pointing all those quirks... Ill try to review raymath for next raylib 1.8.
  • All raymath has been reviewed, no more transposing required and math seem way more consistent now. Implemented in commit: https://github.com/raysan5/raylib/commit/e52032f64660008fdcf0c8d707ef6aed1e6fc32f

    Still some issues with GetMouseRay() result of the changes... hope to address it soon.

    Please, let me know if you try raymath as standalone library! :)
Sign In or Register to comment.