Orbiting And Spinning Rotation in OpenGL using GLM - c++

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;

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);

Function to determine when a sphere is touching floor 3d

I am trying to get a sphere to make contact with the floor. The spheres radius is 1.0f - I need to work out how to determine the distance between the sphere and the floor.
The Sphere is placed here
glm::mat4 mv_matrix_sphere =
glm::translate(glm::vec3(-2.0f, y, 0.0f)) *
glm::rotate(-t, glm::vec3(0.0f, 1.0f, 0.0f)) *
glm::rotate(-t, glm::vec3(1.0f, 0.0f, 0.0f)) *
glm::mat4(1.0f);
mySphere.mv_matrix = myGraphics.viewMatrix * mv_matrix_sphere;
mySphere.proj_matrix = myGraphics.proj_matrix;
Where y = 20.0f
The sphere will fall and land on the floor at
myFloor.mv_matrix = myGraphics.viewMatrix *
glm::translate(glm::vec3(0.0f, 0.0f, 0.0f)) *
glm::scale(glm::vec3(1000.0f, 0.001f, 1000.0f)) *
glm::mat4(1.0f);
myFloor.proj_matrix = myGraphics.proj_matrix;
The function I need will work out when the Sphere is 1.0f(radius) from the floor so that it collides with it instead of clipping through.

How do I rotate my camera around my object?

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));

Orbiting camera around an object causes it to spin off into the distance

I'm going for just some basic camera control. Move camera up, down, left, right, and rotate around the origin.
If the camera is at y = 0 it works great, but as soon as I move the camera up, the rotation starts to move away from the origin.
I'm not going for fluid movement or anything like that at the moment. Just basics.
Move code:
// increment camX/Y/Z as float
vec3 camPos = vec3(camX, camY, camZ);
viewMatrix = lookAt(camPos, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
Rotate Code:
// Increment camY angle as float
float camOrbX = distance(vec3(camX, camY, camZ), vec3(0.0f)) * sin(camRotY);
float camOrbZ = distance(vec3(camX, camY, camZ), vec3(0.0f)) * cos(camRotY);
camX = camOrbX;
camZ = camOrbZ;
vec3 camPos = vec3(camX, camY, camZ);
viewMatrix = lookAt(camPos, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));

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));