feat: add particle map
This commit is contained in:
parent
a5ff616e86
commit
56aa50251b
|
@ -0,0 +1,9 @@
|
|||
# Skein
|
||||
|
||||
Skein is a library for efficiently simulating Keplerian astrodynamics.
|
||||
|
||||
## Usage
|
||||
|
||||
Kepler models orbiting bodies as particles. Particles are zero-dimensional objects which can be on elliptical orbits around other particles. The orbited particle is assumed to make up the overwhelming majority of the mass of the combined two-object system.
|
||||
|
||||
|
|
@ -4,6 +4,7 @@ project(skein)
|
|||
add_library(skein STATIC
|
||||
src/orbit.cpp
|
||||
src/particle.cpp
|
||||
src/particlemap.cpp
|
||||
)
|
||||
|
||||
target_include_directories(skein PUBLIC
|
||||
|
|
|
@ -2,14 +2,19 @@
|
|||
|
||||
#include <skein/orbit.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
class Particle
|
||||
{
|
||||
public:
|
||||
Particle() = default;
|
||||
Particle(const std::string& id, double mass);
|
||||
Particle(const Particle& other);
|
||||
~Particle() = default;
|
||||
|
||||
Orbit& getOrbit();
|
||||
const std::string& getId() const;
|
||||
double getMass() const;
|
||||
|
||||
private:
|
||||
Orbit _orbit;
|
||||
const std::string _id;
|
||||
const double _mass;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "skein/particle.h"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class ParticleMap
|
||||
{
|
||||
public:
|
||||
ParticleMap() = default;
|
||||
~ParticleMap() = default;
|
||||
|
||||
// providing these as two methods keeps things unambiguous - manipulating particles
|
||||
// is just done for setup
|
||||
const Particle& getParticle(const std::string& id) const;
|
||||
glm::vec3 getParticlePosition(const std::string& id, double time) const;
|
||||
const Orbit& getOrbit(const std::string& id) const;
|
||||
|
||||
void setParticle(const Particle& particle);
|
||||
void setRelationship(const std::string& parentId, const std::string& childId, const Orbit& orbit);
|
||||
|
||||
private:
|
||||
std::map<std::string, Particle> _particles;
|
||||
std::map<std::string, std::string> _relationships;
|
||||
std::map<std::string, Orbit> _orbits;
|
||||
};
|
|
@ -1,7 +1,21 @@
|
|||
#include "skein/particle.h"
|
||||
|
||||
Orbit& Particle::getOrbit()
|
||||
Particle::Particle(const std::string& id, double mass)
|
||||
: _id(id), _mass(mass)
|
||||
{
|
||||
return _orbit;
|
||||
}
|
||||
|
||||
Particle::Particle(const Particle& other)
|
||||
: _id(other.getId()), _mass(other.getMass())
|
||||
{
|
||||
}
|
||||
|
||||
const std::string& Particle::getId() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
double Particle::getMass() const
|
||||
{
|
||||
return _mass;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#include "skein/particlemap.h"
|
||||
#include "skein/particle.h"
|
||||
|
||||
|
||||
const Particle& ParticleMap::getParticle(const std::string& id) const
|
||||
{
|
||||
return _particles.at(id);
|
||||
}
|
||||
|
||||
const Orbit& ParticleMap::getOrbit(const std::string& id) const
|
||||
{
|
||||
return _orbits.at(id);
|
||||
}
|
||||
|
||||
glm::vec3 ParticleMap::getParticlePosition(const std::string& id, double time) const
|
||||
{
|
||||
// TODO: actually nest stuff so position is determined from all parents
|
||||
|
||||
if (_orbits.find(id) != _orbits.end())
|
||||
{
|
||||
const Orbit& orbit = _orbits.at(id);
|
||||
return orbit.getPosition(time);
|
||||
}
|
||||
|
||||
return {0,0,0};
|
||||
}
|
||||
|
||||
void ParticleMap::setParticle(const Particle& particle)
|
||||
{
|
||||
_particles.insert({particle.getId(), particle});
|
||||
}
|
||||
|
||||
void ParticleMap::setRelationship(const std::string& parentId, const std::string& childId, const Orbit& orbit)
|
||||
{
|
||||
// map children to parent - children can only have one parent, so we use the map to
|
||||
// identify the parent directly using the child as the key
|
||||
_relationships.insert({childId, parentId});
|
||||
_orbits.insert({childId, orbit});
|
||||
}
|
|
@ -110,7 +110,7 @@ GLuint compileShaderProgram(const std::string& fragShaderPath)
|
|||
|
||||
void updateProjectionMatrix(GLuint shaderProgram)
|
||||
{
|
||||
float left = -aspect_, right = aspect_, bottom = -1.0, top = 1.0, near = -1.0, far = 1.0;
|
||||
float left = -aspect_, right = aspect_, bottom = -1.0, top = 1.0, near = -2.0, far = 1.0;
|
||||
glm::mat4 projection = glm::ortho(left, right, bottom, top, near, far);
|
||||
GLint projectionLocation = getShaderUniformLocation(shaderProgram, "_Projection");
|
||||
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, &projection[0][0]);
|
||||
|
|
38
src/main.cpp
38
src/main.cpp
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include <skein/orbit.h>
|
||||
#include <skein/particle.h>
|
||||
#include <skein/particlemap.h>
|
||||
|
||||
// INPUT!
|
||||
//
|
||||
|
@ -92,19 +93,26 @@ int main()
|
|||
GLuint litProgram = compileShaderProgram("./frag_lit.glsl");
|
||||
GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl");
|
||||
|
||||
// set up scene
|
||||
Icosphere planet(0.2, 3, litProgram);
|
||||
// set parameters of moon's orbit around earth
|
||||
Orbit orbit;
|
||||
orbit.setSemiMajorAxis(1.0); // in km
|
||||
// TODO: implement zoom
|
||||
//orbit.setSemiMajorAxis(384748); // in km
|
||||
orbit.setEccentricity(0.055);
|
||||
orbit.setInclination(5.15); // degreees
|
||||
orbit.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
|
||||
|
||||
Particle particle;
|
||||
Orbit& orbit = particle.getOrbit();
|
||||
orbit.setSemiMajorAxis(.75);
|
||||
orbit.setEccentricity(.5);
|
||||
orbit.setInclination(3.142 / 2.0 + 1);
|
||||
orbit.setArgumentOfPeriapsis(2.0);
|
||||
orbit.setLongitudeOfAscendingNode(0.1);
|
||||
|
||||
ParticleVisualizer particleVisualizer(particle, litProgram, unlitProgram);
|
||||
OrbitVisualizer orbitVisualizer(orbit, unlitProgram);
|
||||
// TODO: add something in a nice eccentric orbit around the moon
|
||||
// make the earth-moon system
|
||||
ParticleMap map;
|
||||
map.setParticle({"moon", 7.3e22});
|
||||
map.setParticle({"earth", 5.9e24});
|
||||
map.setRelationship("moon", "earth", orbit);
|
||||
// TODO: there is a bug where re-ordering the visualizers breaks rendering
|
||||
ParticleVisualizer moonVis(map, "moon", 0.1, litProgram, unlitProgram);
|
||||
ParticleVisualizer earthVis(map, "earth", 0.2, litProgram, unlitProgram);
|
||||
OrbitVisualizer orbitVis(orbit, unlitProgram);
|
||||
|
||||
// register input
|
||||
glfwSetKeyCallback(window, keyCallback);
|
||||
|
@ -148,9 +156,9 @@ int main()
|
|||
glClearColor(0.2, 0.3, 0.3, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
planet.render(time);
|
||||
particleVisualizer.render(time);
|
||||
orbitVisualizer.render(time);
|
||||
earthVis.render(time);
|
||||
moonVis.render(time);
|
||||
orbitVis.render(time);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
#include "particlevisualizer.hpp"
|
||||
|
||||
ParticleVisualizer::ParticleVisualizer(Particle& particle, GLuint sphereShaderProgram, GLuint widgetShaderProgram)
|
||||
: _particle(particle), _sphere({0.07, 2, sphereShaderProgram}), _widget(widgetShaderProgram)
|
||||
ParticleVisualizer::ParticleVisualizer(const ParticleMap& map, const std::string& particleId, float radius,
|
||||
GLuint sphereShaderProgram, GLuint widgetShaderProgram)
|
||||
: _map(map), _particleId(particleId), _sphere({radius, 2, sphereShaderProgram}), _widget(widgetShaderProgram)
|
||||
{
|
||||
}
|
||||
|
||||
void ParticleVisualizer::render(float time)
|
||||
{
|
||||
const Orbit& orbit = _particle.getOrbit();
|
||||
|
||||
// TODO: get mean anomly from particle which has the mass!!
|
||||
const float meanAnomaly = time;
|
||||
glm::vec3 pos = orbit.getPosition(meanAnomaly);
|
||||
glm::vec3 pos = _map.getParticlePosition(_particleId, meanAnomaly);
|
||||
|
||||
// render widget
|
||||
glm::mat4 widgetMatrix = orbit.getLookAlongMatrix(time);
|
||||
_widget.setModelMatrix(widgetMatrix);
|
||||
_widget.render(time);
|
||||
// TODO: extract widget to its own visualizer since we know it wants an orbit but we
|
||||
// might not have one here
|
||||
//// render widget
|
||||
//const Orbit& orbit = _map.getOrbit(_particleId);
|
||||
//glm::mat4 widgetMatrix = orbit.getLookAlongMatrix(time);
|
||||
//_widget.setModelMatrix(widgetMatrix);
|
||||
//_widget.render(time);
|
||||
|
||||
// render sphere
|
||||
_sphere.setPosition(pos);
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
#include "widget.hpp"
|
||||
#include "icosphere.hpp"
|
||||
|
||||
#include <skein/particle.h>
|
||||
#include <skein/particlemap.h>
|
||||
|
||||
class ParticleVisualizer
|
||||
{
|
||||
public:
|
||||
ParticleVisualizer(Particle& particle, GLuint sphereShaderProgram, GLuint widgetShaderProgram);
|
||||
ParticleVisualizer(const ParticleMap& map, const std::string& particleId, float radius, GLuint sphereShaderProgram, GLuint widgetShaderProgram);
|
||||
~ParticleVisualizer() = default;
|
||||
|
||||
void render(float time);
|
||||
|
@ -16,7 +16,8 @@ class ParticleVisualizer
|
|||
private:
|
||||
void updateModelMatrix();
|
||||
|
||||
Particle& _particle;
|
||||
const ParticleMap& _map;
|
||||
const std::string& _particleId;
|
||||
Icosphere _sphere;
|
||||
Widget _widget;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue