ENH: Click+Drag to rotate view

This commit is contained in:
David Allemang
2023-02-05 21:47:19 -05:00
parent 9dd634481c
commit 600b18a8af
2 changed files with 87 additions and 52 deletions

View File

@@ -28,8 +28,18 @@ namespace vis {
}; };
struct VBOs { struct VBOs {
struct ModelMatrix {
Eigen::Matrix4f linear;
Eigen::Vector4f translation;
};
cgl::Buffer<vec4> verts; cgl::Buffer<vec4> verts;
cgl::Buffer<Primitive<4>> ibo; cgl::Buffer<Primitive<4>> ibo;
cgl::Buffer<ModelMatrix> ubo;
using Affine4f = Eigen::Transform<float, 4, Eigen::Affine>;
Affine4f tform = Affine4f::Identity();
}; };
void upload_groups(entt::registry &reg) { void upload_groups(entt::registry &reg) {
@@ -60,6 +70,15 @@ namespace vis {
} }
} }
void upload_ubo(entt::registry &reg) {
auto view = reg.view<VBOs>();
for (auto [entity, vbos]: view.each()) {
vbos.ubo.put({vbos.tform.linear(),
vbos.tform.translation()});
}
}
struct SliceRenderer { struct SliceRenderer {
cgl::pgm::vert defer = cgl::pgm::vert(shaders::deferred_vs_glsl); cgl::pgm::vert defer = cgl::pgm::vert(shaders::deferred_vs_glsl);
cgl::pgm::geom slice = cgl::pgm::geom(shaders::slice_gm_glsl); cgl::pgm::geom slice = cgl::pgm::geom(shaders::slice_gm_glsl);
@@ -86,6 +105,7 @@ namespace vis {
glBindProgramPipeline(pipe); glBindProgramPipeline(pipe);
glProgramUniform3fv(solid, 2, 1, group.color.data()); glProgramUniform3fv(solid, 2, 1, group.color.data());
glBindBufferBase(GL_UNIFORM_BUFFER, 2, vbos.ubo);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, vbos.verts); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, vbos.verts);

View File

@@ -9,6 +9,7 @@
#include "mirror.hpp" #include "mirror.hpp"
#include "comps.hpp" #include "comps.hpp"
#include "fmt/core.h"
#include <shaders.hpp> #include <shaders.hpp>
@@ -42,6 +43,8 @@ struct State {
float st; float st;
int dimension; int dimension;
entt::registry registry;
}; };
Matrices build(GLFWwindow* window, State &state) { Matrices build(GLFWwindow* window, State &state) {
@@ -57,84 +60,76 @@ Matrices build(GLFWwindow* window, State &state) {
state.st += state.time_delta / 8; state.st += state.time_delta / 8;
} }
Eigen::Matrix4f view; static bool init = false;
view.setIdentity(); static Eigen::Vector2d last;
Eigen::Vector2d pos;
glfwGetCursorPos(window, &pos.x(), &pos.y());
if (!init) {
last = pos;
init = true;
}
Eigen::Vector2d dpos = pos - last;
last = pos;
static Eigen::Matrix4f view = Eigen::Matrix4f::Identity();
if (state.dimension < 4) { if (state.dimension < 4) {
view *= rot<4>(2, 3, M_PI_2f32 + 0.01f); view *= rot<4>(2, 3, M_PI_2f32 + 0.01f);
} }
if (state.dimension > 1) { if (glfwGetMouseButton(window, 0)) {
view *= rot<4>(0, 1, state.st * .40f); float scale = 0.005;
} auto rotate = rotor(
if (state.dimension > 2) { Eigen::Vector4f{0, 0, 1, 0},
view *= rot<4>(0, 2, state.st * .20f); Eigen::Vector4f{
view *= rot<4>(1, 2, state.st * .50f); dpos.x() * scale,
} -dpos.y() * scale,
if (state.dimension > 3) { 1, 0
view *= rot<4>(0, 3, state.st * 1.30f); }.normalized()
view *= rot<4>(1, 3, state.st * .25f); );
view *= rot<4>(2, 3, state.st * 1.42f); view = rotate * view;
} }
return Matrices(proj, view); return Matrices(proj, view);
} }
template<class C>
std::vector<vec4> points(const tc::Group<> &group, const C &coords) {
auto cosets = group.solve();
auto mirrors = mirror<5>(group);
auto corners = plane_intersections(mirrors);
vec5 coord = coords;
auto start = corners * coord;
tc::Path<vec5> path(cosets, mirrors.colwise());
Eigen::Array<float, 5, Eigen::Dynamic> higher(5, path.order());
path.walk(start, Reflect(), higher.matrix().colwise().begin());
Eigen::Array4Xf lower = Stereo()(higher);
std::vector<vec4> vec(lower.cols());
std::copy(lower.colwise().begin(), lower.colwise().end(), vec.begin());
return vec;
}
void run(const std::string &config_file, GLFWwindow* window) { void run(const std::string &config_file, GLFWwindow* window) {
#ifndef NDEBUG #ifndef NDEBUG
glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(log_gl_debug_callback, nullptr); glDebugMessageCallback(log_gl_debug_callback, nullptr);
#endif #endif
if (glfwRawMouseMotionSupported()) {
glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
}
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
entt::registry registry;
vis::SliceRenderer renderer; vis::SliceRenderer renderer;
State state{}; State state{};
glfwSetWindowUserPointer(window, &state); glfwSetWindowUserPointer(window, &state);
auto &registry = state.registry;
state.dimension = 4; state.dimension = 4;
{
auto entity = registry.create(); auto entity = registry.create();
registry.emplace<vis::Group>( registry.emplace<vis::Group>(
entity, entity,
tc::schlafli({5, 3, 3, 2}), tc::schlafli({5, 3, 3, 2}),
vec5{0.80, 0.09, 0.09, 0.09, 0.04}, vec5{0.80, 0.09, 0.09, 0.09, 0.09},
vec3{0.90, 0.90, 0.90}, vec3{0.90, 0.90, 0.90},
std::vector<std::vector<size_t>>{{0, 1, 2}, std::vector<std::vector<size_t>>{{0, 1, 2},
{0, 3, 4}, {1, 3, 4}, {2, 3, 4}} {0, 3, 4},
{1, 3, 4},
{2, 3, 4}}
); );
registry.emplace<vis::VBOs>(entity); registry.emplace<vis::VBOs>(entity);
}
vis::upload_groups(registry); vis::upload_groups(registry);
@@ -152,10 +147,30 @@ void run(const std::string &config_file, GLFWwindow* window) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Matrices mats = build(window, state); ubo.put(build(window, state));
ubo.put(mats);
glLineWidth(1.5); {
auto &tform = registry.get<vis::VBOs>(entity).tform;
tform.linear().setIdentity();
if (state.dimension > 1) {
tform.linear() *= rot<4>(0, 1, state.st * .40f);
}
if (state.dimension > 2) {
tform.linear() *= rot<4>(0, 2, state.st * .20f);
tform.linear() *= rot<4>(1, 2, state.st * .50f);
}
if (state.dimension > 3) {
tform.linear() *= rot<4>(0, 3, state.st * 1.30f);
tform.linear() *= rot<4>(1, 3, state.st * .25f);
tform.linear() *= rot<4>(2, 3, state.st * 1.42f);
}
tform.translation().w() = std::sin(time * 0.3f) * 1.0f;
}
vis::upload_ubo(registry);
renderer(registry); renderer(registry);