|
|
@@ -6,6 +6,12 @@
|
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
|
#include <glm/gtx/rotate_vector.hpp>
|
|
|
|
|
|
+#include <boost/asio/post.hpp>
|
|
|
+
|
|
|
+#include <vtkSphereSource.h>
|
|
|
+
|
|
|
+using boost::asio::post;
|
|
|
+
|
|
|
glm::mat4 camera_augment_helper_v2::impl::freedom_info_type::to_transform() {
|
|
|
// normalize view up
|
|
|
view_up -= view_dir() * glm::dot(view_up, view_dir());
|
|
|
@@ -38,6 +44,7 @@ void camera_augment_helper_v2::impl::freedom_info_type::move_right(float dis) {
|
|
|
translate(-axis * dis);
|
|
|
}
|
|
|
|
|
|
+// TODO: using accelerometer determined world coordinate
|
|
|
void camera_augment_helper_v2::impl::freedom_info_type::move_up(float dis) {
|
|
|
translate(view_up * dis);
|
|
|
}
|
|
|
@@ -57,7 +64,7 @@ void camera_augment_helper_v2::impl::freedom_info_type::yaw(float deg) {
|
|
|
|
|
|
void camera_augment_helper_v2::impl::freedom_info_type::pitch(float deg) {
|
|
|
auto rot_axis = glm::cross(view_up, view_dir());
|
|
|
- view_up = glm::rotate(view_up, deg, rot_axis);
|
|
|
+ view_up = glm::rotate(view_up, glm::radians(deg), rot_axis);
|
|
|
auto next_view_dir = glm::rotate(view_dir(), glm::radians(deg), rot_axis);
|
|
|
center = eye + next_view_dir * view_dis();
|
|
|
}
|
|
|
@@ -69,6 +76,10 @@ glm::mat4 camera_augment_helper_v2::impl::fixed_info_type::extra_transform() con
|
|
|
camera_augment_helper_v2::impl::impl(const create_config &conf) {
|
|
|
manager = conf.manager;
|
|
|
sophiar_conn = conf.sophiar_conn;
|
|
|
+ ctx = conf.ctx;
|
|
|
+
|
|
|
+ pre_render_conn = manager->pre_render_sig.connect(
|
|
|
+ [this](auto &info) { pre_render_slot(info); });
|
|
|
|
|
|
switch (conf.camera.index()) {
|
|
|
case 1: {
|
|
|
@@ -96,6 +107,10 @@ camera_augment_helper_v2::impl::impl(const create_config &conf) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+camera_augment_helper_v2::impl::~impl() {
|
|
|
+ pre_render_conn.disconnect();
|
|
|
+}
|
|
|
+
|
|
|
void camera_augment_helper_v2::impl::update_freedom() {
|
|
|
transform = freedom_info.to_transform();
|
|
|
is_missing = false;
|
|
|
@@ -136,6 +151,8 @@ void camera_augment_helper_v2::impl::render() {
|
|
|
};
|
|
|
if (!is_missing || ignore_missing) {
|
|
|
manager->render(ren_info);
|
|
|
+ last_camera = ren_info;
|
|
|
+ last_vp_size = query_viewport_size();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -143,6 +160,11 @@ void camera_augment_helper_v2::impl::render_image(output_config conf) {
|
|
|
fbo_conf.size = conf.size;
|
|
|
fbo.create(fbo_conf);
|
|
|
|
|
|
+ if (img_downloader == nullptr) [[unlikely]] {
|
|
|
+ img_downloader = std::make_unique<viewport_downloader>(
|
|
|
+ viewport_downloader::create_config{.stream = conf.stream});
|
|
|
+ }
|
|
|
+
|
|
|
fbo.bind();
|
|
|
render();
|
|
|
auto out_img = img_downloader->download_v2();
|
|
|
@@ -205,7 +227,7 @@ void camera_augment_helper_v2::impl::show_fixed() {
|
|
|
}
|
|
|
|
|
|
void camera_augment_helper_v2::impl::show() {
|
|
|
- ImGui::Checkbox("Ignore Missing", &ignore_missing);
|
|
|
+ ImGui::Checkbox("Ignore Missing", &ignore_missing); // TODO: enable sync with another
|
|
|
ImGui::SliderFloat("Clip Near", &near, 1.0f, far, "%.f", ImGuiSliderFlags_Logarithmic);
|
|
|
ImGui::SliderFloat("Clip Far", &far, near, 10000.0f, "%.f", ImGuiSliderFlags_Logarithmic);
|
|
|
|
|
|
@@ -219,6 +241,76 @@ void camera_augment_helper_v2::impl::show() {
|
|
|
RET_ERROR;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (is_interactive) {
|
|
|
+ ImGui::Checkbox("Cursor Guide", &enable_cursor_guide);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::update_cursor_coordinate() {
|
|
|
+ assert(enable_cursor_guide);
|
|
|
+ cursor_pos = {};
|
|
|
+
|
|
|
+ auto s_pos = ImGui::GetMousePos();
|
|
|
+ auto w = last_vp_size.width, h = last_vp_size.height;
|
|
|
+ if (s_pos.x < 0 || s_pos.x > w) return;
|
|
|
+ if (s_pos.y < 0 || s_pos.y > h) return;
|
|
|
+ s_pos.y = h - s_pos.y; // flip y to texture coordinate
|
|
|
+
|
|
|
+ float depth;
|
|
|
+ glReadPixels(s_pos.x, s_pos.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
|
|
|
+ if (depth == 1.f) return;
|
|
|
+
|
|
|
+ auto proj = last_camera.projection(last_vp_size.aspectRatio());
|
|
|
+ auto ndc = glm::vec3(s_pos.x / w, s_pos.y / h, depth);
|
|
|
+ auto c_pos_h = glm::inverse(proj) * to_homo(2.f * ndc - 1.f);
|
|
|
+ auto c_pos = from_homo(c_pos_h);
|
|
|
+
|
|
|
+ auto cam_mat = glm::rotate(last_camera.transform,
|
|
|
+ glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f)); // camera -> viewport
|
|
|
+ auto w_pos_h = glm::inverse(cam_mat) * to_homo(c_pos);
|
|
|
+ auto w_pos = from_homo(w_pos_h);
|
|
|
+ cursor_pos = w_pos;
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::cursor_guide_slot(scene_render_info &info) {
|
|
|
+ assert(enable_cursor_guide);
|
|
|
+
|
|
|
+ if (cursor_symbol == nullptr) [[unlikely]] {
|
|
|
+ vtkNew<vtkSphereSource> source;
|
|
|
+ source->SetRadius(5); // TODO: make this adjustable
|
|
|
+ source->SetCenter(0, 0, 0);
|
|
|
+ source->Update();
|
|
|
+ cursor_symbol = mesh_type::from_vtk(source->GetOutput());
|
|
|
+ }
|
|
|
+
|
|
|
+ // record cursor position
|
|
|
+ auto rec_info = scene_render_info::custom_info{
|
|
|
+ .func = [this] { update_cursor_coordinate(); },
|
|
|
+ };
|
|
|
+ info.items.push_back({.info = rec_info});
|
|
|
+
|
|
|
+ if (cursor_pos.has_value()) {
|
|
|
+ auto color = glm::vec3(0.0f, 1.0f, 0.0f); // TODO: make this adjustable
|
|
|
+ auto amb_factor = 0.9f;
|
|
|
+ auto item_info = scene_render_info::mesh_info{
|
|
|
+ .mesh = cursor_symbol,
|
|
|
+ .material = {.ambient = color * amb_factor, .diffuse = color,},
|
|
|
+ };
|
|
|
+ info.items.push_back(
|
|
|
+ {.info = item_info, .transform = glm::translate(*cursor_pos),});
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::pre_render_slot(scene_render_info &info) {
|
|
|
+ if (!is_interactive) return;
|
|
|
+ if (enable_cursor_guide) {
|
|
|
+ cursor_guide_slot(info);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::set_interactive(bool flag) {
|
|
|
+ is_interactive = flag;
|
|
|
}
|
|
|
|
|
|
camera_augment_helper_v2::camera_augment_helper_v2(const create_config &conf)
|
|
|
@@ -237,4 +329,8 @@ void camera_augment_helper_v2::render_image(output_config conf) {
|
|
|
|
|
|
void camera_augment_helper_v2::show() {
|
|
|
pimpl->show();
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::set_interactive(bool flag) {
|
|
|
+ pimpl->set_interactive(flag);
|
|
|
}
|