|
|
@@ -0,0 +1,240 @@
|
|
|
+#include "camera_augment_helper_v2_impl.h"
|
|
|
+#include "core/math_helper.hpp"
|
|
|
+#include "core/imgui_utility.hpp"
|
|
|
+
|
|
|
+#include <glm/gtc/matrix_transform.hpp>
|
|
|
+#include <glm/gtc/type_ptr.hpp>
|
|
|
+#include <glm/gtx/rotate_vector.hpp>
|
|
|
+
|
|
|
+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());
|
|
|
+ view_up = glm::normalize(view_up);
|
|
|
+
|
|
|
+ auto ret = glm::lookAt(eye, center, view_up);
|
|
|
+ ret = glm::rotate(ret, glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f)); // viewport -> camera
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+glm::vec3 camera_augment_helper_v2::impl::freedom_info_type::view_dir() const {
|
|
|
+ return glm::normalize(center - eye);
|
|
|
+}
|
|
|
+
|
|
|
+float camera_augment_helper_v2::impl::freedom_info_type::view_dis() const {
|
|
|
+ return glm::distance(center, eye);
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::freedom_info_type::translate(glm::vec3 offset) {
|
|
|
+ eye += offset;
|
|
|
+ center += offset;
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::freedom_info_type::forward(float dis) {
|
|
|
+ translate(view_dir() * dis);
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::freedom_info_type::move_right(float dis) {
|
|
|
+ auto axis = glm::cross(view_up, view_dir());
|
|
|
+ translate(-axis * dis);
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::freedom_info_type::move_up(float dis) {
|
|
|
+ translate(view_up * dis);
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::freedom_info_type::center_forward(float dis) {
|
|
|
+ center = eye + view_dir() * (view_dis() + dis);
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::freedom_info_type::roll(float deg) {
|
|
|
+ view_up = glm::rotate(view_up, glm::radians(deg), view_dir());
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::freedom_info_type::yaw(float deg) {
|
|
|
+ auto next_view_dir = glm::rotate(view_dir(), glm::radians(deg), view_up);
|
|
|
+ center = eye + next_view_dir * view_dis();
|
|
|
+}
|
|
|
+
|
|
|
+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);
|
|
|
+ auto next_view_dir = glm::rotate(view_dir(), glm::radians(deg), rot_axis);
|
|
|
+ center = eye + next_view_dir * view_dis();
|
|
|
+}
|
|
|
+
|
|
|
+glm::mat4 camera_augment_helper_v2::impl::fixed_info_type::extra_transform() const {
|
|
|
+ return to_transform_mat(extra_offset, extra_rotation);
|
|
|
+}
|
|
|
+
|
|
|
+camera_augment_helper_v2::impl::impl(const create_config &conf) {
|
|
|
+ manager = conf.manager;
|
|
|
+ sophiar_conn = conf.sophiar_conn;
|
|
|
+
|
|
|
+ switch (conf.camera.index()) {
|
|
|
+ case 1: {
|
|
|
+ mode = MODE_FREEDOM;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 2: {
|
|
|
+ mode = MODE_FIXED;
|
|
|
+ auto info = std::get<2>(conf.camera);
|
|
|
+ fov = info.fov;
|
|
|
+ fixed_info.transform_var = info.transform_var;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 3: {
|
|
|
+ mode = MODE_RELATIVE;
|
|
|
+ auto info = std::get<3>(conf.camera);
|
|
|
+ fov = info.fov;
|
|
|
+ relative_info.parent = info.parent->pimpl.get();
|
|
|
+ relative_info.transform = info.transform;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ RET_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::update_freedom() {
|
|
|
+ transform = freedom_info.to_transform();
|
|
|
+ is_missing = false;
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::update_fixed() {
|
|
|
+ assert(sophiar_conn != nullptr);
|
|
|
+ auto trans = sophiar_conn->
|
|
|
+ query_transform_variable(fixed_info.transform_var);
|
|
|
+ is_missing = !trans.has_value();
|
|
|
+ if (trans.has_value()) {
|
|
|
+ transform = to_mat4(*trans) * fixed_info.extra_transform();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::update_relative() {
|
|
|
+ auto par = relative_info.parent;
|
|
|
+ par->update_transform();
|
|
|
+ is_missing = par->is_missing;
|
|
|
+ transform = par->transform * relative_info.transform;
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::update_transform() {
|
|
|
+ switch (mode) {
|
|
|
+ // @formatter:off
|
|
|
+ case MODE_FREEDOM: { update_freedom(); break; }
|
|
|
+ case MODE_RELATIVE: { update_relative(); break; }
|
|
|
+ case MODE_FIXED: { update_fixed(); break; }
|
|
|
+ // @formatter:on
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::render() {
|
|
|
+ update_transform();
|
|
|
+ auto ren_info = camera_info{
|
|
|
+ .transform = transform, .fov = fov,
|
|
|
+ .near = near, .far = far
|
|
|
+ };
|
|
|
+ if (!is_missing || ignore_missing) {
|
|
|
+ manager->render(ren_info);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::render_image(output_config conf) {
|
|
|
+ fbo_conf.size = conf.size;
|
|
|
+ fbo.create(fbo_conf);
|
|
|
+
|
|
|
+ fbo.bind();
|
|
|
+ render();
|
|
|
+ auto out_img = img_downloader->download_v2();
|
|
|
+ OBJ_SAVE(conf.img_name, out_img);
|
|
|
+ fbo.unbind();
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::show_freedom() {
|
|
|
+ auto &info = freedom_info;
|
|
|
+
|
|
|
+ if (ImGui::TreeNode("Center")) {
|
|
|
+ if (ImGui::Button("X+")) { info.move_right(info.linear_speed); }
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::Button("Y+")) { info.move_up(info.linear_speed); }
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::Button("Z+")) { info.forward(info.linear_speed); }
|
|
|
+// ImGui::SameLine();
|
|
|
+// if (ImGui::Button("D+")) { info.center_forward(info.linear_speed); }
|
|
|
+
|
|
|
+ if (ImGui::Button("X-")) { info.move_right(-info.linear_speed); }
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::Button("Y-")) { info.move_up(-info.linear_speed); }
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::Button("Z-")) { info.forward(-info.linear_speed); }
|
|
|
+// ImGui::SameLine();
|
|
|
+// if (ImGui::Button("D-")) { info.center_forward(-info.linear_speed); }
|
|
|
+
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ImGui::TreeNode("Eye")) {
|
|
|
+ if (ImGui::Button("Ro+")) { info.roll(info.angle_speed); } // roll
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::Button("Ya+")) { info.yaw(info.angle_speed); } // yaw
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::Button("Pi+")) { info.pitch(info.angle_speed); } // pitch
|
|
|
+
|
|
|
+ if (ImGui::Button("Ro-")) { info.roll(-info.angle_speed); } // roll
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::Button("Ya-")) { info.yaw(-info.angle_speed); } // yaw
|
|
|
+ ImGui::SameLine();
|
|
|
+ if (ImGui::Button("Pi-")) { info.pitch(-info.angle_speed); } // pitch
|
|
|
+
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ImGui::TreeNode("Extra")) {
|
|
|
+ ImGui::SliderFloat("Angular Step", &info.angle_speed, 0.01f, 10.0f, "%.2f");
|
|
|
+ ImGui::SliderFloat("Linear Step", &info.linear_speed, 0.01f, 100.0f, "%.2f");
|
|
|
+ ImGui::DragFloat("FOV (deg)", &fov, 0.5f, 10.0f, 178.0f, "%.01f");
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::show_fixed() {
|
|
|
+ ImGui::DragFloat3("Offset (mm)", glm::value_ptr(fixed_info.extra_offset),
|
|
|
+ 0.05f, 0.0f, 0.0f, "%.02f");
|
|
|
+ ImGui::DragFloat3("Offset (deg)", glm::value_ptr(fixed_info.extra_rotation),
|
|
|
+ 0.1f, -180.0f, 180.0f, "%.01f");
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::impl::show() {
|
|
|
+ ImGui::Checkbox("Ignore Missing", &ignore_missing);
|
|
|
+ ImGui::SliderFloat("Clip Near", &near, 1.0f, far, "%.f", ImGuiSliderFlags_Logarithmic);
|
|
|
+ ImGui::SliderFloat("Clip Far", &far, near, 10000.0f, "%.f", ImGuiSliderFlags_Logarithmic);
|
|
|
+
|
|
|
+ switch (mode) {
|
|
|
+ // @formatter:off
|
|
|
+ case MODE_FIXED: { show_fixed(); break; }
|
|
|
+ case MODE_RELATIVE: { break; }
|
|
|
+ case MODE_FREEDOM: { show_freedom(); break; }
|
|
|
+ // @formatter:on
|
|
|
+ default: {
|
|
|
+ RET_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+camera_augment_helper_v2::camera_augment_helper_v2(const create_config &conf)
|
|
|
+ : pimpl(std::make_unique<impl>(conf)) {
|
|
|
+}
|
|
|
+
|
|
|
+camera_augment_helper_v2::~camera_augment_helper_v2() = default;
|
|
|
+
|
|
|
+void camera_augment_helper_v2::render() {
|
|
|
+ pimpl->render();
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::render_image(output_config conf) {
|
|
|
+ pimpl->render_image(conf);
|
|
|
+}
|
|
|
+
|
|
|
+void camera_augment_helper_v2::show() {
|
|
|
+ pimpl->show();
|
|
|
+}
|