I am writing a Tetris Clone, it is almost done, except for the collisions. For example In order to move the Piece Z I use a method:
void PieceZ::movePieceDown()
{
drawBlock (x1,y1++);
drawBlock (x2,y2++);
drawBlock (x3,y3++);
drawBlock (x4,y4++);
}
and in order to rotate a Piece I use a setter (because coordinates are private). For rotation I use a 90 degree clockwise rotation matrix. For example if I want to move (x1,y1) and (x2, y2) is my origin, to get x and y of a new block:
newX = (y1-y2) + x2;
newY = (x2-x1) + y2 + 1;
That works to some extent, it starts out as:
0 0 0 0
0 1 1 0
0 0 1 1
0 0 0 0
Then as planned it rotates to:
0 0 0 1
0 0 1 1
0 0 1 0
0 0 0 0
And then it rotates to Piece S:
0 0 0 0
0 0 1 1
0 1 1 0
0 0 0 0
And then it just alternates between the second and the third stages.
My calculations are wrong but I can't figure out where, I just need a little hint.
Ok here is how it should go (somewhat):
Determine where you want to rotate the piece (this could be the upper or lower corner or the center) and call it origin
Calculate the new x newX = y - origin.y;
Calculate the new y newY = -x + origin.x;
This should work (I got this idea from wikipedia and rotation matrixes: https://en.wikipedia.org/wiki/Transformation_matrix)
Related
I´m trying to create a view matrix for my program to be able to move and rotate the camera in OpenGL.
I have a camera struct that has the position and rotation vectors in it. From what I understood, to create the view matrix, you need to multiply the transform matrix with the rotation matrix to get the expected result.
So far I tried creating matrices for rotation and for transformation and multiply them like this:
> Transformation Matrix T =
1 0 0 -x
0 1 0 -y
0 0 1 -z
0 0 0 1
> Rotation Matrix Rx =
1 0 0 0
0 cos(-x) -sin(-x) 0
0 sin(-x) cos(-x) 0
0 0 0 1
> Rotation Matrix Ry =
cos(-y) 0 sin(-y) 0
0 1 0 0
-sin(-y) 0 cos(-y) 0
0 0 0 1
> Rotation Matrix Rz =
cos(-z) -sin(-z) 0 0
sin(-z) cos(-z) 0 0
0 0 1 0
0 0 0 1
View matrix = Rz * Ry * Rx * T
Notice that the values are negated, because if we want to move the camera to one side, the entire world is moving to the opposite side.
This solution seems to almost be working. The problem that I have is that when the camera is not at 0, 0, 0, if I rotate the camera, the position is changed. What I think is that if the camera is positioned at, let´s say, 0, 0, -20 and I rotate the camera, the position should remain at 0, 0, -20 right?
I feel like I´m missing something but I can´t seem to know what. Any help?
Edit 1:
It´s an assignment for university, so I can´t use any built-in functions!
Edit 2:
I tried changing the order of the operations and putting the translation in the left side, so T * Rz * Ry * Rx, but then the models rotate around themselves, and not around the camera.
I am trying to convert from UE4 coordinates (Z up) to opengl coorinates (Y up) but I cant seem to get around it.
I do this Matrix transforming from X+ right, Y+ up, Z- deep to Y+ right, Z+ up, X+ deep
[mat = M]
0 1 0 0
0 0 1 0
-1 0 0 0
0 0 0 1
But I end up getting the wrong result and also the rotation....
I get ActorTranfrom from (T) = this->GetTransform()
then
FTransform R = T * M
Then I do the R - ToMatrixWithScale() - then get send it to OpenGL backend.
But the orientation is wrong... What am I doing wrong ?
I want to rotate an object with the face side to the center of another one, but I have some problems with it: when I try to rotate an object to another one and it lies on X axis, it works properly [first two screenshots], but when I try to rotate it as on the screenshot, everything breaks down [second two screenshots].
Before1:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
After1:
0 0 -1 0
-0 -1 0 0
1 0 0 0
0 0 0 1
Before2:
0 0 -1 0
-0 -1 0 0
1 0 0 0
0 0 0 1
After2:
0 0 -0.707107 0
0.5 -0.5 0 0
0.707107 -0.707107 0 0
0 0 0 1
Here's my code:
void ConcreteObject::faceObjectTo(ConcreteObject otherObject) {
Vector<double> temp = {0, 1, 0};
Vector<double> forward = otherObject.getCenter() - this->getCenter();
forward.normalize();
Vector<double> right = temp.cross(forward);
right.normalize();
Vector<double> up = forward.cross(right);
Matrix<double> newMatrix = this->getTransformMatrix().getCurrentState();
newMatrix(0, 0) = right[0];
newMatrix(0, 1) = right[1];
newMatrix(0, 2) = right[2];
newMatrix(1, 0) = up[0];
newMatrix(1, 1) = up[1];
newMatrix(1, 2) = up[2];
newMatrix(2, 0) = forward[0];
newMatrix(2, 1) = forward[1];
newMatrix(2, 2) = forward[2];
TransformMatrix newObjectMatrix(newMatrix);
this->setTransformMatrix(newObjectMatrix);
}
You need to normalize right, there's no reason for temp and forward to be orthogonal, hence even if they are unit vectors, their crossproduct need not be.
I have been trying to learn more about matrices in opengl; right now I'm stuck trying to understand where things are stored inside the modelview matrix. (location,scaling,rotations etc) This is obviously very important as understanding matrices is one of the first steps to fully understand modern opengl.
I have been trying to find some good articles, and I've currently found 2: (1,2)
However, I stil don't understand where the values are stored; any help is very appreciated (links, pinpointers etc)
Here is a reference of how different (affine) transformation matrices are constructed:
Identity:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Translate (x, y ,z):
1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1
Scale (sx, sy, sz):
sx 0 0 0
0 sy 0 0
0 0 sz 0
0 0 0 1
Rotate along x axis (by angle t):
1 0 0 0
0 cos(t) -sin(t) 0
0 sin(t) cos(t) 0
0 0 0 1
Rotate along y axis (by angle t):
cos(t) 0 sin(t) 0
0 1 0 0
-sin(t) 0 cos(t) 0
0 0 0 1
Rotate along z axis (by angle t):
cos(t) -sin(t) 0 0
sin(t) cos(t) 0 0
0 0 1 0
0 0 0 1
I try to construct my own View Matrix in OpenGL.
I'm following this link
https://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
From the OpenGL doc, I have following.
eye position = eye(xe, ye, ze)
center position = cen(0, 0, 0)
up = up(xu, yu, zu). (e.g. up = (0, 1, 0))
forward vector
f' = cen - eye = (0, 0, 0) - (xe, ye, ze) = (-xe, -ye, -ze)
side vector
s' = f' x up
I don't understand why f' x up, why not up x f'
u' = s' x f'
I do't understand why u' = s' x f', why not u' = f' x s'
we normalize s', u', f'
s = norm(s'), u = norm(u'), f=norm(f')
We construct the rotation matrix with row-major(what we learn in algebra class)
R =
s_x u_x f_x 0
s_y u_y f_y 0
s_z u_z f_z 0
0 0 0 1
translation matrix:
T =
1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1
we know
M = T*R
View Matrix V = invert(M)
V = invert(T*R) = invert(R)invert(T)
V = transpose(R)invert(T)
transpose(R) =
s_x s_y s_z 0
u_x u_y u_z 0
f_x f_y f_z 0
0 0 0 1
invert(T) =
1 0 0 -x
0 1 0 -y
0 0 1 -z
0 0 0 1
so
View Matrix V = transpose(R)invert(T)
But from the OpenGL doc., f change to -f
The rotation changes to following
R =
s_x u_x -f_x 0
s_y u_y -f_y 0
s_z u_z -f_z 0
0 0 0 1
I Don't understand why we need to change the forward vector to negative.
The cross product order just follows from its definition. It is just like it is. You are setting up a right-handed coordinate system. So if you align the thumb of your right hand with the first factor and the index finger with the second factor, then the middle finger will point in the direction of the cross product (perpendicular to both). There is really not much more to tell about this.
And since you are setting up a right-handed coordinate system, the forward direction of the camera must be mapped to the negative z-direction. That's why the third column of the rotation matrix is inverted. If you don't do this, you end up with a left-handed coordinate system, where the camera looks in the direction of the positive z-axis.