mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 12:02:47 -05:00
Refactor Slice / SliceRenderer to be less general; get away from "prop" overhead.
This commit is contained in:
@@ -15,7 +15,7 @@ add_custom_command(
|
|||||||
add_definitions(${NANOGUI_EXTRA_DEFS})
|
add_definitions(${NANOGUI_EXTRA_DEFS})
|
||||||
include_directories(${NANOGUI_EXTRA_INCS})
|
include_directories(${NANOGUI_EXTRA_INCS})
|
||||||
|
|
||||||
add_executable(vis-gui src/main-gui.cpp)
|
add_executable(vis src/main.cpp)
|
||||||
target_include_directories(vis-gui PRIVATE include)
|
target_include_directories(vis PRIVATE include)
|
||||||
target_link_libraries(vis-gui PRIVATE tc nanogui yaml-cpp ${NANOGUI_EXTRA_LIBS})
|
target_link_libraries(vis PRIVATE tc nanogui yaml-cpp ${NANOGUI_EXTRA_LIBS})
|
||||||
add_dependencies(vis-gui shaders presets)
|
add_dependencies(vis shaders presets)
|
||||||
|
|||||||
@@ -7,6 +7,33 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "combo_iterator.hpp"
|
#include "combo_iterator.hpp"
|
||||||
|
|
||||||
|
template<int N>
|
||||||
|
using vec = Eigen::Matrix<float, N, 1>;
|
||||||
|
template<int N>
|
||||||
|
using mat = Eigen::Matrix<float, N, N>;
|
||||||
|
|
||||||
|
using vec1 = vec<1>;
|
||||||
|
using vec2 = vec<2>;
|
||||||
|
using vec3 = vec<3>;
|
||||||
|
using vec4 = vec<4>;
|
||||||
|
using vec5 = vec<5>;
|
||||||
|
|
||||||
|
using mat1 = mat<1>;
|
||||||
|
using mat2 = mat<2>;
|
||||||
|
using mat3 = mat<3>;
|
||||||
|
using mat4 = mat<4>;
|
||||||
|
using mat5 = mat<5>;
|
||||||
|
|
||||||
|
mat4 ortho(float left, float right, float bottom, float top, float front, float back) {
|
||||||
|
mat<4> res = mat4();
|
||||||
|
res <<
|
||||||
|
2 / (right - left), 0, 0, -(right + left) / (right - left),
|
||||||
|
0, 2 / (top - bottom), 0, -(top + bottom) / (top - bottom),
|
||||||
|
0, 0, 2 / (front - back), -(front + back) / (front - back),
|
||||||
|
0, 0, 0, 1;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An primitive stage N indices.
|
* An primitive stage N indices.
|
||||||
* @tparam N
|
* @tparam N
|
||||||
|
|||||||
@@ -8,22 +8,7 @@
|
|||||||
|
|
||||||
#include <nanogui/glutil.h>
|
#include <nanogui/glutil.h>
|
||||||
|
|
||||||
template<int N>
|
#include <geometry.hpp>
|
||||||
using vec = Eigen::Matrix<float, N, 1>;
|
|
||||||
template<int N>
|
|
||||||
using mat = Eigen::Matrix<float, N, N>;
|
|
||||||
|
|
||||||
using vec1 = vec<1>;
|
|
||||||
using vec2 = vec<2>;
|
|
||||||
using vec3 = vec<3>;
|
|
||||||
using vec4 = vec<4>;
|
|
||||||
using vec5 = vec<5>;
|
|
||||||
|
|
||||||
using mat1 = mat<1>;
|
|
||||||
using mat2 = mat<2>;
|
|
||||||
using mat3 = mat<3>;
|
|
||||||
using mat4 = mat<4>;
|
|
||||||
using mat5 = mat<5>;
|
|
||||||
|
|
||||||
template<class V>
|
template<class V>
|
||||||
float dot(int n, const V &a, const V &b) {
|
float dot(int n, const V &a, const V &b) {
|
||||||
@@ -143,13 +128,3 @@ mat<N> rot(int u, int v, float theta) {
|
|||||||
res(v, v) = std::cos(theta);
|
res(v, v) = std::cos(theta);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
mat4 ortho(float left, float right, float bottom, float top, float front, float back) {
|
|
||||||
mat<4> res = mat4();
|
|
||||||
res <<
|
|
||||||
2 / (right - left), 0, 0, -(right + left) / (right - left),
|
|
||||||
0, 2 / (top - bottom), 0, -(top + bottom) / (top - bottom),
|
|
||||||
0, 0, 2 / (front - back), -(front + back) / (front - back),
|
|
||||||
0, 0, 0, 1;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
@@ -3,26 +3,75 @@
|
|||||||
#include <cgl/vertexarray.hpp>
|
#include <cgl/vertexarray.hpp>
|
||||||
#include <cgl/buffer.hpp>
|
#include <cgl/buffer.hpp>
|
||||||
#include <cgl/pipeline.hpp>
|
#include <cgl/pipeline.hpp>
|
||||||
|
|
||||||
#include <geometry.hpp>
|
#include <geometry.hpp>
|
||||||
|
#include "mirror.hpp"
|
||||||
|
|
||||||
#include <tuple>
|
struct Matrices {
|
||||||
|
mat4 proj = mat4::Identity();
|
||||||
|
mat4 view = mat4::Identity();
|
||||||
|
|
||||||
template<unsigned N, class... T>
|
Matrices() = default;
|
||||||
struct Prop {
|
|
||||||
cgl::VertexArray vao;
|
Matrices(mat4 proj, mat4 view) : proj(std::move(proj)), view(std::move(view)) {}
|
||||||
std::tuple<cgl::Buffer<T>...> vbos;
|
|
||||||
|
static Matrices build(const nanogui::Screen &screen) {
|
||||||
|
auto aspect = (float) screen.width() / (float) screen.height();
|
||||||
|
auto pheight = 1.4f;
|
||||||
|
auto pwidth = aspect * pheight;
|
||||||
|
mat4 proj = ortho(-pwidth, pwidth, -pheight, pheight, -10.0f, 10.0f);
|
||||||
|
|
||||||
|
auto view = mat4::Identity();
|
||||||
|
return Matrices(proj, view);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Renderer {
|
||||||
|
public:
|
||||||
|
virtual void draw(const T &prop) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<unsigned N>
|
||||||
|
class Slice {
|
||||||
|
private:
|
||||||
|
const tc::Group group;
|
||||||
|
|
||||||
|
public:
|
||||||
cgl::Buffer<Primitive<N>> ibo;
|
cgl::Buffer<Primitive<N>> ibo;
|
||||||
|
cgl::Buffer<vec4> vbo;
|
||||||
|
cgl::VertexArray vao;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Slice(const tc::Group &g, T all_sg_gens, const std::vector<std::vector<int>> &exclude) : group(g) {
|
||||||
|
ibo.put(merge<N>(hull<N>(g, all_sg_gens, exclude)));
|
||||||
|
vao.ipointer(0, ibo, 4, GL_UNSIGNED_INT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPoints(const vec5 &root, mat5 transform = mat5::Identity()) {
|
||||||
|
auto cosets = group.solve();
|
||||||
|
auto mirrors = mirror<5>(group);
|
||||||
|
|
||||||
|
auto corners = plane_intersections(mirrors);
|
||||||
|
auto start = barycentric(corners, root);
|
||||||
|
|
||||||
|
auto higher = cosets.path.walk<vec5, vec5>(start, mirrors, reflect<vec5>);
|
||||||
|
|
||||||
|
std::transform(
|
||||||
|
higher.begin(), higher.end(), higher.begin(),
|
||||||
|
[&](const vec5& v) { return transform * v; }
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<vec4> lower(higher.size());
|
||||||
|
std::transform(higher.begin(), higher.end(), lower.begin(), stereo<4>);
|
||||||
|
|
||||||
|
vbo.put(lower);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<unsigned N, class T>
|
template<unsigned N>
|
||||||
struct Renderer {
|
class SliceRenderer : public Renderer<Slice<N>> {
|
||||||
cgl::pipeline pipe;
|
private:
|
||||||
|
|
||||||
virtual void draw(const Prop<N, T> &prop) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<unsigned N, class T>
|
|
||||||
struct SliceRenderer : public Renderer<N, T> {
|
|
||||||
cgl::pgm::vert defer = cgl::pgm::vert::file(
|
cgl::pgm::vert defer = cgl::pgm::vert::file(
|
||||||
"shaders/slice/deferred.vs.glsl");
|
"shaders/slice/deferred.vs.glsl");
|
||||||
cgl::pgm::geom slice = cgl::pgm::geom::file(
|
cgl::pgm::geom slice = cgl::pgm::geom::file(
|
||||||
@@ -32,20 +81,20 @@ struct SliceRenderer : public Renderer<N, T> {
|
|||||||
|
|
||||||
cgl::pipeline pipe;
|
cgl::pipeline pipe;
|
||||||
|
|
||||||
|
cgl::Buffer<Matrices> ubo;
|
||||||
|
|
||||||
|
public:
|
||||||
SliceRenderer() {
|
SliceRenderer() {
|
||||||
pipe.stage(defer);
|
pipe.stage(defer);
|
||||||
pipe.stage(slice);
|
pipe.stage(slice);
|
||||||
pipe.stage(solid);
|
pipe.stage(solid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(const Prop<N, T> &prop) const override {
|
void draw(const Slice<N> &prop) const {
|
||||||
pipe.bound([&]() {
|
glBindProgramPipeline(pipe);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, std::get<0>(prop.vbos));
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, prop.vbo);
|
||||||
//// glProgramUniform3fv(solid, 2, 1, &prop.color.front());
|
|
||||||
glProgramUniform3f(solid, 2, 1.f, 1.f, 1.f);
|
glProgramUniform3f(solid, 2, 1.f, 1.f, 1.f);
|
||||||
prop.vao.bound([&]() {
|
glBindVertexArray(prop.vao);
|
||||||
glDrawArrays(GL_POINTS, 0, prop.ibo.count() * N);
|
glDrawArrays(GL_POINTS, 0, prop.ibo.count() * N);
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,16 +1,3 @@
|
|||||||
/*
|
|
||||||
src/example4.cpp -- C++ version of an example application that shows
|
|
||||||
how to use the OpenGL widget. For a Python implementation, see
|
|
||||||
'../python/example4.py'.
|
|
||||||
|
|
||||||
NanoGUI was developed by Wenzel Jakob <wenzel.jakob@epfl.ch>.
|
|
||||||
The widget drawing code is based on the NanoVG demo application
|
|
||||||
by Mikko Mononen.
|
|
||||||
|
|
||||||
All rights reserved. Use of this source code is governed by a
|
|
||||||
BSD-style license that can be found in the LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <nanogui/opengl.h>
|
#include <nanogui/opengl.h>
|
||||||
#include <nanogui/nanogui.h>
|
#include <nanogui/nanogui.h>
|
||||||
#include <nanogui/glutil.h>
|
#include <nanogui/glutil.h>
|
||||||
@@ -25,35 +12,7 @@
|
|||||||
#include <util.hpp>
|
#include <util.hpp>
|
||||||
#include <tc/groups.hpp>
|
#include <tc/groups.hpp>
|
||||||
|
|
||||||
struct Matrices {
|
mat5 wander(float time) {
|
||||||
mat4 proj = mat4::Identity();
|
|
||||||
mat4 view = mat4::Identity();
|
|
||||||
|
|
||||||
Matrices() = default;
|
|
||||||
|
|
||||||
Matrices(mat4 proj, mat4 view) : proj(std::move(proj)), view(std::move(view)) {}
|
|
||||||
|
|
||||||
static Matrices build(const nanogui::Screen &screen) {
|
|
||||||
auto aspect = (float) screen.width() / (float) screen.height();
|
|
||||||
auto pheight = 1.4f;
|
|
||||||
auto pwidth = aspect * pheight;
|
|
||||||
mat4 proj = ortho(-pwidth, pwidth, -pheight, pheight, -10.0f, 10.0f);
|
|
||||||
|
|
||||||
auto view = mat4::Identity();
|
|
||||||
return Matrices(proj, view);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class C>
|
|
||||||
std::vector<vec4> points(const tc::Group &group, const C &coords, const float time) {
|
|
||||||
auto cosets = group.solve();
|
|
||||||
auto mirrors = mirror<5>(group);
|
|
||||||
|
|
||||||
auto corners = plane_intersections(mirrors);
|
|
||||||
auto start = barycentric(corners, coords);
|
|
||||||
|
|
||||||
auto higher = cosets.path.walk<vec5, vec5>(start, mirrors, reflect<vec5>);
|
|
||||||
|
|
||||||
mat5 r = mat5::Identity();
|
mat5 r = mat5::Identity();
|
||||||
r *= rot<5>(0, 2, time * .21f);
|
r *= rot<5>(0, 2, time * .21f);
|
||||||
// r *= rot<5>(1, 4, time * .27f);
|
// r *= rot<5>(1, 4, time * .27f);
|
||||||
@@ -62,37 +21,18 @@ std::vector<vec4> points(const tc::Group &group, const C &coords, const float ti
|
|||||||
r *= rot<5>(1, 3, time * .25f);
|
r *= rot<5>(1, 3, time * .25f);
|
||||||
r *= rot<5>(2, 3, time * .12f);
|
r *= rot<5>(2, 3, time * .12f);
|
||||||
|
|
||||||
std::transform(higher.begin(), higher.end(), higher.begin(), [&](vec5 v) { return r * v; });
|
return r;
|
||||||
|
|
||||||
std::vector<vec4> lower(higher.size());
|
|
||||||
std::transform(higher.begin(), higher.end(), lower.begin(), stereo<4>);
|
|
||||||
return lower;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int N, class T, class C>
|
|
||||||
Prop<4, vec4> make_slice(
|
|
||||||
const tc::Group &g,
|
|
||||||
const C &coords,
|
|
||||||
vec3 color,
|
|
||||||
T all_sg_gens,
|
|
||||||
const std::vector<std::vector<int>> &exclude
|
|
||||||
) {
|
|
||||||
Prop<N, vec4> res{};
|
|
||||||
|
|
||||||
// res.vbo.put(points(g, coords));
|
|
||||||
res.ibo.put(merge<N>(hull<N>(g, all_sg_gens, exclude)));
|
|
||||||
res.vao.ipointer(0, res.ibo, 4, GL_UNSIGNED_INT);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExampleApplication : public nanogui::Screen {
|
class ExampleApplication : public nanogui::Screen {
|
||||||
public:
|
public:
|
||||||
vec5 root;
|
vec5 root;
|
||||||
std::unique_ptr<tc::Group> group;
|
|
||||||
std::unique_ptr<Prop<4, vec4>> prop;
|
// std::unique_ptr<tc::Group> group;
|
||||||
|
std::unique_ptr<SliceRenderer<4>> ren;
|
||||||
std::unique_ptr<cgl::Buffer<Matrices>> ubo;
|
std::unique_ptr<cgl::Buffer<Matrices>> ubo;
|
||||||
std::unique_ptr<SliceRenderer<4, vec4>> ren;
|
|
||||||
|
std::unique_ptr<Slice<4>> slice;
|
||||||
|
|
||||||
float glfw_time = 0;
|
float glfw_time = 0;
|
||||||
float last_frame = 0;
|
float last_frame = 0;
|
||||||
@@ -123,19 +63,19 @@ public:
|
|||||||
|
|
||||||
std::cout << utilInfo();
|
std::cout << utilInfo();
|
||||||
|
|
||||||
std::vector<int> symbol = {5, 3, 3, 2};
|
std::vector<int> symbol = {3, 4, 3, 2};
|
||||||
root << .80, .02, .02, .02, .02;
|
root << .80, .02, .02, .02, .02;
|
||||||
|
|
||||||
group = std::make_unique<tc::Group>(tc::schlafli(symbol));
|
auto group = tc::schlafli(symbol);
|
||||||
auto gens = generators(*group);
|
|
||||||
std::vector<std::vector<int>> exclude = {{0, 1, 2}};
|
|
||||||
auto combos = Combos<int>(gens, 3);
|
|
||||||
|
|
||||||
prop = std::make_unique<Prop<4, vec4>>(make_slice<4>(*group, root, {}, combos, exclude));
|
auto gens = generators(group);
|
||||||
|
auto combos = Combos<int>(gens, 3);
|
||||||
|
std::vector<std::vector<int>> exclude = {{0, 1, 2}};
|
||||||
|
|
||||||
|
slice = std::make_unique<Slice<4>>(group, combos, exclude);
|
||||||
|
ren = std::make_unique<SliceRenderer<4>>();
|
||||||
|
|
||||||
ubo = std::make_unique<cgl::Buffer<Matrices>>();
|
ubo = std::make_unique<cgl::Buffer<Matrices>>();
|
||||||
|
|
||||||
ren = std::make_unique<SliceRenderer<4, vec4>>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawContents() override {
|
void drawContents() override {
|
||||||
@@ -154,16 +94,17 @@ public:
|
|||||||
last_frame = glfw_time;
|
last_frame = glfw_time;
|
||||||
if (!paused) time += frame_time;
|
if (!paused) time += frame_time;
|
||||||
|
|
||||||
std::get<0>(prop->vbos).put(points(*group, root, time));
|
auto rotation = wander(time);
|
||||||
|
slice->setPoints(root, rotation);
|
||||||
|
|
||||||
Matrices mats = Matrices::build(*this);
|
Matrices mats = Matrices::build(*this);
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 1, *ubo);
|
glBindBufferBase(GL_UNIFORM_BUFFER, 1, *ubo);
|
||||||
ubo->put(mats);
|
ubo->put(mats);
|
||||||
ren->draw(*prop);
|
ren->draw(*slice);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int /* argc */, char ** /* argv */) {
|
int main(int argc, char ** argv) {
|
||||||
try {
|
try {
|
||||||
nanogui::init();
|
nanogui::init();
|
||||||
|
|
||||||
Reference in New Issue
Block a user