glm::translate with local space - opengl

I want to move a matrix according to it's own space (direction) and not world space.
Specifically I want to move the view matrix/the "camera".
glm::mat4x4 view = glm::lookAt(glm::vec3(1.1f, 1.3f, 1.2f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f));
view=glm::rotate(view, r, glm::vec3(0,1,0));
view=glm::translate(view, glm::vec3(x,y,z));
The translation is equal disregarding it's rotation, but I'd like to translate according to where the camera is facing, e.g. when the camera is facing the x axis, and I translate z, it should translate along world axis x. How can this be done?

If you want to manipulate the camera position, you should store the camera position and only put it into view space when you need to.
glm::mat4 camera = glm::inverse(glm::lookAt(
glm::vec3(1.1f, 1.3f, 1.2f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f)));
camera = glm::rotate(camera, r, glm::vec3(0,1,0));
camera = glm::translate(camera, glm::vec3(x,y,z));
glm::mat4 view = glm::inverse(camera);
It's also possible that doing pre-multiplcation of your view matrix is what you want, but I'm uncertain, since I try to avoid having to deal with pre vs post multiplication as if my life depended on it.
glm::mat4 view = glm::lookAt(
glm::vec3(1.1f, 1.3f, 1.2f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f)));
view = glm::rotate(glm::mat4(), r, glm::vec3(0,1,0)) * view;
view = glm::translate(glm::mat4(), glm::vec3(x,y,z)) * view;

Related

How can I rotate my camera around the Y axis on a specific orientation without rotating the x and z axis?

I am trying to rotate my camera from it's position but around the Y axis. If anyone has any ideas
please let me know. Whenever I use the glm rotate function I am faced with this issue in it's third
parameter.
glm::mat4 xlook(1.0f);
glm::vec3 position(0.05f, 0.05f, -1.0f);
glm::vec3 viewdirection(0.0f, 0.0f, -1.0f);
glm::vec3 UP(0.0f, 1.0f, 0.0f);
xlook = glm::rotate(xlook, leftright, UP);
glm::mat3 rot = glm::mat3(xlook);
viewdirection = rot * viewdirection;
glm::mat4 views;
glm::mat4 trans1(1.0f);
trans1 = glm::rotate(trans1, 0.0f, glm::vec3(0.0f, 1.0f, 0.0f));
trans1 = glm::rotate(trans1, 0.0f, glm::vec3(4.0f, 0.0f, 0.0f));
trans1 = glm::scale(trans1, glm::vec3(Thescale,Thescale, 0.0f));
trans1 = glm::translate(trans1, glm::vec3(0.0f, 0.0f, Thetranslation));
views = glm::lookAt(position, position + viewdirection, UP);

Orbiting And Spinning Rotation in OpenGL using GLM

I'm making a solar system in OpenGL and I want the planets to be able to orbit other planets as well as rotate around their own centers.
This is the code I'm currently using to make the planets orbit a specific point:
Model = glm::translate(Model, glm::vec3(-orbit_radius_, 0.0f, 0.0f));
Model = glm::rotate(Model, glm::radians(orbit_speed_) / 100.0f, glm::vec3(0.0f, 1.0f, 0.0f));
Model = glm::translate(Model, glm::vec3(orbit_radius_, 0.0f, 0.0f));
How would I combine this with a transformation that spins the object around itself?
I got it to work by just splitting then transformations and then combining them at the end.
rotate_ = glm::translate(rotate_, glm::vec3(-orbit_radius_, 0.0f, 0.0f));
rotate_ = glm::rotate(rotate_, glm::radians(orbit_speed_) / 100.0f, glm::vec3(0.0f, 1.0f, 0.0f));
rotate_ = glm::translate(rotate_, glm::vec3(orbit_radius_, 0.0f, 0.0f));
spin_ = glm::rotate(spin_, glm::radians(spin_speed_) / 100.0f, glm::vec3(0.0f, 1.0f, 0.0f));
final_ = rotate_ * spin_;
If you want to spinn and rotate an object, the I recommend to create an object which has its center at (0, 0, 0)
The self spinning of the object has to be do first. Then translate and rotate the object:
Model = rotate * translate * spinn
e.g.:
rot_angle += glm::radians(orbit_speed_) / 100.0f;
spin_angle += glm::radians(orbit_speed_) / 100.0f;
glm::vec3 tvec = glm::vec3(orbit_radius_, 0.0f, 0.0f);
glm::vec3 axis = glm::vec3(0.0f, 1.0f, 0.0f)
glm::mat4 translate = glm::translate(glm::mat(1.0f), tvec);
glm::mat4 rotate = glm::rotate(glm::mat(1.0f), rot_angle, axis);
glm::mat4 spin = glm::rotate(glm::mat(1.0f), spin_angle , axis);
Model = rotate * translate * spin;
With this solution rot_angle and spin_angle have to be incremented in every frame by a constant step.
If you don't want to increment the angles, then you have to store 2 matrices, instead of the angles. 1 for the rotation and on for the spin:
mat4 rotate(1.0f);
mat4 spin(1.0f);
glm::vec3 tvec = glm::vec3(-orbit_radius_, 0.0f, 0.0f);
glm::vec3 axis = glm::vec3(0.0f, 1.0f, 0.0f)
float rot_angle = glm::radians(orbit_speed_) / 100.0f;
float spin_angle = glm::radians(spin_speed_) / 100.0f;
rotate = glm::translate(rotate, tvec);
rotate = glm::rotate(rotate, rot_angle, axis );
rotate = glm::translate(rotate, -tvec);
spin = glm::rotate(spin, spin_angle, axis);
Model = rotate * spin;

How can I set up a camera at bird's eye view using GLM?

I am trying to set up my camera at a bird's eye perspective. By that I mean pointing straight down. This is what I've initialized so far:
glm::vec3 camPosition = glm::vec3(0.0f, 10.0f, 0.0f); // camera's position
glm::vec3 camFront = glm::vec3(0.0f, 0.0f, 0.0f); // where the camera is pointing
glm::vec3 camUp = glm::vec3(0.0f, 0.0f, 1.0f);
I pass this into the glm::lookat function but this is not working at all. Perhaps I haven't understood it that well...
I am trying to set up my camera at a bird's eye perspective.
I recommend to do the following. Define 2 vectors.
Define the up vector of the world. This means the vector, which points form the ground to the sky, in the coordinate system of your world:
glm::vec3 world_up( 0.0f, 0.0f, 1.0f );
Define the direction to the north in the coordinate system of your world:
glm::vec3 world_north( 0.0f, 1.0f, 0.0f );
With this information the vectors of the view coordinates system can be set up.
camPosition is the position of the "bird". A point hight up in the sky:
float height = 10.0f;
glm::vec3 camPosition = world_up * 10.0f;
camTraget it the position where the "bird" is looking at. A point on the ground:
glm::vec3 camTraget = glm::vec3(0.0f, 0.0f, 0.0f);
camUp is perpendicular to the vector from camPosition to camTraget. Since the "bird" looks at the ground it is the flight direction of the bird (e.g. to the north):
glm::vec3 camUp = world_north;
With this vectrs the view matrix can be set up by glm::lookAt():
glm::mat4 view = glm::lookAt( camPosition, camTraget, camUp );

OpenGL Rotation Around a Point Using GLM

I've been reading other posts about how to rotate objects around a point in OpenGL by translating the pivot to the origin, rotating, and the translating back. However, I can't seem to get it working. I have a cube and am using glm::perspective and glm::lookAt to generate the projection and view matrices.
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
// Camera matrix
glm::mat4 View = glm::lookAt(
glm::vec3(0,3.5,-5),
glm::vec3(0,0,0),
glm::vec3(0,1,0)
);
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 Model = glm::mat4(1.0f);
Then I apply the transformations on the model matrix like this, inside a while loop:
if (glfwGetKeyOnce(window, GLFW_KEY_UP))
{
Model = translate(Model, vec3(1.0f, 0.0f, 0.0f));
Model = rotate(Model, 90.0f, vec3(1.0f, 0.0f, 0.0f));
Model = translate(Model, vec3(-1.0f, 0.0f, 0.0f));
}
mat4 MVP = Projection * View * Model;
And in my vertex shader, I have this:
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
However, this still just rotates the cube around its center. If I get rid of the calls to glm::translate, and instead, translate by adjusting the x positions of the vertices, it works properly. But I don't think that's the correct way to do it. What am I missing here?
if (glfwGetKeyOnce(window, GLFW_KEY_UP))
{
Model = translate(Model, vec3(1.0f, 0.0f, 0.0f));
Model = rotate(Model, 90.0f, vec3(1.0f, 0.0f, 0.0f));
Model = translate(Model, vec3(-1.0f, 0.0f, 0.0f));
}
mat4 MVP = Projection * View * Model;
try to visualize this code with your "thumbs-up hand". The thumb is the x-Axis. At first you lift your hand, then you walk in a circle, at last you lower your hand.
Most likely you wanted to rotate around another axis.
Please bear in Mind there are more modern ways to do rotations like quaternions. This'll spare you loads of operations.

Displace cube into origin with OpenGL

I'm drawing a bunch of points inside a 64x64x64 cube and can't figure out how to displace the origin so that rotations are done around the center of the cube.
My vertex data is stored inside a 1D array, going from {(0,0,0), (0,0,1), ..., (63, 63, 63)}.
This is my current code to setup the matrices each frame:
// Set ProjectionMatrix
projectionMatrix = glm::perspective(90.0f, (GLfloat)width / (GLfloat) height,0.1f, 1000.f);
glUniformMatrix4fv(location_projectionMatrix, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
// Set ModelViewMatrix
glm::mat4 identity = glm::mat4(1.0);
glm::mat4 viewTranslate = glm::translate(identity, glm::vec3(0.0f, 0.0f, -translate_z));
glm::mat4 viewRotateX = glm::rotate(viewTranslate, rotate_x, glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 viewRotateY = glm::rotate(viewRotateX, rotate_y, glm::vec3(0.0f, 1.0f, 0.0f));
modelViewMatrix = viewRotateY;
glUniformMatrix4fv(location_modelViewMatrix, 1, GL_FALSE, glm::value_ptr(modelViewMatrix));
I tried to just translate the cube by -32 into the x and y direction, but without success.
Matrix operations are non commutative .It means that doing translation first and then rotation is not the same as doing rotation and then translation.Usually the order is :scale-> rotation -> translation.
So try this instead:
glm::mat4 viewRotateX = glm::rotate(identity, rotate_x, glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 viewRotateY = glm::rotate(viewRotateX, rotate_y, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 viewTranslate = glm::translate(viewRotateY , glm::vec3(0.0f, 0.0f, -translate_z));