-1

In my program I'm loading a cube from a GLTF file and display it using my own implementation of math objects like vectors, matrices, and quaternions.

That's what my program draws when I try to rotate the cube:

The X rotation:

enter image description here

and the Y rotation:

enter image description here

as you can see the Y rotation looks like if my cube was flat.

I tried to find the culprit but for now it eludes me. But I'm 100% sure that:

  • it is not the GLTF loader fault as my tests shows me the data for the cube is loaded right
  • it is not my math module fault as my tests again tell me the calculations are done right
  • it only happens when I try to rotate around Y and Z axis. The X axis rotation somehow doesn't have got this problem

The only thing that I'm not sure are shaders. But my shader code is the simplest possible:

#version 330 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;

uniform mat4 projection;
uniform mat4 view;

out vec3 fragNormal;
out float distance;

void main()
{
    gl_Position = projection * view * vec4(position, 1.0);
    vec4 tmp = view * vec4(position, 1.0);
    distance = tmp.z + 10.0;
    fragNormal = normal;
}
#version 330 core
in vec3 fragNormal;
in float distance;

out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f) * distance;
}

I really don't know where else could I look. Also, I wish to give you my code for the rest of my program, but at this point it would be plain impossible to put it in this post as my program has many lines of code.

So, how this error might happen?

EDIT:

My projection matrix is standard perspective with fov=45°, near=0.1, far=100.0 :

|1.29996 0 0 0 |
|0 2.41421 0 0 |
|0 0 -1.002 -0.2002 |
|0 0 -1 0 |

The view matrix changes: it is a translation matrix (x=0,y=0,z=-10) multiplied (from the right) with a rotation matrix (in the below listing around Y axis by some degree)

| 0.5 0 0 0 |
| 0 1 0 0 |
| -0.866026 0 0.5 -10 |
| 0 0 0 1 |

Rotation is taken from a quaternion, but it can also be calculated from a rotation matrix directly. The error happens no mater how I calculate the rotation matrix.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Felix.leg
  • 622
  • 1
  • 4
  • 13

1 Answers1

-2

I've found where lies the error: in the multiplication method of the matrix class. Somehow this code:

mat4 operator* (const mat4& other) const {
    T _c11 = c11 * other.c11 + c12 * other.c21 + c13 * other.c31 + c14 * other.c41;
    T _c12 = c11 * other.c12 + c12 * other.c22 + c13 * other.c32 + c14 * other.c42;
    T _c13 = c11 * other.c13 + c12 * other.c23 + c13 * other.c33 + c14 * other.c43;
    T _c14 = c11 * other.c14 + c12 * other.c24 + c13 * other.c34 + c14 * other.c44;
    
    T _c21 = c21 * other.c11 + c22 * other.c21 + c23 * other.c31 + c24 * other.c41;
    T _c22 = c21 * other.c12 + c22 * other.c22 + c23 * other.c32 + c24 * other.c42;
    T _c23 = c21 * other.c13 + c22 * other.c23 + c23 * other.c33 + c24 * other.c43;
    T _c24 = c21 * other.c14 + c22 * other.c24 + c23 * other.c34 + c24 * other.c44;
    
    T _c31 = c31 * other.c11 + c32 * other.c21 + c33 * other.c31 + c34 * other.c41;
    T _c32 = c31 * other.c12 + c32 * other.c22 + c33 * other.c32 + c34 * other.c42;
    T _c33 = c31 * other.c13 + c32 * other.c23 + c33 * other.c33 + c34 * other.c43;
    T _c34 = c31 * other.c14 + c32 * other.c24 + c33 * other.c34 + c34 * other.c44;
    
    T _c41 = c41 * other.c11 + c42 * other.c21 + c43 * other.c31 + c44 * other.c41;
    T _c42 = c41 * other.c12 + c42 * other.c22 + c43 * other.c32 + c44 * other.c42;
    T _c43 = c41 * other.c13 + c42 * other.c23 + c43 * other.c33 + c44 * other.c43;
    T _c44 = c41 * other.c14 + c42 * other.c24 + c43 * other.c34 + c44 * other.c44;
    
    return mat4{_c11, c12, c13, _c14, 
                _c21, _c22, _c23, _c24, 
                _c31, _c32, _c33, _c34,
                _c41, _c42, _c43, _c44};
}

wasn't working like this code:

mat4 operator* (const mat4& other) const {
    mat4<T> result;
    result.c11 = c11 * other.c11 + c12 * other.c21 + c13 * other.c31 + c14 * other.c41;
    result.c12 = c11 * other.c12 + c12 * other.c22 + c13 * other.c32 + c14 * other.c42;
    result.c13 = c11 * other.c13 + c12 * other.c23 + c13 * other.c33 + c14 * other.c43;
    result.c14 = c11 * other.c14 + c12 * other.c24 + c13 * other.c34 + c14 * other.c44;
    
    result.c21 = c21 * other.c11 + c22 * other.c21 + c23 * other.c31 + c24 * other.c41;
    result.c22 = c21 * other.c12 + c22 * other.c22 + c23 * other.c32 + c24 * other.c42;
    result.c23 = c21 * other.c13 + c22 * other.c23 + c23 * other.c33 + c24 * other.c43;
    result.c24 = c21 * other.c14 + c22 * other.c24 + c23 * other.c34 + c24 * other.c44;
    
    result.c31 = c31 * other.c11 + c32 * other.c21 + c33 * other.c31 + c34 * other.c41;
    result.c32 = c31 * other.c12 + c32 * other.c22 + c33 * other.c32 + c34 * other.c42;
    result.c33 = c31 * other.c13 + c32 * other.c23 + c33 * other.c33 + c34 * other.c43;
    result.c34 = c31 * other.c14 + c32 * other.c24 + c33 * other.c34 + c34 * other.c44;
    
    result.c41 = c41 * other.c11 + c42 * other.c21 + c43 * other.c31 + c44 * other.c41;
    result.c42 = c41 * other.c12 + c42 * other.c22 + c43 * other.c32 + c44 * other.c42;
    result.c43 = c41 * other.c13 + c42 * other.c23 + c43 * other.c33 + c44 * other.c43;
    result.c44 = c41 * other.c14 + c42 * other.c24 + c43 * other.c34 + c44 * other.c44;
    
    return result;
}

Probably I hit some compilator implementation detail.

Felix.leg
  • 622
  • 1
  • 4
  • 13
  • 1
    You are not using arrays but separate variable per matrix cell/element? That will bring you a lot of pain as you need to write a lot more code than necessary... here few examples of how I do it [ND math check the template version](https://stackoverflow.com/a/55439139/2521214) and [my GLSL math mimicking vec and mat in C++](https://ulozto.net/tamhle/Lac6wsTA65Ni#!ZJD0MwR2AJR0ZmR5LJAyZwHlLJH1MJyBAGL0I3MvJKDlF2L3LD==) for inspiration. **Btw the likely reason your first code does not work is when you are modifying the same matrix ... you overwriting one of the operands** – Spektre Feb 28 '22 at 22:33