Line to Spline with CatmullRom interpolation
This commit is contained in:
@@ -503,15 +503,32 @@ void Square::setup_buffers()
|
|||||||
_buffers_are_setup = true;
|
_buffers_are_setup = true;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
void Line::initSpline()
|
||||||
|
{
|
||||||
|
draw(glm::mat4x4{},
|
||||||
|
std::vector<glm::vec3>{ {}, {} },
|
||||||
|
glm::vec4{},
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
void Line::draw(glm::mat4x4 const& mvp
|
void Line::draw(glm::mat4x4 const& mvp
|
||||||
, std::vector<glm::vec3> const points
|
, std::vector<glm::vec3> const points
|
||||||
, glm::vec4 const& color
|
, glm::vec4 const& color
|
||||||
|
, bool spline
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (points.size() < 2)
|
if (points.size() < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setup_buffers(points);
|
if (!spline || points.size() == 2)
|
||||||
|
{
|
||||||
|
setup_buffers(points);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initSpline();
|
||||||
|
setup_buffers_interpolated(points);
|
||||||
|
}
|
||||||
|
|
||||||
OpenGL::Scoped::use_program line_shader{ *_program.get() };
|
OpenGL::Scoped::use_program line_shader{ *_program.get() };
|
||||||
|
|
||||||
@@ -536,6 +553,73 @@ void Square::setup_buffers()
|
|||||||
indices.push_back(i);
|
indices.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setup_shader(vertices, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Line::setup_buffers_interpolated(std::vector<glm::vec3> const points)
|
||||||
|
{
|
||||||
|
const float tension = 0.5f;
|
||||||
|
|
||||||
|
std::vector<glm::vec3> tempPoints;
|
||||||
|
tempPoints.push_back(points[0]);
|
||||||
|
|
||||||
|
for (auto const& p : points)
|
||||||
|
tempPoints.push_back(p);
|
||||||
|
|
||||||
|
tempPoints.push_back(points[points.size() - 1]);
|
||||||
|
|
||||||
|
std::vector<glm::vec3> vertices;
|
||||||
|
std::vector<std::uint16_t> indices;
|
||||||
|
|
||||||
|
for (int i = 1; i < tempPoints.size() - 2; i++)
|
||||||
|
{
|
||||||
|
auto s = tension * 2.f;
|
||||||
|
auto p0 = tempPoints[i - 1];
|
||||||
|
auto p1 = tempPoints[i + 0];
|
||||||
|
auto p2 = tempPoints[i + 1];
|
||||||
|
auto p3 = tempPoints[i + 2];
|
||||||
|
|
||||||
|
glm::vec3 m1(
|
||||||
|
(p2.x - p0.x) / s,
|
||||||
|
(p2.y - p0.y) / s,
|
||||||
|
(p2.z - p0.z) / s
|
||||||
|
);
|
||||||
|
|
||||||
|
glm::vec3 m2(
|
||||||
|
(p3.x - p1.x) / s,
|
||||||
|
(p3.y - p1.y) / s,
|
||||||
|
(p3.z - p1.z) / s
|
||||||
|
);
|
||||||
|
|
||||||
|
vertices.push_back(interpolate(0, p1, p2, m1, m2));
|
||||||
|
|
||||||
|
for (float t = 0.01f; t < 1.f; t += 0.01f)
|
||||||
|
vertices.push_back(interpolate(t, p1, p2, m1, m2));
|
||||||
|
|
||||||
|
vertices.push_back(interpolate(1, p1, p2, m1, m2));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < vertices.size(); ++i)
|
||||||
|
{
|
||||||
|
indices.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_shader(vertices, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Line::interpolate(float t, glm::vec3 p0, glm::vec3 p1, glm::vec3 m0, glm::vec3 m1)
|
||||||
|
{
|
||||||
|
auto c = 2 * t * t * t - 3 * t * t;
|
||||||
|
auto c0 = c + 1;
|
||||||
|
auto c1 = t * t * t - 2 * t * t + t;
|
||||||
|
auto c2 = -c;
|
||||||
|
auto c3 = t * t * t - t * t;
|
||||||
|
|
||||||
|
return (c0 * p0 + c1 * m0 + c2 * p1 + c3 * m1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Line::setup_shader(std::vector<glm::vec3> vertices, std::vector<std::uint16_t> indices)
|
||||||
|
{
|
||||||
_indice_count = (int)indices.size();
|
_indice_count = (int)indices.size();
|
||||||
_program.reset(new OpenGL::program(
|
_program.reset(new OpenGL::program(
|
||||||
{
|
{
|
||||||
@@ -544,8 +628,8 @@ void Square::setup_buffers()
|
|||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
gl.bufferData<GL_ARRAY_BUFFER, glm::vec3> (_vertices_vbo, vertices, GL_STATIC_DRAW);
|
gl.bufferData<GL_ARRAY_BUFFER, glm::vec3>(_vertices_vbo, vertices, GL_STATIC_DRAW);
|
||||||
gl.bufferData<GL_ELEMENT_ARRAY_BUFFER, std::uint16_t> (_indices_vbo, indices, GL_STATIC_DRAW);
|
gl.bufferData<GL_ELEMENT_ARRAY_BUFFER, std::uint16_t>(_indices_vbo, indices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
OpenGL::Scoped::index_buffer_manual_binder indices_binder(_indices_vbo);
|
OpenGL::Scoped::index_buffer_manual_binder indices_binder(_indices_vbo);
|
||||||
OpenGL::Scoped::use_program shader(*_program.get());
|
OpenGL::Scoped::use_program shader(*_program.get());
|
||||||
|
|||||||
@@ -157,14 +157,20 @@ namespace Noggit::Rendering::Primitives
|
|||||||
class Line
|
class Line
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void draw(glm::mat4x4 const& mvp, std::vector<glm::vec3> const points, glm::vec4 const& color);
|
void initSpline();
|
||||||
|
void draw(glm::mat4x4 const& mvp, std::vector<glm::vec3> const points, glm::vec4 const& color, bool spline);
|
||||||
void unload();
|
void unload();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _buffers_are_setup = false;
|
bool _buffers_are_setup = false;
|
||||||
void setup_buffers(std::vector<glm::vec3> const points);
|
void setup_buffers(std::vector<glm::vec3> const points);
|
||||||
|
|
||||||
|
void setup_buffers_interpolated(std::vector<glm::vec3> const points);
|
||||||
|
glm::vec3 interpolate(float t, glm::vec3 p0, glm::vec3 p1, glm::vec3 m0, glm::vec3 m1);
|
||||||
|
|
||||||
int _indice_count = 0;
|
int _indice_count = 0;
|
||||||
|
|
||||||
|
void setup_shader(std::vector<glm::vec3> vertices, std::vector<std::uint16_t> indices);
|
||||||
OpenGL::Scoped::deferred_upload_vertex_arrays<1> _vao;
|
OpenGL::Scoped::deferred_upload_vertex_arrays<1> _vao;
|
||||||
OpenGL::Scoped::deferred_upload_buffers<2> _buffers;
|
OpenGL::Scoped::deferred_upload_buffers<2> _buffers;
|
||||||
GLuint const& _vertices_vbo = _buffers[0];
|
GLuint const& _vertices_vbo = _buffers[0];
|
||||||
|
|||||||
Reference in New Issue
Block a user