From a2b2ef52c3105a70605aab3ef5231fc2d305b12f Mon Sep 17 00:00:00 2001 From: omigamedev Date: Thu, 17 Jan 2019 12:02:03 +0100 Subject: [PATCH] implement heightmap overlay for navigation --- src/node_panel_grid.cpp | 106 +++++++++++++++++++++++++++++++++++++++- src/node_panel_grid.h | 18 +++++++ 2 files changed, 122 insertions(+), 2 deletions(-) diff --git a/src/node_panel_grid.cpp b/src/node_panel_grid.cpp index f2a5eca..fcb9e6a 100644 --- a/src/node_panel_grid.cpp +++ b/src/node_panel_grid.cpp @@ -44,6 +44,10 @@ void NodePanelGrid::init_controls() m_hm_preview->SetHeight(0); m_hm_plane.create(1, 1, 100); + m_hm_preview_nav = m_hm_preview->add_child(); + m_hm_preview_nav->SetWidthP(100); + m_hm_preview_nav->SetHeightP(100); + //m_hm_height->on_value_changed = update_hm; m_groud_resolution->on_value_final = [this](Node* target, float v) { if (m_hm_image.data()) @@ -156,12 +160,14 @@ void NodePanelGrid::draw_heightmap(const glm::mat4& proj, const glm::mat4& camer glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); + auto nav = -(m_hm_preview_nav->m_value - 0.5f); auto mvp = proj * camera - * glm::translate(glm::vec3(0, get_offset(), 0)); + * glm::translate(glm::vec3(0, get_offset(), 0)) + * glm::translate(glm::vec3(nav.x, get_offset(), nav.y)); auto light_yaw = m_hm_lyaw->get_value() * glm::pi() * 2.f; auto light_pitch = m_hm_lpitch->get_value() * 5; - auto light_pos = glm::vec3(sinf(light_yaw), light_pitch + get_offset(), cosf(light_yaw)); + auto light_pos = glm::vec3(sinf(light_yaw) + nav.x, light_pitch + get_offset(), cosf(light_yaw) + nav.y); auto light_dir = glm::normalize(light_pos); // DRAW SUN SPHERE @@ -360,3 +366,99 @@ void NodePanelGrid::bake_uvs() m_texture.create_mipmaps(); App::I.async_redraw(); } + +/////////////////////////////////////////////////////////////////////////////// + +Node* NodeHeightmapOverlay::clone_instantiate() const +{ + return new NodeHeightmapOverlay(); +} + +void NodeHeightmapOverlay::clone_finalize(Node* dest) const +{ + auto n = (NodeHeightmapOverlay*)dest; + n->m_picker = (NodeBorder*)n->m_children[0].get(); +} + +void NodeHeightmapOverlay::init() +{ + m_picker = new NodeBorder; + m_picker->SetSize({ 10, 10 }); + m_picker->SetPositioning(YGPositionTypeAbsolute); + m_picker->SetPosition(0, 0); + m_picker->m_border_color = glm::vec4(0, 0, 0, 1); + m_picker->m_thinkness = 1; + m_picker->m_color = glm::vec4(1, 1, 1, 0.25f); + add_child(m_picker); +} + +void NodeHeightmapOverlay::set_value(float x, float y) +{ + auto sz = m_size; + auto pos = glm::clamp(glm::vec2(x, y) * sz, { 0, 0 }, sz); + //m_picker->SetPosition(pos - m_picker->GetSize() * .5f); + m_value = pos / glm::max({ 1,1 }, sz); // avoid div0 + if (on_value_changed) + on_value_changed(this, m_value); +} + +kEventResult NodeHeightmapOverlay::handle_event(Event* e) +{ + NodeBorder::handle_event(e); + switch (e->m_type) + { + case kEventType::MouseDownL: + { + m_old_value = m_value; + dragging = true; + mouse_capture(); + auto sz = m_size; + auto pos = glm::clamp(((MouseEvent*)e)->m_pos - m_pos, { 0, 0 }, sz); + m_picker->SetPosition(pos - m_picker->GetSize() * .5f); + m_value = pos / glm::max({ 1,1 }, sz); // avoid div0 + if (on_value_changed) + on_value_changed(this, m_value); + } + break; + case kEventType::MouseUpL: + mouse_release(); + dragging = false; + break; + case kEventType::MouseMove: + if (dragging) + { + auto sz = m_size; + auto pos = glm::clamp(((MouseEvent*)e)->m_pos - m_pos, { 0, 0 }, sz); + m_picker->SetPosition(pos - m_picker->GetSize() * .5f); + m_value = pos / glm::max({ 1,1 }, sz); // avoid div0 + if (on_value_changed) + on_value_changed(this, m_value); + } + break; + case kEventType::MouseCancel: + mouse_release(); + dragging = false; + m_value = m_old_value; + set_value(m_value.x, m_value.y); + if (on_value_changed) + on_value_changed(this, m_value); + break; + default: + return kEventResult::Available; + break; + } + return kEventResult::Consumed; +} + +void NodeHeightmapOverlay::draw() +{ + auto sz = m_size; + auto pos = glm::clamp(m_value * sz, { 0, 0 }, sz); + m_picker->SetPosition(pos - m_picker->GetSize() * .5f); +} + +void NodeHeightmapOverlay::handle_resize(glm::vec2 old_size, glm::vec2 new_size) +{ + NodeBorder::handle_resize(old_size, new_size); + set_value(m_value.x, m_value.y); +} diff --git a/src/node_panel_grid.h b/src/node_panel_grid.h index e2efdcb..aa4b41e 100644 --- a/src/node_panel_grid.h +++ b/src/node_panel_grid.h @@ -14,6 +14,23 @@ #define NANORT_ENABLE_PARALLEL_BUILD #include "nanort.h" +class NodeHeightmapOverlay : public NodeBorder +{ + NodeBorder* m_picker{ nullptr }; + bool dragging = false; +public: + glm::vec2 m_value{ 0.5f, 0.5f }; + glm::vec2 m_old_value{ 0.f }; + std::function on_value_changed; + virtual Node* clone_instantiate() const override; + virtual void clone_finalize(Node* dest) const override; + virtual void init() override; + void set_value(float x, float y); + virtual kEventResult handle_event(Event* e) override; + virtual void draw() override; + virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size) override; +}; + class NodePanelGrid : public Node { public: @@ -35,6 +52,7 @@ public: NodeButton* m_render; NodeButton* m_commit; HeightmapPlane m_hm_plane; + NodeHeightmapOverlay* m_hm_preview_nav; Sphere m_sphere; Image m_hm_image; Texture2D m_texture;