feat: add particle map
This commit is contained in:
		
							parent
							
								
									a5ff616e86
								
							
						
					
					
						commit
						56aa50251b
					
				
							
								
								
									
										9
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								lib/skein/include/skein/particlemap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								lib/skein/include/skein/particlemap.h
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								lib/skein/src/particlemap.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								lib/skein/src/particlemap.cpp
									
									
									
									
									
										Normal file
									
								
							@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user