I have been trying to get a camera in my world that can rotate and look around a 3D scene actually working for a very long time now. I don't understand why my camera is behaving so strangely when I rotate it moving back and forth not rotating how it should. I have been stuck on this and would really appreciate it if anyone could let me know what I could correct. Thanks.
::MAIN MATH
glm::mat4 look(1.0f);
glm::mat4 model_view(1.0f);
glm::mat4 look_around(1.0f);
glm::mat4 the_perspective(1.0f);
float leftrightlook;
the_perspective = glm::perspective(glm::radians(45.0f), static_cast<float>(width)/height , -7.1f,
150.0f);
look_around = glm::rotate(glm::mat4(1.0f), (leftrightlook), glm::vec3(0.0f, 1.0f, 0.0f));
glm::vec3 UP(0.0f, 1.0f, 0.0f);
glm::vec3 position(1.0f, 1.0f, 1.0f);
glm::vec3 viewdirection(0.0f, 0.0f, 1.0f);
look = glm::lookAt(position, position + viewdirection, UP);
model_view = look_around * look;
::SHADER MATRIX MULTIPLICATION
gl_Position = vec4(position.x, position.y, position.z, 1.0) * the_perspective * model_view;
Related
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);
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;
I want to rotate my camera around the scene and an object which is in the center. I've tried doing it this way:
glm::mat4 view;
float radius = 10.0f;
float camX = sin(SDL_GetTicks()/1000.0f) * radius;
float camZ = cos(SDL_GetTicks()/1000.0f) * radius;
view = glm::lookAt(glm::vec3(camX, 0.0f, camZ), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glUniformMatrix4fv(glGetUniformLocation(shader, "viewingMatrix"), 1, false, &view[0][0]);
but my object loads up further away on the screen and the object rotates around the scene, not the camera.
That's my vertex shader:
void main()
{
FragPos = vec3(modelMatrix * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(modelMatrix))) * aPos;
TexCoord = aTexture;
vec4 transformedPosition = projectionMatrix * viewingMatrix * vec4(FragPos, 1.0f);
gl_Position = transformedPosition;
}
How do I make it such that the camera is the one rotating around in the scene without the object rotating around?
I'm following this tutorial and I'm trying to work out the what happens in the first animation.
https://learnopengl.com/Getting-started/Camera
modelMatrix
glm::mat4 modelMat(1.0f);
modelMat = glm::translate(modelMat, parentEntity.position);
modelMat = glm::rotate(modelMat, parentEntity.rotation.z, glm::vec3(0.0f, 0.0f, 1.0f));
modelMat = glm::rotate(modelMat, parentEntity.rotation.y, glm::vec3(0.0f, 1.0f, 0.0f));
modelMat = glm::rotate(modelMat, parentEntity.rotation.x, glm::vec3(1.0f, 0.0f, 0.0f));
modelMat = glm::scale(modelMat, parentEntity.scale);
int modelMatrixLoc = glGetUniformLocation(shader, "modelMatrix");
glUniformMatrix4fv(modelMatrixLoc, 1, false, &modelMat[0][0]);
The target of the view (2nd parameter of glm::lookAt) should be the center of the object. The position of the object (and the center of the object) is changed by the model matrix (modelMatrix) in the vertex sahder.
You have to add the world position of the object to the 1st and 2nd parameter of glm::lookAt. The position of the object is the translation of the model matrix.
Further the object is to far away from the camera, because the radius is to large.
To solve your issue, the code has to look somehow like this:
glm::mat4 view;
float radius = 2.0f;
float camX = sin(SDL_GetTicks()/1000.0f) * radius;
float camZ = cos(SDL_GetTicks()/1000.0f) * radius;
view = glm::lookAt(
glm::vec3(camX, 0.0f, camZ) + parentEntity.position,
parentEntity.position,
glm::vec3(0.0f, 1.0f, 0.0f));
glUniformMatrix4fv(
glGetUniformLocation(shader, "viewingMatrix"), 1, false, glm::value_ptr(view));
I would like to ask what the steps are to setting a 4x4 Rotation Matrix using degrees for all separate X, Y, Z axis.
Illustrations would be much appreciated, thanks!
(C++ implementation preferred)
Assuming a C++ program, if you want a header-only library that will do this for you, you can use the amazing glm:
http://glm.g-truc.net/0.9.6/index.html
And use glm::rotate as such:
glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.f);
glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Translate));
glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Rotate.y, glm::vec3(-1.0f, 0.0f, 0.0f));
glm::mat4 View = glm::rotate(ViewRotateX, Rotate.x, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 Model = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
glm::mat4 MVP = Projection * View * Model;
You can find the implementation on Github if you are interested in writing your own: matrix_transform.inl
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));