feat(widget): draw axis widget aligned to orbit
This commit is contained in:
parent
9f2c05bf6f
commit
2384028542
|
@ -30,6 +30,7 @@ add_executable(${PROJECT_NAME}
|
||||||
src/icosphere.cpp
|
src/icosphere.cpp
|
||||||
src/gfx.cpp
|
src/gfx.cpp
|
||||||
src/orbit.cpp
|
src/orbit.cpp
|
||||||
|
src/widget.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "gfx.hpp"
|
#include "gfx.hpp"
|
||||||
#include "icosphere.hpp"
|
#include "icosphere.hpp"
|
||||||
#include "orbit.hpp"
|
#include "orbit.hpp"
|
||||||
|
#include "widget.hpp"
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
@ -55,6 +56,8 @@ int main()
|
||||||
Icosphere orbiter(0.07, 2, litProgram);
|
Icosphere orbiter(0.07, 2, litProgram);
|
||||||
Orbit orbit(100);
|
Orbit orbit(100);
|
||||||
|
|
||||||
|
Widget widget(orbit, unlitProgram);
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
|
@ -77,6 +80,7 @@ int main()
|
||||||
glUseProgram(unlitProgram);
|
glUseProgram(unlitProgram);
|
||||||
updateModelViewProjectionMatrix(unlitProgram, time);
|
updateModelViewProjectionMatrix(unlitProgram, time);
|
||||||
orbit.render();
|
orbit.render();
|
||||||
|
widget.render();
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
|
@ -65,6 +65,14 @@ glm::vec3 Orbit::getPosition(const float meanAnomaly)
|
||||||
cartesian[astro::zPositionIndex]);
|
cartesian[astro::zPositionIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Orbit::getTangent(const float meanAnomaly)
|
||||||
|
{
|
||||||
|
float epsilon = 0.01;
|
||||||
|
glm::vec3 ahead = getPosition(meanAnomaly + epsilon);
|
||||||
|
glm::vec3 behind = getPosition(meanAnomaly - epsilon);
|
||||||
|
return glm::normalize(ahead - behind);
|
||||||
|
}
|
||||||
|
|
||||||
void Orbit::render()
|
void Orbit::render()
|
||||||
{
|
{
|
||||||
glBindVertexArray(_vao);
|
glBindVertexArray(_vao);
|
||||||
|
|
|
@ -12,6 +12,7 @@ public:
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
glm::vec3 getPosition(const float meanAnomaly);
|
glm::vec3 getPosition(const float meanAnomaly);
|
||||||
|
glm::vec3 getTangent(const float meanAnomaly);
|
||||||
|
|
||||||
~Orbit();
|
~Orbit();
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include "widget.hpp"
|
||||||
|
#include "gfx.hpp"
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
Widget::Widget(Orbit& orbit, GLuint shaderProgram) :
|
||||||
|
_orbit(orbit),
|
||||||
|
_shaderProgram(shaderProgram)
|
||||||
|
{
|
||||||
|
const float lineLength = 0.1;
|
||||||
|
for (int i = 0; i < 3*6; i++)
|
||||||
|
{
|
||||||
|
_vertices[i] *= _lineLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &_vao);
|
||||||
|
glGenBuffers(1, &_vbo);
|
||||||
|
|
||||||
|
glBindVertexArray(_vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||||
|
size_t v3Size = 3 * sizeof(float);
|
||||||
|
size_t lineSize = 2 * sizeof(float);
|
||||||
|
size_t vboBufferSize = v3Size * lineSize * 3;
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, vboBufferSize, &_vertices[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::render()
|
||||||
|
{
|
||||||
|
updateModelMatrix();
|
||||||
|
|
||||||
|
glBindVertexArray(_vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||||
|
glDrawArrays(GL_LINES, 0, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::updateModelMatrix()
|
||||||
|
{
|
||||||
|
float p = glfwGetTime();
|
||||||
|
|
||||||
|
_position = _orbit.getPosition(p);
|
||||||
|
|
||||||
|
// get the tangent of the orbital ellipse
|
||||||
|
glm::vec3 tan = _orbit.getTangent(p);
|
||||||
|
// we want to point along the orbit
|
||||||
|
glm::vec3 target = _position + tan;
|
||||||
|
// 'up' is just the normalized position vector because the orbit is centred at the origin
|
||||||
|
glm::vec3 up = glm::normalize(_position);
|
||||||
|
// easy peasy lookAt matrix
|
||||||
|
glm::mat4 look = glm::lookAt(_position, target, up);
|
||||||
|
|
||||||
|
// invert the lookat matrix because it's meant for cameras, cameras work backwards and
|
||||||
|
// we are not a camera
|
||||||
|
glm::mat4 model = glm::inverse(look);
|
||||||
|
|
||||||
|
GLint modelLocation = getShaderUniformLocation(_shaderProgram, "_Model");
|
||||||
|
glUniformMatrix4fv(modelLocation, 1, GL_FALSE, &model[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget::~Widget()
|
||||||
|
{
|
||||||
|
glDeleteVertexArrays(1, &_vao);
|
||||||
|
glDeleteBuffers(1, &_vbo);
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "orbit.hpp"
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class Widget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// A widget is renderer at a point on the orbit.
|
||||||
|
// It consists of 3 orthagonally intersecting lines.
|
||||||
|
|
||||||
|
Widget(Orbit& orbit, GLuint shaderProgram);
|
||||||
|
void render();
|
||||||
|
|
||||||
|
void setPosition(glm::vec3 position);
|
||||||
|
~Widget();
|
||||||
|
private:
|
||||||
|
Orbit& _orbit;
|
||||||
|
glm::vec3 _position;
|
||||||
|
|
||||||
|
GLuint _vao;
|
||||||
|
GLuint _vbo;
|
||||||
|
GLuint _shaderProgram;
|
||||||
|
|
||||||
|
void updateModelMatrix();
|
||||||
|
|
||||||
|
float _lineLength = 0.2;
|
||||||
|
float _vertices[3*6] =
|
||||||
|
{
|
||||||
|
-1, 0, 0,
|
||||||
|
1, 0, 0,
|
||||||
|
0, 1, 0,
|
||||||
|
0,-1, 0,
|
||||||
|
0, 0, 1,
|
||||||
|
0, 0,-1
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue