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/gfx.cpp
|
||||
src/orbit.cpp
|
||||
src/widget.cpp
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "gfx.hpp"
|
||||
#include "icosphere.hpp"
|
||||
#include "orbit.hpp"
|
||||
#include "widget.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -55,6 +56,8 @@ int main()
|
|||
Icosphere orbiter(0.07, 2, litProgram);
|
||||
Orbit orbit(100);
|
||||
|
||||
Widget widget(orbit, unlitProgram);
|
||||
|
||||
// Main loop
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
|
@ -77,6 +80,7 @@ int main()
|
|||
glUseProgram(unlitProgram);
|
||||
updateModelViewProjectionMatrix(unlitProgram, time);
|
||||
orbit.render();
|
||||
widget.render();
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
|
|
|
@ -65,6 +65,14 @@ glm::vec3 Orbit::getPosition(const float meanAnomaly)
|
|||
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()
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
|
|
|
@ -12,6 +12,7 @@ public:
|
|||
void render();
|
||||
|
||||
glm::vec3 getPosition(const float meanAnomaly);
|
||||
glm::vec3 getTangent(const float meanAnomaly);
|
||||
|
||||
~Orbit();
|
||||
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