So here is what I want to do. I want to implement a translation with my mouse so that the object I am translating will follow my mouse movement i.e if my mouse cursor moves by a certain amount of pixels X I want the object to move by that exact same amount X.
So far for rotations I have been using glm to implement arcball and I get a rotation matrix thanks to that.
I am using openGL and SDL so that getting my mouse coordinates is not difficult. I can create a vector of size 3 with the current mouse coordinates during a mouse motion event with:
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_MOUSEMOTION:
glm::vec3 vecTranslation(event.motion.x, event.motion.y, 0);
glm::mat4 translationMatrix ;
glm::translate(translationMatrix, vecTranslation) ;
}
}
With that I have a translation matrix, but that will not get me a translation following exactly what the mouse cursor did in the end.
Would anyone have some insights on it?
Besides, to get my final projection matrix so as to call glMulMatrix()
, I do:
glm::matrixCompMult(translationMatrix,rotationMatrix);
But when I do so, both translation and rotation don't work. If I simply return the rotation matrix and use it directly with glMulMatrix()
, my arcball behaves as expected, but if I use the code above, I can only see one face of the cube that I have and it keeps on changing its proportions but never rotates nor translates.
As for the code that I use for the drawing: //Assume some code is done to know if and what translations should be done matrixProjection = translationMatrix * mMatNow * scaleMatrix ; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT); glMultMatrixf(matrixProjection); // scaling transfomation glScalef(0.5,0.5,0.5); drawCube();
glFlush();
SDL_GL_SwapBuffers();
The matrix that I get is something like: First:
1 ; 0 ; 0 ; 0 ; 0 ; 1 ; 0 ; 0 ; 0 ; 0 ; 1 ; 0 ; 0 ; 0 ; 0 ; 1 ;
Then after a translation:
1 ; 0 ; 0 ; 0 ; 0 ; 1 ; 0 ; 0 ; 0 ; 0 ; 1 ; -25 ; 0 ; 0 ; 0 ; 1 ;
So apparently the translation does happen, however I get this weird result on my drawing:
Original drawing:
You have the position of your mouse-courser and of the object you want to move.
The easiest way to let your object follow your mouse would be to set its position to the position of the mouse:
one way: lets say you have vec3(10, 10, 4) as your mouse position, then simply set
. . . 10
. . . 10
. . . 4
0 0 0 1
(of yourse dont write dots) as the objects matrix. For this it is neccessary that you the mouse position is not the location on the window but the location in the world.
another way: add an in variable in your vertex-shader like this:
layout(location = 0) in vec3 inputPosition;
layout(location = 1) in vec3 inputOffset;
layout(location = 2) in vec4 inputColor;
out vec4 color;
uniform mat4 worldMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
void main(void)
{
gl_Position = worldMatrix * vec4(inputPosition + inputOffset, 1.0f);
gl_Position = viewMatrix * gl_Position;
gl_Position = projectionMatrix * gl_Position;
color = inputColor;
}
where the offset is your mouse-position vector. This approach doesnt attach the object to your mouse but moves it with it. Also for every object you dont want to move you need another shader.
Edit: If you want to rotate the object that it points to your courser, the easiest way would be to take the middle of that object as a vector and calculate the distance between mouse position and object vector. Then you can do some math to get the right angle and rotate the object.
Edit2:
Try the following: I also once had the problem that my matrix before translation was the same like after translation. This was because he did overwrite the matrix anyhow. What I did: First, to make it easier, make a glm::vec3 with the position of your Object. eg. vec3(0,0,0). Then draw your quad that it's center is at the left upper corner of screen. If you now update the position vector of your quad with your mouse position, the mouse respresents the center of the quad. So every frame you do the following: pseudo code:
positionQuad.x = event.motion.x;
positionQuad.y = 0;
positionQuad.z = event.motion.y;
translationMatrix = glm::translate(positionQuad); // Declare translationMatrix as global/class variable to have access anywhere. glm translate multiplies the translation vector (vec4(mX, 0, mZ, 1) with an identity matrix. This works because we initialized the quad at upper left corner
render(); // translationMatrix now is the model matrix. in render you still have to build the MVP matrix and draw it like always.
With rotation simply add
glm::rotate(translationMatrix, DEGREES, glm::vec3(0,1,0)); //this changes the current model-matrix by rotating it by DEGREES degrees around the axis specified in the vec3. If you do it otherwise like translationMatrix= glm::rotate.... you would overwrite the Matrix and you wont have any translation anymore.
after the translation and before the render