refactor: extract OrbiterVisualizer class
This commit is contained in:
parent
129d65c31e
commit
bb9b8320ec
|
@ -32,6 +32,7 @@ add_executable(${PROJECT_NAME}
|
||||||
src/icosphere.cpp
|
src/icosphere.cpp
|
||||||
src/gfx.cpp
|
src/gfx.cpp
|
||||||
src/orbitvisualizer.cpp
|
src/orbitvisualizer.cpp
|
||||||
|
src/orbitervisualizer.cpp
|
||||||
src/orbiter.cpp
|
src/orbiter.cpp
|
||||||
src/widget.cpp
|
src/widget.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,18 +9,26 @@ typedef std::vector<float> Vector6;
|
||||||
class Orbit
|
class Orbit
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Orbit(float semiMajorAxis, float eccentricity, float inclination,
|
Orbit();
|
||||||
float argumentOfPeriapsis, float longitudeOfAscendingNode);
|
|
||||||
~Orbit() = default;
|
~Orbit() = default;
|
||||||
|
|
||||||
|
float getSemiMajorAxis() const;
|
||||||
float getEccentricity() const;
|
float getEccentricity() const;
|
||||||
|
float getInclination() const;
|
||||||
|
float getArgumentOfPeriapsis() const;
|
||||||
|
float getLongitudeOfAscendingNode() const;
|
||||||
|
|
||||||
|
void setSemiMajorAxis(float semiMajorAxis);
|
||||||
void setEccentricity(float eccentricity);
|
void setEccentricity(float eccentricity);
|
||||||
|
void setInclination(float inclination);
|
||||||
|
void setArgumentOfPeriapsis(float argumentOfPeriapsis);
|
||||||
|
void setLongitudeOfAscendingNode(float longitudeOfAscendingNode);
|
||||||
|
|
||||||
// TODO: meanAnomaly in all these arguments actually means eccentricMeanAnomaly,
|
// TODO: meanAnomaly in all these arguments actually means eccentricMeanAnomaly,
|
||||||
// will have to change that when adding non-ellipctical orbits - don't get confused!
|
// will have to change that when adding non-ellipctical orbits - don't get confused!
|
||||||
const glm::vec3 getPosition(const float meanAnomaly) const;
|
glm::vec3 getPosition(const float meanAnomaly) const;
|
||||||
glm::vec3 getTangent(const float meanAnomaly);
|
glm::vec3 getTangent(const float meanAnomaly) const;
|
||||||
glm::mat4 getLookAlongMatrix(const float meanAnomaly);
|
glm::mat4 getLookAlongMatrix(const float meanAnomaly) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector6 _keplerianElements;
|
Vector6 _keplerianElements;
|
||||||
|
|
|
@ -5,28 +5,57 @@
|
||||||
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
Orbit::Orbit(float semiMajorAxis, float eccentricity, float inclination,
|
Orbit::Orbit()
|
||||||
float argumentOfPeriapsis, float longitudeOfAscendingNode)
|
|
||||||
{
|
{
|
||||||
_keplerianElements.resize(6);
|
_keplerianElements.resize(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Orbit::getSemiMajorAxis() const
|
||||||
|
{
|
||||||
|
return _keplerianElements[astro::semiMajorAxisIndex];
|
||||||
|
}
|
||||||
|
void Orbit::setSemiMajorAxis(float semiMajorAxis)
|
||||||
|
{
|
||||||
_keplerianElements[astro::semiMajorAxisIndex] = semiMajorAxis;
|
_keplerianElements[astro::semiMajorAxisIndex] = semiMajorAxis;
|
||||||
_keplerianElements[astro::eccentricityIndex] = eccentricity;
|
|
||||||
_keplerianElements[astro::inclinationIndex] = inclination;
|
|
||||||
_keplerianElements[astro::argumentOfPeriapsisIndex] = argumentOfPeriapsis;
|
|
||||||
_keplerianElements[astro::longitudeOfAscendingNodeIndex] = semiMajorAxis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Orbit::getEccentricity() const
|
float Orbit::getEccentricity() const
|
||||||
{
|
{
|
||||||
return _keplerianElements[astro::eccentricityIndex];
|
return _keplerianElements[astro::eccentricityIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Orbit::setEccentricity(float eccentricity)
|
void Orbit::setEccentricity(float eccentricity)
|
||||||
{
|
{
|
||||||
_keplerianElements[astro::eccentricityIndex] = eccentricity;
|
_keplerianElements[astro::eccentricityIndex] = eccentricity;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Orbit::getLookAlongMatrix(const float meanAnomaly)
|
float Orbit::getInclination() const
|
||||||
|
{
|
||||||
|
return _keplerianElements[astro::inclinationIndex];
|
||||||
|
}
|
||||||
|
void Orbit::setInclination(float inclination)
|
||||||
|
{
|
||||||
|
_keplerianElements[astro::inclinationIndex] = inclination;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Orbit::getArgumentOfPeriapsis() const
|
||||||
|
{
|
||||||
|
return _keplerianElements[astro::argumentOfPeriapsisIndex];
|
||||||
|
}
|
||||||
|
void Orbit::setArgumentOfPeriapsis(float argumentOfPeriapsis)
|
||||||
|
{
|
||||||
|
_keplerianElements[astro::argumentOfPeriapsisIndex] = argumentOfPeriapsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Orbit::getLongitudeOfAscendingNode() const
|
||||||
|
{
|
||||||
|
return _keplerianElements[astro::longitudeOfAscendingNodeIndex];
|
||||||
|
}
|
||||||
|
void Orbit::setLongitudeOfAscendingNode(float longitudeOfAscendingNode)
|
||||||
|
{
|
||||||
|
_keplerianElements[astro::longitudeOfAscendingNodeIndex] = longitudeOfAscendingNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 Orbit::getLookAlongMatrix(const float meanAnomaly) const
|
||||||
{
|
{
|
||||||
glm::vec3 position = getPosition(meanAnomaly);
|
glm::vec3 position = getPosition(meanAnomaly);
|
||||||
|
|
||||||
|
@ -60,7 +89,7 @@ const float Orbit::getEccentricAnomaly(const float meanAnomaly) const
|
||||||
|
|
||||||
// Interpolate a position around the orbit.
|
// Interpolate a position around the orbit.
|
||||||
// t is in range 0..1 and wraps.
|
// t is in range 0..1 and wraps.
|
||||||
const glm::vec3 Orbit::getPosition(const float meanAnomaly) const
|
glm::vec3 Orbit::getPosition(const float meanAnomaly) const
|
||||||
{
|
{
|
||||||
Vector6 cartesian = getCartesianCoordinates(meanAnomaly);
|
Vector6 cartesian = getCartesianCoordinates(meanAnomaly);
|
||||||
return glm::vec3(
|
return glm::vec3(
|
||||||
|
@ -85,7 +114,7 @@ const Vector6 Orbit::getCartesianCoordinates(const float meanAnomaly) const
|
||||||
return astro::convertKeplerianToCartesianElements(kepler, 1.0);
|
return astro::convertKeplerianToCartesianElements(kepler, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Orbit::getTangent(const float meanAnomaly)
|
glm::vec3 Orbit::getTangent(const float meanAnomaly) const
|
||||||
{
|
{
|
||||||
float epsilon = 0.01;
|
float epsilon = 0.01;
|
||||||
glm::vec3 ahead = getPosition(meanAnomaly + epsilon);
|
glm::vec3 ahead = getPosition(meanAnomaly + epsilon);
|
||||||
|
|
41
src/main.cpp
41
src/main.cpp
|
@ -42,6 +42,7 @@
|
||||||
#include "gfx.hpp"
|
#include "gfx.hpp"
|
||||||
#include "icosphere.hpp"
|
#include "icosphere.hpp"
|
||||||
#include "orbiter.hpp"
|
#include "orbiter.hpp"
|
||||||
|
#include "orbitervisualizer.hpp"
|
||||||
#include "orbitvisualizer.hpp"
|
#include "orbitvisualizer.hpp"
|
||||||
#include "widget.hpp"
|
#include "widget.hpp"
|
||||||
|
|
||||||
|
@ -94,15 +95,28 @@ int main()
|
||||||
// set up scene
|
// set up scene
|
||||||
Icosphere planet(0.2, 3, litProgram);
|
Icosphere planet(0.2, 3, litProgram);
|
||||||
|
|
||||||
Orbit orbit(.75f, .5, 3.142 / 2.0 + 1, 2.0, 0);
|
//Orbiter orbiter(orbiterSphere, orbit, unlitProgram);
|
||||||
OrbitVisualizer orbitVisualizer(orbit, unlitProgram);
|
Orbiter orbiter;
|
||||||
|
Orbit& orbit = orbiter.getOrbit();
|
||||||
|
orbit.setSemiMajorAxis(.75);
|
||||||
|
orbit.setEccentricity(.5);
|
||||||
|
orbit.setInclination(3.142 / 2.0 + 1);
|
||||||
|
orbit.setArgumentOfPeriapsis(2.0);
|
||||||
|
orbit.setLongitudeOfAscendingNode(0.1);
|
||||||
|
|
||||||
Icosphere orbiterSphere(0.07, 2, litProgram);
|
Icosphere orbiterSphere(0.07, 2, litProgram);
|
||||||
Orbiter orbiter(orbiterSphere, orbit, unlitProgram);
|
OrbiterVisualizer orbiterVisualizer(orbiter, orbiterSphere, unlitProgram);
|
||||||
|
OrbitVisualizer orbitVisualizer(orbit, unlitProgram);
|
||||||
|
|
||||||
// register input
|
// register input
|
||||||
glfwSetKeyCallback(window, keyCallback);
|
glfwSetKeyCallback(window, keyCallback);
|
||||||
|
|
||||||
|
// TODO: convert these to an enum
|
||||||
|
const int ANIM_ORBITING = 0;
|
||||||
|
const int ANIM_ECCENTRICITY = 1;
|
||||||
|
int animation = 0;
|
||||||
|
float time = glfwGetTime();
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
|
@ -114,17 +128,30 @@ int main()
|
||||||
// apply input
|
// apply input
|
||||||
if (input.cycleAnimation)
|
if (input.cycleAnimation)
|
||||||
{
|
{
|
||||||
orbiter.cycleAnimation();
|
animation++;
|
||||||
|
if (animation > ANIM_ECCENTRICITY)
|
||||||
|
{
|
||||||
|
animation = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only update time if playing the orbiting animation
|
||||||
|
if (animation == ANIM_ORBITING)
|
||||||
|
{
|
||||||
|
time = glfwGetTime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float e = .25 + .2 * sin(glfwGetTime());
|
||||||
|
orbit.setEccentricity(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rendering
|
// rendering
|
||||||
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);
|
||||||
|
|
||||||
float time = glfwGetTime();
|
|
||||||
|
|
||||||
planet.render(time);
|
planet.render(time);
|
||||||
orbiter.render(time);
|
orbiterVisualizer.render(time);
|
||||||
orbitVisualizer.render(time);
|
orbitVisualizer.render(time);
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
|
|
|
@ -1,66 +1,7 @@
|
||||||
#include "orbiter.hpp"
|
#include "orbiter.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
Orbit& Orbiter::getOrbit()
|
||||||
|
|
||||||
Orbiter::Orbiter(Icosphere& sphere, Orbit& orbit, GLuint shaderProgram) :
|
|
||||||
_sphere(sphere),
|
|
||||||
_orbit(orbit),
|
|
||||||
_widget(shaderProgram)
|
|
||||||
{
|
{
|
||||||
|
return _orbit;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Orbiter::getMeanAnomaly()
|
|
||||||
{
|
|
||||||
float time = glfwGetTime();
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Orbiter::cycleAnimation()
|
|
||||||
{
|
|
||||||
_animation++;
|
|
||||||
|
|
||||||
if (_animation > ANIM_ECCENTRICITY)
|
|
||||||
{
|
|
||||||
_animation = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 Orbiter::getPosition(const float time)
|
|
||||||
{
|
|
||||||
//int animation = (int)(time/ORBITAL_PERIOD) % 2 == 1;
|
|
||||||
|
|
||||||
if (_animation == ANIM_ORBITING)
|
|
||||||
return _orbit.getPosition(time);
|
|
||||||
|
|
||||||
// TODO: modify the eccentricity of the orbit with a control instead
|
|
||||||
// of an automatic animation
|
|
||||||
if (_animation == ANIM_ECCENTRICITY)
|
|
||||||
{
|
|
||||||
float e = .25 + .2 * sin(time);
|
|
||||||
_orbit.setEccentricity(e);
|
|
||||||
|
|
||||||
return _orbit.getPosition(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cerr << "unknown animation " << _animation << std::endl;
|
|
||||||
throw 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Orbiter::render(const float time)
|
|
||||||
{
|
|
||||||
const float meanAnomaly = time;
|
|
||||||
glm::vec3 pos = getPosition(meanAnomaly);
|
|
||||||
|
|
||||||
// render widget
|
|
||||||
glm::mat4 widgetMatrix = _orbit.getLookAlongMatrix(time);
|
|
||||||
_widget.setModelMatrix(widgetMatrix);
|
|
||||||
_widget.render(time);
|
|
||||||
|
|
||||||
// render sphere
|
|
||||||
_sphere.setPosition(pos);
|
|
||||||
_sphere.render(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
Orbiter::~Orbiter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,37 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "gfx.hpp"
|
|
||||||
#include "icosphere.hpp"
|
|
||||||
#include "widget.hpp"
|
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <skein/orbit.h>
|
#include <skein/orbit.h>
|
||||||
|
|
||||||
class Orbiter
|
class Orbiter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Orbiter(Icosphere& sphere, Orbit& orbit, GLuint shaderProgram);
|
Orbiter() = default;
|
||||||
~Orbiter();
|
~Orbiter() = default;
|
||||||
|
|
||||||
void render(const float time);
|
Orbit& getOrbit();
|
||||||
|
|
||||||
void cycleAnimation();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateModelMatrix();
|
Orbit _orbit;
|
||||||
float getMeanAnomaly();
|
|
||||||
glm::vec3 getPosition(const float time);
|
|
||||||
void getOrbitalElements(const float time, Vector6& keplerianElements);
|
|
||||||
|
|
||||||
Icosphere& _sphere;
|
|
||||||
Orbit& _orbit;
|
|
||||||
Widget _widget;
|
|
||||||
|
|
||||||
const float ORBITAL_PERIOD = 6.284;
|
|
||||||
|
|
||||||
// TODO: convert these to an enum
|
|
||||||
const int ANIM_ORBITING = 0;
|
|
||||||
const int ANIM_ECCENTRICITY = 1;
|
|
||||||
|
|
||||||
int _animation = ANIM_ORBITING;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "orbitervisualizer.hpp"
|
||||||
|
|
||||||
|
OrbiterVisualizer::OrbiterVisualizer(Orbiter& orbiter, Icosphere& sphere, GLuint shaderProgram)
|
||||||
|
: _orbiter(orbiter), _sphere(sphere), _widget(shaderProgram)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbiterVisualizer::render(float time)
|
||||||
|
{
|
||||||
|
const Orbit& orbit = _orbiter.getOrbit();
|
||||||
|
|
||||||
|
const float meanAnomaly = time;
|
||||||
|
glm::vec3 pos = orbit.getPosition(meanAnomaly);
|
||||||
|
|
||||||
|
// render widget
|
||||||
|
glm::mat4 widgetMatrix = orbit.getLookAlongMatrix(time);
|
||||||
|
_widget.setModelMatrix(widgetMatrix);
|
||||||
|
_widget.render(time);
|
||||||
|
|
||||||
|
// render sphere
|
||||||
|
_sphere.setPosition(pos);
|
||||||
|
_sphere.render(time);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "widget.hpp"
|
||||||
|
#include "icosphere.hpp"
|
||||||
|
#include "orbiter.hpp"
|
||||||
|
|
||||||
|
class OrbiterVisualizer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OrbiterVisualizer(Orbiter& orbiter, Icosphere& sphere, GLuint shaderProgram);
|
||||||
|
~OrbiterVisualizer() = default;
|
||||||
|
|
||||||
|
void render(float time);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateModelMatrix();
|
||||||
|
|
||||||
|
Orbiter& _orbiter;
|
||||||
|
Icosphere& _sphere;
|
||||||
|
Widget _widget;
|
||||||
|
};
|
|
@ -6,12 +6,12 @@ OrbitVisualizer::OrbitVisualizer(const Orbit& orbit, const GLuint shaderProgram)
|
||||||
{
|
{
|
||||||
glGenVertexArrays(1, &_vao);
|
glGenVertexArrays(1, &_vao);
|
||||||
glGenBuffers(1, &_vbo);
|
glGenBuffers(1, &_vbo);
|
||||||
|
|
||||||
regenerateVertices();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OrbitVisualizer::render(const float time)
|
void OrbitVisualizer::render(const float time)
|
||||||
{
|
{
|
||||||
|
regenerateVertices();
|
||||||
|
|
||||||
glUseProgram(_shaderProgram);
|
glUseProgram(_shaderProgram);
|
||||||
updateModelViewProjectionMatrix(_shaderProgram, time);
|
updateModelViewProjectionMatrix(_shaderProgram, time);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue