3

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?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • see [Is it possible to make realistic n-body solar system simulation in matter of size and mass?](https://stackoverflow.com/a/28020934/2521214) – Spektre Jan 16 '20 at 08:45

2 Answers2

0

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;
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thank you for your reply! I tried doing it like this but then the planet in question just ends up going away in one direction. Figured it would be more complicated than that. And if I do the spinning after the orbiting the planet stops all motion completely. Weird huh? – Lukas Clausson Jan 15 '20 at 14:37
0

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