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/gfx.cpp
|
||||
src/orbitvisualizer.cpp
|
||||
src/orbitervisualizer.cpp
|
||||
src/orbiter.cpp
|
||||
src/widget.cpp
|
||||
)
|
||||
|
|
|
@ -9,18 +9,26 @@ typedef std::vector<float> Vector6;
|
|||
class Orbit
|
||||
{
|
||||
public:
|
||||
Orbit(float semiMajorAxis, float eccentricity, float inclination,
|
||||
float argumentOfPeriapsis, float longitudeOfAscendingNode);
|
||||
Orbit();
|
||||
~Orbit() = default;
|
||||
|
||||
float getSemiMajorAxis() const;
|
||||
float getEccentricity() const;
|
||||
float getInclination() const;
|
||||
float getArgumentOfPeriapsis() const;
|
||||
float getLongitudeOfAscendingNode() const;
|
||||
|
||||
void setSemiMajorAxis(float semiMajorAxis);
|
||||
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,
|
||||
// will have to change that when adding non-ellipctical orbits - don't get confused!
|
||||
const glm::vec3 getPosition(const float meanAnomaly) const;
|
||||
glm::vec3 getTangent(const float meanAnomaly);
|
||||
glm::mat4 getLookAlongMatrix(const float meanAnomaly);
|
||||
glm::vec3 getPosition(const float meanAnomaly) const;
|
||||
glm::vec3 getTangent(const float meanAnomaly) const;
|
||||
glm::mat4 getLookAlongMatrix(const float meanAnomaly) const;
|
||||
|
||||
private:
|
||||
Vector6 _keplerianElements;
|
||||
|
|
|
@ -5,28 +5,57 @@
|
|||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
Orbit::Orbit(float semiMajorAxis, float eccentricity, float inclination,
|
||||
float argumentOfPeriapsis, float longitudeOfAscendingNode)
|
||||
Orbit::Orbit()
|
||||
{
|
||||
_keplerianElements.resize(6);
|
||||
}
|
||||
|
||||
float Orbit::getSemiMajorAxis() const
|
||||
{
|
||||
return _keplerianElements[astro::semiMajorAxisIndex];
|
||||
}
|
||||
void Orbit::setSemiMajorAxis(float 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
|
||||
{
|
||||
return _keplerianElements[astro::eccentricityIndex];
|
||||
}
|
||||
|
||||
void Orbit::setEccentricity(float 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);
|
||||
|
||||
|
@ -60,7 +89,7 @@ const float Orbit::getEccentricAnomaly(const float meanAnomaly) const
|
|||
|
||||
// Interpolate a position around the orbit.
|
||||
// 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);
|
||||
return glm::vec3(
|
||||
|
@ -85,7 +114,7 @@ const Vector6 Orbit::getCartesianCoordinates(const float meanAnomaly) const
|
|||
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;
|
||||
glm::vec3 ahead = getPosition(meanAnomaly + epsilon);
|
||||
|
|
41
src/main.cpp
41
src/main.cpp
|
@ -42,6 +42,7 @@
|
|||
#include "gfx.hpp"
|
||||
#include "icosphere.hpp"
|
||||
#include "orbiter.hpp"
|
||||
#include "orbitervisualizer.hpp"
|
||||
#include "orbitvisualizer.hpp"
|
||||
#include "widget.hpp"
|
||||
|
||||
|
@ -94,15 +95,28 @@ int main()
|
|||
// set up scene
|
||||
Icosphere planet(0.2, 3, litProgram);
|
||||
|
||||
Orbit orbit(.75f, .5, 3.142 / 2.0 + 1, 2.0, 0);
|
||||
OrbitVisualizer orbitVisualizer(orbit, unlitProgram);
|
||||
//Orbiter orbiter(orbiterSphere, 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);
|
||||
Orbiter orbiter(orbiterSphere, orbit, unlitProgram);
|
||||
OrbiterVisualizer orbiterVisualizer(orbiter, orbiterSphere, unlitProgram);
|
||||
OrbitVisualizer orbitVisualizer(orbit, unlitProgram);
|
||||
|
||||
// register input
|
||||
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
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
|
@ -114,17 +128,30 @@ int main()
|
|||
// apply input
|
||||
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
|
||||
glClearColor(0.2, 0.3, 0.3, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
float time = glfwGetTime();
|
||||
|
||||
planet.render(time);
|
||||
orbiter.render(time);
|
||||
orbiterVisualizer.render(time);
|
||||
orbitVisualizer.render(time);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
|
|
|
@ -1,66 +1,7 @@
|
|||
#include "orbiter.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
Orbiter::Orbiter(Icosphere& sphere, Orbit& orbit, GLuint shaderProgram) :
|
||||
_sphere(sphere),
|
||||
_orbit(orbit),
|
||||
_widget(shaderProgram)
|
||||
Orbit& Orbiter::getOrbit()
|
||||
{
|
||||
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
|
||||
|
||||
#include "gfx.hpp"
|
||||
#include "icosphere.hpp"
|
||||
#include "widget.hpp"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <skein/orbit.h>
|
||||
|
||||
class Orbiter
|
||||
{
|
||||
public:
|
||||
Orbiter(Icosphere& sphere, Orbit& orbit, GLuint shaderProgram);
|
||||
~Orbiter();
|
||||
Orbiter() = default;
|
||||
~Orbiter() = default;
|
||||
|
||||
void render(const float time);
|
||||
|
||||
void cycleAnimation();
|
||||
Orbit& getOrbit();
|
||||
|
||||
private:
|
||||
void updateModelMatrix();
|
||||
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;
|
||||
Orbit _orbit;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
glGenBuffers(1, &_vbo);
|
||||
|
||||
regenerateVertices();
|
||||
}
|
||||
|
||||
void OrbitVisualizer::render(const float time)
|
||||
{
|
||||
regenerateVertices();
|
||||
|
||||
glUseProgram(_shaderProgram);
|
||||
updateModelViewProjectionMatrix(_shaderProgram, time);
|
||||
|
||||
|
|
Loading…
Reference in New Issue