Rotation around axis other than X makes 3D object flat - c++

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:
and the Y rotation:
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.

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.

Related

OpenGL Triangle pipe around line segment

I would like to ask how can I render in geometry shader a triangle pipe from a line segment?
I first compute perpendicular vector "perp" to the line vector "axis".
Then I rotate the "perp" vector few times by "rotate" function.
Since mesh is composed from 8 vertices I am trying to use "triangle_strip".
My current code :
#version 330 core
layout (lines) in;
layout(triangle_strip, max_vertices = 8) out;//triangle_strip
uniform float u_thickness ;
uniform vec2 u_viewportSize ;
uniform bool u_scale_width_by_zoom ;
in gl_PerVertex
{
vec4 gl_Position;
//float gl_PointSize;
//float gl_ClipDistance[];
} gl_in[];
vec4 rotate(vec4 p, float x, float y, float z,float angle )
{
vec3 q;
q[0] = p[0] * (x*x * (1.0 - cos(angle)) + cos(angle))
+ p[1] * (x*y * (1.0 - cos(angle)) + z * sin(angle))
+ p[2] * (x*z * (1.0 - cos(angle)) - y * sin(angle));
q[1] = p[0] * (y*x * (1.0 - cos(angle)) - z * sin(angle))
+ p[1]* (y*y * (1.0 - cos(angle)) + cos(angle))
+ p[2] * (y*z * (1.0 - cos(angle)) + x * sin(angle));
q[2] = p[0] * (z*x * (1.0 - cos(angle)) + y * sin(angle))
+ p[1] * (z*y * (1.0 - cos(angle)) - x * sin(angle))
+ p[2] * (z*z * (1.0 - cos(angle)) + cos(angle));
return vec4(q, 0.0);
}
void main() {
//https://stackoverflow.com/questions/54686818/glsl-geometry-shader-to-replace-gllinewidth
vec4 p1 = gl_in[0].gl_Position;
vec4 p2 = gl_in[1].gl_Position;
//tube
// Specify the axis to rotate about:
vec4 axis = p2-p1;
float x = axis[0];
float y = axis[1];
float z = axis[2];
axis = normalize(axis);
//float length = hypotf(axis[0], hypotf(axis[1], axis[2]));
float length = sqrt((axis[0]*axis[0]) + sqrt(axis[1]*axis[1]+ axis[2]*axis[2]));
float dir_scalar = (axis[0] > 0.0) ? length : -length;
float xt = axis[0] + dir_scalar;
float dot = -axis[1] / (dir_scalar * xt);
vec3 perp_0 = vec3(dot * xt, 1.0f + dot * axis.y, dot * axis.z);
perp_0 = normalize(perp_0);
vec4 perp = vec4(perp_0,0)*u_thickness*0.001;
//side0
vec4 p1_1 = p1+perp;
vec4 p1_2 = p2+perp;
vec4 perp_rot_2=rotate(perp,x,y,z,60.0 * 3.14 / 180.0);
vec4 p2_1 = p1+perp_rot_2;
vec4 p2_2 = p2+perp_rot_2;
vec4 perp_rot_3=rotate(perp,x,y,z, 120.0 * 3.14 / 180.0);
vec4 p3_1 = p1+perp_rot_3;
vec4 p3_2 = p2+perp_rot_3;
gl_Position = p1_1;
EmitVertex();
gl_Position = p1_2;
EmitVertex();
gl_Position = p2_1;
EmitVertex();
gl_Position = p2_2;
EmitVertex();
gl_Position = p3_1;
EmitVertex();
gl_Position = p3_2;
EmitVertex();
gl_Position = p1_1;
EmitVertex();
gl_Position = p1_2;
EmitVertex();
EndPrimitive();
}
It produces wrong results:

Issue with 3d rotation along the X axis

I'm working on a project that required a 3d cube to be rotated along 3 axes. The cube is made up of 12 triangles, each with an instance of the Triangle class. Each triangle has a p0, p1, and p2 with the type sf::Vector3f. The triangles also have a float* position and a float* rotation. The position and rotation of a triangle is updated using this method.
void Triangle::update() {
position;
p0 = originalP0;
p1 = originalP1;
p2 = originalP2;
sf::Vector3f rotatedP0;
sf::Vector3f rotatedP1;
sf::Vector3f rotatedP2;
// along z
rotatedP0.x = p0.x * cos((*rotation).z * 0.0174533) - p0.y * sin((*rotation).z * 0.0174533);
rotatedP0.y = p0.x * sin((*rotation).z * 0.0174533) + p0.y * cos((*rotation).z * 0.0174533);
rotatedP0.z = p0.z;
rotatedP1.x = p1.x * cos((*rotation).z * 0.0174533) - p1.y * sin((*rotation).z * 0.0174533);
rotatedP1.y = p1.x * sin((*rotation).z * 0.0174533) + p1.y * cos((*rotation).z * 0.0174533);
rotatedP1.z = p1.z;
rotatedP2.x = p2.x * cos((*rotation).z * 0.0174533) - p2.y * sin((*rotation).z * 0.0174533);
rotatedP2.y = p2.x * sin((*rotation).z * 0.0174533) + p2.y * cos((*rotation).z * 0.0174533);
rotatedP2.z = p2.z;
p0 = rotatedP0;
p1 = rotatedP1;
p2 = rotatedP2;
// along y
rotatedP0.x = p0.x * cos((*rotation).y * 0.0174533) + originalP0.z * sin((*rotation).y * 0.0174533);
rotatedP0.y = p0.y;
rotatedP0.z = p0.x * -sin((*rotation).y * 0.0174533) + originalP0.z * cos((*rotation).y * 0.0174533);
rotatedP1.x = p1.x * cos((*rotation).y * 0.0174533) + originalP1.z * sin((*rotation).y * 0.0174533);
rotatedP1.y = p1.y;
rotatedP1.z = p1.x * -sin((*rotation).y * 0.0174533) + originalP1.z * cos((*rotation).y * 0.0174533);
rotatedP2.x = p2.x * cos((*rotation).y * 0.0174533) + originalP2.z * sin((*rotation).y * 0.0174533);
rotatedP2.y = p2.y;
rotatedP2.z = p2.x * -sin((*rotation).y * 0.0174533) + originalP2.z * cos((*rotation).y * 0.0174533);
p0 = rotatedP0;
p1 = rotatedP1;
p2 = rotatedP2;
// along x
rotatedP0.x = p0.x;
rotatedP0.y = p0.y * cos((*rotation).x * 0.0174533) - p0.z * sin((*rotation).x * 0.0174533);
rotatedP0.z = p0.y * sin((*rotation).x * 0.0174533) + p0.z * cos((*rotation).x * 0.0174533);
rotatedP1.x = p1.x;
rotatedP1.y = p1.y * cos((*rotation).x * 0.0174533) - p1.z * sin((*rotation).x * 0.0174533);
rotatedP1.z = p1.y * sin((*rotation).x * 0.0174533) + p1.z * cos((*rotation).x * 0.0174533);
rotatedP2.x = p2.x;
rotatedP2.y = p2.y * cos((*rotation).x * 0.0174533) - p2.z * sin((*rotation).x * 0.0174533);
rotatedP2.z = p2.y * sin((*rotation).x * 0.0174533) + p2.z * cos((*rotation).x * 0.0174533);
p0 = rotatedP0 + *position;
p1 = rotatedP1 + *position;
p2 = rotatedP2 + *position;
}
This method works well for all axes except the X axis. The cube has two red faces intersecting the Z axis, two green faces intersecting the Y axis, and two blue faces intersecting the X axis. Rotating the cube along the Z and Y axes works fine. The cube is rotating around the red and green faces. When rotating along the X axis, the cube is not rotated around the blue faces, but rather the global X axis.
Am I doing something wrong? Is it supposed to be this way? Is there any way to fix it? I searched all over and couldn't find anything helpful.
bro you did it all wrong. use this 3D point rotation algorithm. i know it is javascript but the math still the same

Most accurate way to calculate view frustum corners in world space

I'm trying to calculate the view frustum corners in world space. I've implemented it by using the FOV and using the width/height of the planes and some vector math
However, a lot of examples simply state that you can multiply a NDC corner like (1,1,1) by the inverse viewProjection matrix. But when I do this I get somewhat different results. This is the code I'm using right now to test things:
float nearHeight = 2 * tan(mFOV / 2) * mNear;
float nearWidth = mNear * mRatio;
float farHeight = 2 * tan(mFOV / 2) * mFar;
float farWidth = mFar * mRatio;
glm::vec3 fc = mPos + mFront * mFar;
glm::vec3 nc = mPos + mFront * mNear;
mFrustum.frustumCorners[0] = fc + (mUp * farHeight / 2.0f) - (mRight * farWidth / 2.0f);
mFrustum.frustumCorners[1] = fc + (mUp * farHeight / 2.0f) + (mRight * farWidth / 2.0f);
mFrustum.frustumCorners[2] = fc - (mUp * farHeight / 2.0f) - (mRight * farWidth / 2.0f);
mFrustum.frustumCorners[3] = fc - (mUp * farHeight / 2.0f) + (mRight * farWidth / 2.0f);
mFrustum.frustumCorners[4] = nc + (mUp * nearHeight / 2.0f) - (mRight * nearWidth / 2.0f);
mFrustum.frustumCorners[5] = nc + (mUp * nearHeight / 2.0f) + (mRight * nearWidth / 2.0f);
mFrustum.frustumCorners[6] = nc - (mUp * nearHeight / 2.0f) - (mRight * nearWidth / 2.0f);
mFrustum.frustumCorners[7] = nc - (mUp * nearHeight / 2.0f) + (mRight * nearWidth / 2.0f);
glm::vec4 test(1.0f, 1.0f, 1.0f,1.0f);
glm::vec4 test2(-1.0f, -1.0f, -1.0f, 1.0f);
glm::mat4 testingMatrix = glm::inverse(mProjectionMatrix * getViewMatrix());
test = testingMatrix*test;
test2 = testingMatrix*test2;
test2.x /= test2.w;
test2.y /= test2.w;
test2.z /= test2.w;
test.x /= test.w;
test.y /= test.w;
test.z /= test.w;
Now both of these results give an accurate z value for [near,far] = [1, 10000] but the x values are off by quite a bit while the y values are pretty much the same. I was just wonder which way is the most accurate one?
Inverse viewProjection
Regular calculation

OpenGL Matrix Multiplication C++

So I am trying to multiply rotation and translation matrices together and I can't quite figure out what is going wrong.
If, in the program I multiply a translation matrix by a rotation matrix then send that matrix as a uniform to my shader program I end up with the object becoming 2D then 3D again as it spins [ https://a.pomf.se/xvvrsg.mp4 ] (object on the right).
shader.setUniformMat4("model_matrix", Matrix4::translation(Vector3(10.0f, 0.0f, 0.0f)) * Matrix4::rotation(rotation, Vector3(0.0f, 1.0f, 0.0f)));
(vertex shader)
#version 330 core
layout (location = 0) in vec4 in_position;
layout (location = 1) in vec4 in_normal;
uniform mat4 pr_matrix;
uniform mat4 vw_matrix = mat4(1.0);
uniform mat4 model_matrix = mat4(1.0);
out vec4 pos;
out vec4 normal;
void main()
{
pos = pr_matrix * vw_matrix * model_matrix * in_position;
normal = in_normal;
gl_Position = pos;
}
However if I send my individual translation and rotation matrices as separate uniforms and then multiply them in the shader to create my model matrix it works as intended [ https://a.pomf.se/jyxpnb.mp4 ] (object on the right).
shader.setUniformMat4("translation_matrix", Matrix4::translation(Vector3(10.0f, 0.0f, 0.0f)));
shader.setUniformMat4("rotation_matrix", Matrix4::rotation(rotation, Vector3(0.0f, 1.0f, 0.0f)));
shader.setUniformMat4("scale_matrix", Matrix4::identity());
(vertex shader)
#version 330 core
layout (location = 0) in vec4 in_position;
layout (location = 1) in vec4 in_normal;
uniform mat4 pr_matrix;
uniform mat4 vw_matrix = mat4(1.0);
uniform mat4 translation_matrix = mat4(1.0);
uniform mat4 rotation_matrix = mat4(1.0);
uniform mat4 scale_matrix = mat4(1.0);
out vec4 pos;
out vec4 normal;
void main()
{
mat4 model_matrix = translation_matrix * rotation_matrix * scale_matrix;
pos = pr_matrix * vw_matrix * model_matrix * in_position;
normal = in_normal;
gl_Position = pos;
}
This leads me to believe that there must be an error in my multiplication of matrices, this is how I am currently doing it:
Matrix4 &Matrix4::multiply(const Matrix4 &other)
{
elements[0] = elements[0] * other.elements[0] + elements[4] * other.elements[1] + elements[8] * other.elements[2] + elements[12] * other.elements[3];
elements[1] = elements[1] * other.elements[0] + elements[5] * other.elements[1] + elements[9] * other.elements[2] + elements[13] * other.elements[3];
elements[2] = elements[2] * other.elements[0] + elements[6] * other.elements[1] + elements[10] * other.elements[2] + elements[14] * other.elements[3];
elements[3] = elements[3] * other.elements[0] + elements[7] * other.elements[1] + elements[11] * other.elements[2] + elements[15] * other.elements[3];
elements[4] = elements[0] * other.elements[4] + elements[4] * other.elements[5] + elements[8] * other.elements[6] + elements[12] * other.elements[7];
elements[5] = elements[1] * other.elements[4] + elements[5] * other.elements[5] + elements[9] * other.elements[6] + elements[13] * other.elements[7];
elements[6] = elements[2] * other.elements[4] + elements[6] * other.elements[5] + elements[10] * other.elements[6] + elements[14] * other.elements[7];
elements[7] = elements[3] * other.elements[4] + elements[7] * other.elements[5] + elements[11] * other.elements[6] + elements[15] * other.elements[7];
elements[8] = elements[0] * other.elements[8] + elements[4] * other.elements[9] + elements[8] * other.elements[10] + elements[12] * other.elements[11];
elements[9] = elements[1] * other.elements[8] + elements[5] * other.elements[9] + elements[9] * other.elements[10] + elements[13] * other.elements[11];
elements[10] = elements[2] * other.elements[8] + elements[6] * other.elements[9] + elements[10] * other.elements[10] + elements[14] * other.elements[11];
elements[11] = elements[3] * other.elements[8] + elements[7] * other.elements[9] + elements[11] * other.elements[10] + elements[15] * other.elements[11];
elements[12] = elements[0] * other.elements[12] + elements[4] * other.elements[13] + elements[8] * other.elements[14] + elements[12] * other.elements[15];
elements[13] = elements[1] * other.elements[12] + elements[5] * other.elements[13] + elements[9] * other.elements[14] + elements[13] * other.elements[15];
elements[14] = elements[2] * other.elements[12] + elements[6] * other.elements[13] + elements[10] * other.elements[14] + elements[14] * other.elements[15];
elements[15] = elements[3] * other.elements[12] + elements[7] * other.elements[13] + elements[11] * other.elements[14] + elements[15] * other.elements[15];
return *this;
}
I did have a nested loop to do this but I ended up writing it all out while trying to find out an answer to this problem. Bear in mind the matrices are in column major and do not get transposed by OpenGL
The rotation and translation matrices are as follows but I don't believe there is any problem with them:
Matrix4 Matrix4::translation(const Vector3 &translation)
{
Matrix4 result(1.0f);
result.elements[0 + 3 * 4] = translation.x;
result.elements[1 + 3 * 4] = translation.y;
result.elements[2 + 3 * 4] = translation.z;
return result;
}
Matrix4 Matrix4::rotation(float angle, const Vector3 &axis)
{
Matrix4 result(1.0f);
float r = toRadians(angle);
float c = (float)cos(r);
float s = (float)sin(r);
float cFlip = 1.0f - c;
result.elements[0 + 0 * 4] = axis.x * cFlip + c;
result.elements[1 + 0 * 4] = axis.y * axis.x * cFlip + axis.z * s;
result.elements[2 + 0 * 4] = axis.x * axis.z * cFlip - axis.y * s;
result.elements[0 + 1 * 4] = axis.x * axis.y * cFlip - axis.z * s;
result.elements[1 + 1 * 4] = axis.y * cFlip + c;
result.elements[2 + 1 * 4] = axis.y * axis.z * cFlip + axis.x * s;
result.elements[0 + 2 * 4] = axis.x * axis.y * cFlip + axis.y * s;
result.elements[1 + 2 * 4] = axis.y * axis.z * cFlip - axis.x * s;
result.elements[2 + 2 * 4] = axis.z * cFlip + c;
return result;
}
Any ideas on what the problem here could be or how to fix it would be greatly appreciated :^)
At your multiply function, you wrote:
elements[0] = elements[0] * other.elements[0] ...
...
Notice that element[0] got its contents actualized now and then you do:
elements[8] = elements[0] * other.elements[8] ...
which use the new value and not the original one. I guess, you want to make a copy of your original matrix before doing this multiplication
opssss !! i just saw !!!
in your multiply, your output matrice is the first input matrix, so the latest operations are calculated with coefficient of the multiplied matrix !! :
elements[0] = elements[0] * .....
....
elements[4] = elements[0] * ..... /* here element[ 0 ] is the top left
element of the multiplied matix */
moreover, operator* shouldn't modfify (nor return) one of his operand, operator*= is here for that

Need documentation that describes the output of OpenGL's rotate method

I have created a custom cube whose sides can be removed. I would eventually like to print the cube to a paper printer. I would like to do my own rotation by using the output from the OpenGL rotate method.
My question: Does documentation exist that describes the Identity Matrix after a rotation? Or is the source available for the OpenGL rotate method?
glRotate creates a rotation matrix and multiplies that in place on the matrix on top of the current matrix stack. Rotation matrices are a well known thing in linear algebra.
You can read about Matrix calculations and Matrix Transformations all over the internet, here is a few links.
Matrix Mathematics
Transformation Matrix
OpenGL Programming/3D/Matrices
Though here is something I've created for calculating exactly what you're trying to calculate. There isn't much so explain because it is basically just a bunch of math formulas.
public class Matrix4
{
public float m00, m01, m02, m03;
public float m10, m11, m12, m13;
public float m20, m21, m22, m23;
public float m30, m31, m32, m33;
public Matrix4()
{
this.set(
1f, 0f, 0f, 0f,
0f, 1f, 0f, 0f,
0f, 0f, 1f, 0f,
0f, 0f, 0f, 1f);
}
public void rotate(float angle, float x, float y, float z)
{
float sin = (float) Math.sin(angle);
float cos = (float) Math.cos(angle);
if ((x * x + y * y + z * z) != 1f)
{
float length = (float) Math.sqrt(x * x + y * y + z * z);
if (length > 0f)
{
length = 1f / length;
x *= length;
y *= length;
z *= length;
}
}
this.mul(
x * x * (1f - cos) + cos, x * y * (1f - cos) - z * sin, x * z * (1f - cos) + y * sin, 0f,
y * x * (1f - cos) + z * sin, y * y * (1f - cos) + cos, y * z * (1f - cos) - x * sin, 0f,
x * z * (1f - cos) - y * sin, y * z * (1f - cos) + x * sin, z * z * (1f - cos) + cos, 0f,
0f, 0f, 0f, 1f);
}
public void mul(
float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33)
{
float mm00 = this.m00 * m00 + this.m01 * m10 + this.m02 * m20 + this.m03 * m30;
float mm01 = this.m00 * m01 + this.m01 * m11 + this.m02 * m21 + this.m03 * m31;
float mm02 = this.m00 * m02 + this.m01 * m12 + this.m02 * m22 + this.m03 * m32;
float mm03 = this.m00 * m03 + this.m01 * m13 + this.m02 * m23 + this.m03 * m33;
float mm10 = this.m10 * m00 + this.m11 * m10 + this.m12 * m20 + this.m13 * m30;
float mm11 = this.m10 * m01 + this.m11 * m11 + this.m12 * m21 + this.m13 * m31;
float mm12 = this.m10 * m02 + this.m11 * m12 + this.m12 * m22 + this.m13 * m32;
float mm13 = this.m10 * m03 + this.m11 * m13 + this.m12 * m23 + this.m13 * m33;
float mm20 = this.m20 * m00 + this.m21 * m10 + this.m22 * m20 + this.m23 * m30;
float mm21 = this.m20 * m01 + this.m21 * m11 + this.m22 * m21 + this.m23 * m31;
float mm22 = this.m20 * m02 + this.m21 * m12 + this.m22 * m22 + this.m23 * m32;
float mm23 = this.m20 * m03 + this.m21 * m13 + this.m22 * m23 + this.m23 * m33;
float mm30 = this.m30 * m00 + this.m31 * m10 + this.m32 * m20 + this.m33 * m30;
float mm31 = this.m30 * m01 + this.m31 * m11 + this.m32 * m21 + this.m33 * m31;
float mm32 = this.m30 * m02 + this.m31 * m12 + this.m32 * m22 + this.m33 * m32;
float mm33 = this.m30 * m03 + this.m31 * m13 + this.m32 * m23 + this.m33 * m33;
this.m00 = mm00; this.m01 = mm01; this.m02 = mm02; this.m03 = mm03;
this.m10 = mm10; this.m11 = mm11; this.m12 = mm12; this.m13 = mm13;
this.m20 = mm20; this.m21 = mm21; this.m22 = mm22; this.m23 = mm23;
this.m30 = mm30; this.m31 = mm31; this.m32 = mm32; this.m33 = mm33;
}
public void set(
float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33)
{
this.m00 = m00;
this.m01 = m01;
this.m02 = m02;
this.m03 = m03;
this.m10 = m10;
this.m11 = m11;
this.m12 = m12;
this.m13 = m13;
this.m20 = m20;
this.m21 = m21;
this.m22 = m22;
this.m23 = m23;
this.m30 = m30;
this.m31 = m31;
this.m32 = m32;
this.m33 = m33;
}
}
The following will create an Identity Matrix Matrix4 m = new Matrix4();
Important do notice that the angle given in the rotate() function in Matrix4 is in radians where in OpenGL the glRotate() functions requires the angle to be in degrees.
Also if the Matrix is "opposite", when you are using it then simply before you use the Matrix for anything else calculate the Transpose of the matrix, and then you can use it.