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
|
add_library(skein STATIC
|
||||||
src/orbit.cpp
|
src/orbit.cpp
|
||||||
src/particle.cpp
|
src/particle.cpp
|
||||||
|
src/particlemap.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(skein PUBLIC
|
target_include_directories(skein PUBLIC
|
||||||
|
|
|
@ -2,14 +2,19 @@
|
||||||
|
|
||||||
#include <skein/orbit.h>
|
#include <skein/orbit.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class Particle
|
class Particle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Particle() = default;
|
Particle(const std::string& id, double mass);
|
||||||
|
Particle(const Particle& other);
|
||||||
~Particle() = default;
|
~Particle() = default;
|
||||||
|
|
||||||
Orbit& getOrbit();
|
const std::string& getId() const;
|
||||||
|
double getMass() const;
|
||||||
|
|
||||||
private:
|
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"
|
#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)
|
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);
|
glm::mat4 projection = glm::ortho(left, right, bottom, top, near, far);
|
||||||
GLint projectionLocation = getShaderUniformLocation(shaderProgram, "_Projection");
|
GLint projectionLocation = getShaderUniformLocation(shaderProgram, "_Projection");
|
||||||
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, &projection[0][0]);
|
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/orbit.h>
|
||||||
#include <skein/particle.h>
|
#include <skein/particle.h>
|
||||||
|
#include <skein/particlemap.h>
|
||||||
|
|
||||||
// INPUT!
|
// INPUT!
|
||||||
//
|
//
|
||||||
|
@ -92,19 +93,26 @@ int main()
|
||||||
GLuint litProgram = compileShaderProgram("./frag_lit.glsl");
|
GLuint litProgram = compileShaderProgram("./frag_lit.glsl");
|
||||||
GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl");
|
GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl");
|
||||||
|
|
||||||
// set up scene
|
// set parameters of moon's orbit around earth
|
||||||
Icosphere planet(0.2, 3, litProgram);
|
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;
|
// TODO: add something in a nice eccentric orbit around the moon
|
||||||
Orbit& orbit = particle.getOrbit();
|
// make the earth-moon system
|
||||||
orbit.setSemiMajorAxis(.75);
|
ParticleMap map;
|
||||||
orbit.setEccentricity(.5);
|
map.setParticle({"moon", 7.3e22});
|
||||||
orbit.setInclination(3.142 / 2.0 + 1);
|
map.setParticle({"earth", 5.9e24});
|
||||||
orbit.setArgumentOfPeriapsis(2.0);
|
map.setRelationship("moon", "earth", orbit);
|
||||||
orbit.setLongitudeOfAscendingNode(0.1);
|
// TODO: there is a bug where re-ordering the visualizers breaks rendering
|
||||||
|
ParticleVisualizer moonVis(map, "moon", 0.1, litProgram, unlitProgram);
|
||||||
ParticleVisualizer particleVisualizer(particle, litProgram, unlitProgram);
|
ParticleVisualizer earthVis(map, "earth", 0.2, litProgram, unlitProgram);
|
||||||
OrbitVisualizer orbitVisualizer(orbit, unlitProgram);
|
OrbitVisualizer orbitVis(orbit, unlitProgram);
|
||||||
|
|
||||||
// register input
|
// register input
|
||||||
glfwSetKeyCallback(window, keyCallback);
|
glfwSetKeyCallback(window, keyCallback);
|
||||||
|
@ -148,9 +156,9 @@ int main()
|
||||||
glClearColor(0.2, 0.3, 0.3, 1.0);
|
glClearColor(0.2, 0.3, 0.3, 1.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
planet.render(time);
|
earthVis.render(time);
|
||||||
particleVisualizer.render(time);
|
moonVis.render(time);
|
||||||
orbitVisualizer.render(time);
|
orbitVis.render(time);
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
#include "particlevisualizer.hpp"
|
#include "particlevisualizer.hpp"
|
||||||
|
|
||||||
ParticleVisualizer::ParticleVisualizer(Particle& particle, GLuint sphereShaderProgram, GLuint widgetShaderProgram)
|
ParticleVisualizer::ParticleVisualizer(const ParticleMap& map, const std::string& particleId, float radius,
|
||||||
: _particle(particle), _sphere({0.07, 2, sphereShaderProgram}), _widget(widgetShaderProgram)
|
GLuint sphereShaderProgram, GLuint widgetShaderProgram)
|
||||||
|
: _map(map), _particleId(particleId), _sphere({radius, 2, sphereShaderProgram}), _widget(widgetShaderProgram)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleVisualizer::render(float time)
|
void ParticleVisualizer::render(float time)
|
||||||
{
|
{
|
||||||
const Orbit& orbit = _particle.getOrbit();
|
// TODO: get mean anomly from particle which has the mass!!
|
||||||
|
|
||||||
const float meanAnomaly = time;
|
const float meanAnomaly = time;
|
||||||
glm::vec3 pos = orbit.getPosition(meanAnomaly);
|
glm::vec3 pos = _map.getParticlePosition(_particleId, meanAnomaly);
|
||||||
|
|
||||||
// render widget
|
// TODO: extract widget to its own visualizer since we know it wants an orbit but we
|
||||||
glm::mat4 widgetMatrix = orbit.getLookAlongMatrix(time);
|
// might not have one here
|
||||||
_widget.setModelMatrix(widgetMatrix);
|
//// render widget
|
||||||
_widget.render(time);
|
//const Orbit& orbit = _map.getOrbit(_particleId);
|
||||||
|
//glm::mat4 widgetMatrix = orbit.getLookAlongMatrix(time);
|
||||||
|
//_widget.setModelMatrix(widgetMatrix);
|
||||||
|
//_widget.render(time);
|
||||||
|
|
||||||
// render sphere
|
// render sphere
|
||||||
_sphere.setPosition(pos);
|
_sphere.setPosition(pos);
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
#include "widget.hpp"
|
#include "widget.hpp"
|
||||||
#include "icosphere.hpp"
|
#include "icosphere.hpp"
|
||||||
|
|
||||||
#include <skein/particle.h>
|
#include <skein/particlemap.h>
|
||||||
|
|
||||||
class ParticleVisualizer
|
class ParticleVisualizer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ParticleVisualizer(Particle& particle, GLuint sphereShaderProgram, GLuint widgetShaderProgram);
|
ParticleVisualizer(const ParticleMap& map, const std::string& particleId, float radius, GLuint sphereShaderProgram, GLuint widgetShaderProgram);
|
||||||
~ParticleVisualizer() = default;
|
~ParticleVisualizer() = default;
|
||||||
|
|
||||||
void render(float time);
|
void render(float time);
|
||||||
|
@ -16,7 +16,8 @@ class ParticleVisualizer
|
||||||
private:
|
private:
|
||||||
void updateModelMatrix();
|
void updateModelMatrix();
|
||||||
|
|
||||||
Particle& _particle;
|
const ParticleMap& _map;
|
||||||
|
const std::string& _particleId;
|
||||||
Icosphere _sphere;
|
Icosphere _sphere;
|
||||||
Widget _widget;
|
Widget _widget;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue