feat: render nested orbits
This commit is contained in:
parent
77d7c2a4d0
commit
da3a917896
|
@ -14,6 +14,7 @@ class ParticleMap
|
||||||
// providing these as two methods keeps things unambiguous - manipulating particles
|
// providing these as two methods keeps things unambiguous - manipulating particles
|
||||||
// is just done for setup
|
// is just done for setup
|
||||||
const Particle& getParticle(const std::string& id) const;
|
const Particle& getParticle(const std::string& id) const;
|
||||||
|
const Particle& getParent(const std::string& id) const;
|
||||||
glm::dvec3 getParticlePosition(const std::string& id, double time) const;
|
glm::dvec3 getParticlePosition(const std::string& id, double time) const;
|
||||||
const Orbit& getOrbit(const std::string& id) const;
|
const Orbit& getOrbit(const std::string& id) const;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,12 @@ const Particle& ParticleMap::getParticle(const std::string& id) const
|
||||||
return _particles.at(id);
|
return _particles.at(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Particle& ParticleMap::getParent(const std::string& childId) const
|
||||||
|
{
|
||||||
|
const std::string parentId = _relationships.at(childId);
|
||||||
|
return _particles.at(parentId);
|
||||||
|
}
|
||||||
|
|
||||||
const Orbit& ParticleMap::getOrbit(const std::string& id) const
|
const Orbit& ParticleMap::getOrbit(const std::string& id) const
|
||||||
{
|
{
|
||||||
return _orbits.at(id);
|
return _orbits.at(id);
|
||||||
|
@ -16,13 +22,31 @@ glm::dvec3 ParticleMap::getParticlePosition(const std::string& id, double time)
|
||||||
if (_orbits.find(id) == _orbits.end())
|
if (_orbits.find(id) == _orbits.end())
|
||||||
return {0,0,0};
|
return {0,0,0};
|
||||||
|
|
||||||
|
const Particle* particle = &(_particles.at(id));
|
||||||
|
glm::dvec3 pos(0,0,0);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const std::string& id = particle->getId();
|
||||||
const std::string& parentId = _relationships.at(id);
|
const std::string& parentId = _relationships.at(id);
|
||||||
const Particle& parent = _particles.at(parentId);
|
const Particle& parent = _particles.at(parentId);
|
||||||
const double gravitationalParameter = parent.getGravitationalParameter();
|
const double gravitationalParameter = parent.getGravitationalParameter();
|
||||||
|
|
||||||
// TODO: actually nest stuff so position is determined from all parents
|
|
||||||
const Orbit& orbit = _orbits.at(id);
|
const Orbit& orbit = _orbits.at(id);
|
||||||
return orbit.getPosition(gravitationalParameter, time);
|
|
||||||
|
pos += orbit.getPosition(gravitationalParameter, time);
|
||||||
|
|
||||||
|
auto it = _relationships.find(parentId);
|
||||||
|
if (it != _relationships.end())
|
||||||
|
{
|
||||||
|
particle = &parent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
particle = nullptr;
|
||||||
|
}
|
||||||
|
} while (particle != nullptr);
|
||||||
|
|
||||||
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleMap::setParticle(const Particle& particle)
|
void ParticleMap::setParticle(const Particle& particle)
|
||||||
|
|
45
src/main.cpp
45
src/main.cpp
|
@ -66,24 +66,35 @@ int main()
|
||||||
GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl");
|
GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl");
|
||||||
|
|
||||||
// set parameters of moon's orbit around earth
|
// set parameters of moon's orbit around earth
|
||||||
Orbit orbit;
|
Orbit moonOrbit;
|
||||||
double semiMajorAxis = 3.84748e8;
|
double moonOrbitSemiMajorAxis = 3.84748e8;
|
||||||
orbit.setSemiMajorAxis(semiMajorAxis); // metres
|
moonOrbit.setSemiMajorAxis(moonOrbitSemiMajorAxis); // metres
|
||||||
orbit.setEccentricity(0.055);
|
moonOrbit.setEccentricity(0.055);
|
||||||
orbit.setInclination(glm::radians(5.15)); // radians
|
moonOrbit.setInclination(glm::radians(5.15)); // radians
|
||||||
orbit.setArgumentOfPeriapsis(318.15); // in the case of the moon these last two values are
|
moonOrbit.setArgumentOfPeriapsis(318.15); // in the case of the moon these last two values are
|
||||||
orbit.setLongitudeOfAscendingNode(60.0); // pretty much constantly changing so use whatever
|
moonOrbit.setLongitudeOfAscendingNode(60.0); // pretty much constantly changing so use whatever
|
||||||
|
|
||||||
|
// set parameters of satellite orbit around moon
|
||||||
|
Orbit stationOrbit;
|
||||||
|
stationOrbit.setSemiMajorAxis(5e7);
|
||||||
|
stationOrbit.setEccentricity(0.6);
|
||||||
|
stationOrbit.setInclination(glm::radians(89.0));
|
||||||
|
stationOrbit.setArgumentOfPeriapsis(43.2);
|
||||||
|
stationOrbit.setLongitudeOfAscendingNode(239.7);
|
||||||
|
|
||||||
// TODO: add something in a nice eccentric orbit around the moon
|
|
||||||
// make the earth-moon system
|
|
||||||
ParticleMap map;
|
ParticleMap map;
|
||||||
map.setParticle({"earth", 5.9e24});
|
map.setParticle({"earth", 5.9e24});
|
||||||
map.setParticle({"moon", 7.3e22});
|
map.setParticle({"moon", 7.3e22});
|
||||||
map.setRelationship("earth", "moon", orbit);
|
map.setParticle({"station", 1e6});
|
||||||
float scale = semiMajorAxis * 1.1;
|
map.setRelationship("earth", "moon", moonOrbit);
|
||||||
ParticleVisualizer earthVis(map, "earth", 0.2, litProgram, unlitProgram, scale);
|
map.setRelationship("moon", "station", stationOrbit);
|
||||||
ParticleVisualizer moonVis(map, "moon", 0.1, litProgram, unlitProgram, scale);
|
|
||||||
OrbitVisualizer orbitVis(orbit, unlitProgram, scale);
|
float scale = moonOrbitSemiMajorAxis * 1.1;
|
||||||
|
ParticleVisualizer earthVis(map, "earth", 0.1, litProgram, unlitProgram, scale);
|
||||||
|
ParticleVisualizer moonVis(map, "moon", 0.02, litProgram, unlitProgram, scale);
|
||||||
|
ParticleVisualizer stationVis(map, "station", 0.01, litProgram, unlitProgram, scale);
|
||||||
|
OrbitVisualizer moonOrbitVis(map, "moon", unlitProgram, scale);
|
||||||
|
OrbitVisualizer stationOrbitVis(map, "station", unlitProgram, scale);
|
||||||
|
|
||||||
// register input
|
// register input
|
||||||
glfwSetKeyCallback(window, keyCallback);
|
glfwSetKeyCallback(window, keyCallback);
|
||||||
|
@ -125,7 +136,7 @@ int main()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double e = .25 + .2 * sin(getTime());
|
double e = .25 + .2 * sin(getTime());
|
||||||
orbit.setEccentricity(e);
|
moonOrbit.setEccentricity(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rendering
|
// rendering
|
||||||
|
@ -134,7 +145,9 @@ int main()
|
||||||
|
|
||||||
earthVis.render(time);
|
earthVis.render(time);
|
||||||
moonVis.render(time);
|
moonVis.render(time);
|
||||||
orbitVis.render(time);
|
stationVis.render(time);
|
||||||
|
moonOrbitVis.render(time);
|
||||||
|
stationOrbitVis.render(time);
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "orbitvisualizer.hpp"
|
#include "orbitvisualizer.hpp"
|
||||||
#include "gfx.hpp"
|
#include "gfx.hpp"
|
||||||
|
|
||||||
OrbitVisualizer::OrbitVisualizer(const Orbit& orbit, const GLuint shaderProgram, float scale)
|
OrbitVisualizer::OrbitVisualizer(const ParticleMap& map, const std::string& particleId, const GLuint shaderProgram, float scale)
|
||||||
: _orbit(orbit), _shaderProgram(shaderProgram), _scale(scale)
|
: _map(map), _particleId(particleId), _shaderProgram(shaderProgram), _scale(scale)
|
||||||
{
|
{
|
||||||
glGenVertexArrays(1, &_vao);
|
glGenVertexArrays(1, &_vao);
|
||||||
glGenBuffers(1, &_vbo);
|
glGenBuffers(1, &_vbo);
|
||||||
|
@ -10,7 +10,11 @@ OrbitVisualizer::OrbitVisualizer(const Orbit& orbit, const GLuint shaderProgram,
|
||||||
|
|
||||||
void OrbitVisualizer::render(const float time)
|
void OrbitVisualizer::render(const float time)
|
||||||
{
|
{
|
||||||
regenerateVertices();
|
// Orbit needs to be drawn relative to its parent
|
||||||
|
const Particle& parent = _map.getParent(_particleId);
|
||||||
|
const glm::vec3 parentPos = _map.getParticlePosition(parent.getId(), time);
|
||||||
|
|
||||||
|
regenerateVertices(parentPos);
|
||||||
|
|
||||||
glUseProgram(_shaderProgram);
|
glUseProgram(_shaderProgram);
|
||||||
updateModelViewProjectionMatrix(_shaderProgram, time);
|
updateModelViewProjectionMatrix(_shaderProgram, time);
|
||||||
|
@ -21,17 +25,19 @@ void OrbitVisualizer::render(const float time)
|
||||||
glDrawArrays(GL_LINE_LOOP, 0, _vertices.size() / 3);
|
glDrawArrays(GL_LINE_LOOP, 0, _vertices.size() / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OrbitVisualizer::regenerateVertices()
|
void OrbitVisualizer::regenerateVertices(const glm::vec3& basePos)
|
||||||
{
|
{
|
||||||
_vertices.clear();
|
const Orbit& orbit = _map.getOrbit(_particleId);
|
||||||
|
|
||||||
|
_vertices.clear();
|
||||||
for (int i = 0; i < _vertexCount; i++)
|
for (int i = 0; i < _vertexCount; i++)
|
||||||
{
|
{
|
||||||
// TODO: this method of getting ellipse vertices is a huge hack. it would be
|
// TODO: this method of getting ellipse vertices is a huge hack. it would be
|
||||||
// better to actually create a first-class ellipse object and use that to generate
|
// better to actually create a first-class ellipse object and use that to generate
|
||||||
// a nice continuous mesh, instead of using orbital positions.
|
// a nice continuous mesh, instead of using orbital positions.
|
||||||
float t = (float)i / (float)_vertexCount * 2.0 * _pi;
|
float t = (float)i / (float)_vertexCount * 2.0 * _pi;
|
||||||
glm::vec3 pos = _orbit.getPositionFromMeanAnomaly(t);
|
glm::vec3 pos = orbit.getPositionFromMeanAnomaly(t);
|
||||||
|
pos += basePos;
|
||||||
|
|
||||||
// Vertices come out of the library with X and Y being in the 'flat' plane. Re-order them
|
// Vertices come out of the library with X and Y being in the 'flat' plane. Re-order them
|
||||||
// here such that Z is up.
|
// here such that Z is up.
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <skein/orbit.h>
|
#include <skein/particlemap.h>
|
||||||
|
|
||||||
class OrbitVisualizer
|
class OrbitVisualizer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OrbitVisualizer(const Orbit& orbit, const GLuint shaderProgram, float scale);
|
OrbitVisualizer(const ParticleMap& map, const std::string& particleId, const GLuint shaderProgram, float scale);
|
||||||
~OrbitVisualizer();
|
~OrbitVisualizer();
|
||||||
|
|
||||||
void render(const float time);
|
void render(const float time);
|
||||||
|
@ -17,12 +17,13 @@ class OrbitVisualizer
|
||||||
|
|
||||||
const int _vertexCount = 100;
|
const int _vertexCount = 100;
|
||||||
const GLuint _shaderProgram;
|
const GLuint _shaderProgram;
|
||||||
const Orbit& _orbit;
|
const ParticleMap& _map;
|
||||||
|
const std::string _particleId;
|
||||||
const float _scale;
|
const float _scale;
|
||||||
|
|
||||||
GLuint _vbo;
|
GLuint _vbo;
|
||||||
GLuint _vao;
|
GLuint _vao;
|
||||||
std::vector<float> _vertices;
|
std::vector<float> _vertices;
|
||||||
|
|
||||||
void regenerateVertices();
|
void regenerateVertices(const glm::vec3& basePos);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue