diff --git a/src/app_layout.cpp b/src/app_layout.cpp index 80b9740..0b400f9 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -332,6 +332,15 @@ void App::init_toolbar_draw() Canvas::set_mode(Canvas::kCanvasMode::Transform); }; } + if (auto* button = layout[main_id]->find("btn-imp")) + { + button->on_click = [this, button](Node*) { + select_button(layout[main_id], button); + auto m = static_cast(canvas->m_canvas->modes[(int)ui::Canvas::kCanvasMode::Transform][0]); + m->m_action = CanvasModeTransform::ActionType::Import; + Canvas::set_mode(Canvas::kCanvasMode::Transform); + }; + } if (auto* button = layout[main_id]->find("btn-fill")) { button->on_click = [this, button](Node*) { @@ -388,8 +397,20 @@ void App::init_menu_file() }; if (auto b = popup->find("file-import")) b->on_click = [this](Node*) { - App::I.pick_image([](std::string path){ - Canvas::I->import_equirectangular(path); + App::I.pick_image([this](std::string path){ + Image img; + img.load_file(path); + if (img.width == img.height / 6 || img.width == img.height * 2) + { + Canvas::I->import_equirectangular(path); + } + else + { + auto m = static_cast(canvas->m_canvas->modes[(int)ui::Canvas::kCanvasMode::Transform][0]); + m->m_action = CanvasModeTransform::ActionType::Import; + m->m_source_image = std::move(img); + Canvas::set_mode(Canvas::kCanvasMode::Transform); + } }); popup->mouse_release(); popup->destroy(); diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index 0466b0d..b56f20e 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -865,6 +865,44 @@ void CanvasModeTransform::enter() if (m_action == ActionType::Import) { + float aspect = 1.f; + if (m_source_image.data()) + { + m_tex[0].create(m_source_image); + aspect = m_source_image.width / m_source_image.height; + } + + auto center = zw(canvas->m_box) * 0.5f; + glm::vec2 bb_sz = glm::vec2(aspect, 0.75f) * 100.f; + glm::vec2 bb_min = center - bb_sz * 0.5f; + glm::vec2 bb_max = center + bb_sz * 0.5f; + glm::vec2 midpoint = (bb_min + bb_max) * 0.5f; + + auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1); + auto center_mat = glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up)); + m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up))); + m_xform_local = glm::mat4(1); + + corners.clear(); + corners.emplace_back(bb_min, 0); // A + corners.emplace_back(bb_max, 0); // C + corners.emplace_back(bb_max.x, bb_min.y, 0); // B + corners.emplace_back(bb_min.x, bb_max.y, 0); // D + corners.emplace_back(midpoint, 0); + corners.emplace_back(midpoint + (bb_max - bb_min) * glm::vec2(0.75f, 0), 0); + + for (auto& c : corners) + c = center_mat * glm::vec4(canvas->point_trace(c), 1); + + m_points_face[0] = std::vector({ + vertex_t(corners[0], { 0, 0 }), + vertex_t(corners[2], { 1, 0 }), + vertex_t(corners[1], { 1, 1 }), + vertex_t(corners[3], { 0, 1 }), + }); + auto shape3d = canvas->triangulate(m_points_face[0]); + m_shape[0].update_vertices(shape3d.data(), shape3d.size()); + return; } @@ -1038,6 +1076,8 @@ void CanvasModeTransform::enter() action->m_canvas = canvas; //action->m_stroke = std::move(m_current_stroke); ActionManager::add(action); + + m_source_image.destroy(); } } diff --git a/src/canvas_modes.h b/src/canvas_modes.h index a9d250a..0fecffe 100644 --- a/src/canvas_modes.h +++ b/src/canvas_modes.h @@ -176,6 +176,7 @@ class CanvasModeTransform : public CanvasMode public: enum class ActionType : uint8_t { Copy, Cut, Import }; ActionType m_action; + ui::Image m_source_image; CanvasModeTransform() = default; virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override; virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override; diff --git a/src/image.h b/src/image.h index dda4d34..982d4e8 100644 --- a/src/image.h +++ b/src/image.h @@ -24,6 +24,13 @@ public: { std::copy(data, data + size(), m_data.get()); } + void destroy() + { + width = 0; + height = 0; + comp = 0; + m_data.reset(); + } void flip(); void create() { m_data = std::make_unique(size()); } Image resize(int w, int h);