diff --git a/samples/basic/viewer/main.cc b/samples/basic/viewer/main.cc index 3c9a29be37cd03ce990ac59aed39247f6de5c5b5..3737540614fa6e3c3d8a5136a7339ed2658a61ae 100644 --- a/samples/basic/viewer/main.cc +++ b/samples/basic/viewer/main.cc @@ -199,90 +199,88 @@ void imguizmo(pm::vertex_attribute<tg::pos3> const& pos) auto transform = tg::mat4::identity; // an interactive view is required - gv::interactive( - [&](float) + gv::interactive([&](float) { + // you can define keybindings to select an operation + if (ImGui::IsKeyPressed(GLFW_KEY_T)) + currentGizmoOperation = ImGuizmo::TRANSLATE; + if (ImGui::IsKeyPressed(GLFW_KEY_R)) + currentGizmoOperation = ImGuizmo::ROTATE; + if (ImGui::IsKeyPressed(GLFW_KEY_S)) + currentGizmoOperation = ImGuizmo::SCALE; + + // you can also choose the correct operation using gui elements + if (ImGui::RadioButton("Translate", currentGizmoOperation == ImGuizmo::TRANSLATE)) + currentGizmoOperation = ImGuizmo::TRANSLATE; + ImGui::SameLine(); + if (ImGui::RadioButton("Rotate", currentGizmoOperation == ImGuizmo::ROTATE)) + currentGizmoOperation = ImGuizmo::ROTATE; + ImGui::SameLine(); + if (ImGui::RadioButton("Scale", currentGizmoOperation == ImGuizmo::SCALE)) + currentGizmoOperation = ImGuizmo::SCALE; + + // ImGuizmo decomposes your input transform into translation, rotation, and scaling components + float matrixTranslation[3], matrixRotation[3], matrixScale[3]; + ImGuizmo::DecomposeMatrixToComponents(&transform[0][0], matrixTranslation, matrixRotation, matrixScale); + + // show the three components individually + ImGui::InputFloat3("Tr", matrixTranslation); + ImGui::InputFloat3("Rt", matrixRotation); + ImGui::InputFloat3("Sc", matrixScale); + + // rebuild your 4x4 transform matrix + ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, &transform[0][0]); + + // only show the radio button to choose local/global coordinate system when NOT scaling + // as scaling is always in local coordinates + if (currentGizmoOperation != ImGuizmo::SCALE) { - // you can define keybindings to select an operation - if (ImGui::IsKeyPressed(GLFW_KEY_T)) - currentGizmoOperation = ImGuizmo::TRANSLATE; - if (ImGui::IsKeyPressed(GLFW_KEY_R)) - currentGizmoOperation = ImGuizmo::ROTATE; - if (ImGui::IsKeyPressed(GLFW_KEY_S)) - currentGizmoOperation = ImGuizmo::SCALE; - - // you can also choose the correct operation using gui elements - if (ImGui::RadioButton("Translate", currentGizmoOperation == ImGuizmo::TRANSLATE)) - currentGizmoOperation = ImGuizmo::TRANSLATE; + if (ImGui::RadioButton("Local", currentGizmoMode == ImGuizmo::LOCAL)) + currentGizmoMode = ImGuizmo::LOCAL; ImGui::SameLine(); - if (ImGui::RadioButton("Rotate", currentGizmoOperation == ImGuizmo::ROTATE)) - currentGizmoOperation = ImGuizmo::ROTATE; - ImGui::SameLine(); - if (ImGui::RadioButton("Scale", currentGizmoOperation == ImGuizmo::SCALE)) - currentGizmoOperation = ImGuizmo::SCALE; - - // ImGuizmo decomposes your input transform into translation, rotation, and scaling components - float matrixTranslation[3], matrixRotation[3], matrixScale[3]; - ImGuizmo::DecomposeMatrixToComponents(&transform[0][0], matrixTranslation, matrixRotation, matrixScale); - - // show the three components individually - ImGui::InputFloat3("Tr", matrixTranslation); - ImGui::InputFloat3("Rt", matrixRotation); - ImGui::InputFloat3("Sc", matrixScale); - - // rebuild your 4x4 transform matrix - ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, &transform[0][0]); - - // only show the radio button to choose local/global coordinate system when NOT scaling - // as scaling is always in local coordinates - if (currentGizmoOperation != ImGuizmo::SCALE) - { - if (ImGui::RadioButton("Local", currentGizmoMode == ImGuizmo::LOCAL)) - currentGizmoMode = ImGuizmo::LOCAL; - ImGui::SameLine(); - if (ImGui::RadioButton("World", currentGizmoMode == ImGuizmo::WORLD)) - currentGizmoMode = ImGuizmo::WORLD; - } + if (ImGui::RadioButton("World", currentGizmoMode == ImGuizmo::WORLD)) + currentGizmoMode = ImGuizmo::WORLD; + } - // toggle snap on p key - if (ImGui::IsKeyPressed(GLFW_KEY_P)) - useSnap = !useSnap; + // toggle snap on p key + if (ImGui::IsKeyPressed(GLFW_KEY_P)) + useSnap = !useSnap; - // ... or use gui elements - ImGui::Checkbox("", &useSnap); - ImGui::SameLine(); + // ... or use gui elements + ImGui::Checkbox("", &useSnap); + ImGui::SameLine(); - // name the snap input accordingly - switch (currentGizmoOperation) - { - case ImGuizmo::TRANSLATE: - ImGui::InputFloat3("Snap", snap); - break; - case ImGuizmo::ROTATE: - ImGui::InputFloat("Angle Snap", snap); - break; - case ImGuizmo::SCALE: - ImGui::InputFloat("Scale Snap", snap); - break; - default: // silence warnings as there are quite a few more possible operations supported by ImGuizmo - break; // do nothing - } + // name the snap input accordingly + switch (currentGizmoOperation) + { + case ImGuizmo::TRANSLATE: + ImGui::InputFloat3("Snap", snap); + break; + case ImGuizmo::ROTATE: + ImGui::InputFloat("Angle Snap", snap); + break; + case ImGuizmo::SCALE: + ImGui::InputFloat("Scale Snap", snap); + break; + default: // silence warnings as there are quite a few more possible operations supported by ImGuizmo + break; // do nothing + } - // ImGuizmo requires view and projection matrix for rendering. - // However, it does not work with a reversed z projection matrix, which is used by the viewer by default - // So we need to disable it temporarily, generate a projection matrix without it, and then reactivate it - auto view = cam->computeViewMatrix(); - auto const rev_z_enabled = cam->reverseZEnabled(); - cam->setReverseZEnabled(false); // - auto project = cam->computeProjMatrix(); - cam->setReverseZEnabled(rev_z_enabled); - - // This is where all the ImGuizmo magic comes together - ImGuizmo::Manipulate(&view[0][0], &project[0][0], currentGizmoOperation, currentGizmoMode, &transform[0][0], nullptr, useSnap ? &snap[0] : nullptr); - - // Because the view is resized when we change the object, it might be a good idea to pass the viewer a fixed bounding box - auto const aabb = tg::aabb3(tg::pos3(-2), tg::pos3(2)); - gv::view(r, cam, transform, aabb); - }); + // ImGuizmo requires view and projection matrix for rendering. + // However, it does not work with a reversed z projection matrix, which is used by the viewer by default + // So we need to disable it temporarily, generate a projection matrix without it, and then reactivate it + auto view = cam->computeViewMatrix(); + auto const rev_z_enabled = cam->reverseZEnabled(); + cam->setReverseZEnabled(false); // + auto project = cam->computeProjMatrix(); + cam->setReverseZEnabled(rev_z_enabled); + + // This is where all the ImGuizmo magic comes together + ImGuizmo::Manipulate(&view[0][0], &project[0][0], currentGizmoOperation, currentGizmoMode, &transform[0][0], nullptr, useSnap ? &snap[0] : nullptr); + + // Because the view is resized when we change the object, it might be a good idea to pass the viewer a fixed bounding box + auto const aabb = tg::aabb3(tg::pos3(-2), tg::pos3(2)); + gv::view(r, cam, transform, aabb); + }); } void advanced_visualization(pm::vertex_attribute<tg::pos3> const& pos) @@ -535,12 +533,10 @@ void advanced_configs(pm::vertex_attribute<tg::pos3> const& pos) } // custom configure function - gv::view(pos, "config via lambda", - [](gv::SceneConfig& cfg) - { - cfg.enableShadows = false; - cfg.bgColorInner = {1, 0, 1}; - }); + gv::view(pos, "config via lambda", [](gv::SceneConfig& cfg) { + cfg.enableShadows = false; + cfg.bgColorInner = {1, 0, 1}; + }); } void advanced_layouting(pm::vertex_attribute<tg::pos3> const& pos) @@ -736,45 +732,38 @@ void interactive_viewer(pm::vertex_attribute<tg::pos3> const& pos) // the scene config and all renderables are hashed and the viewer accumulation is cleared when the hash changes // a simple interactive viewer with some interactive-related controls - gv::interactive( - [&](auto) - { - if (ImGui::Button("make screenshot")) - gv::make_screenshot("screenshot.png", 1920, 1080); + gv::interactive([&](auto) { + if (ImGui::Button("make screenshot")) + gv::make_screenshot("screenshot.png", 1920, 1080); - if (ImGui::Button("close viewer")) - gv::close_viewer(); + if (ImGui::Button("close viewer")) + gv::close_viewer(); - gv::view(pos, "interactive viewer with custom buttons. It is slow because nothing is cached."); - }); + gv::view(pos, "interactive viewer with custom buttons. It is slow because nothing is cached."); + }); // creating renderables is expensive, cache them whenever possible // NOTE: capture by value if the interactive viewer is not the top-most viewer { auto const r = gv::make_renderable(pos); - gv::interactive( - [r](auto dt) - { - static auto time = 0.f; - time += dt; + gv::interactive([r](auto dt) { + static auto time = 0.f; + time += dt; - gv::view(r, tg::translation(tg::vec3(tg::sin(tg::radians(time * .5f)) * .5f, 0.f, 0.f)), - "Caching renderables in interactive views increases performance."); - }); + gv::view(r, tg::translation(tg::vec3(tg::sin(tg::radians(time * .5f)) * .5f, 0.f, 0.f)), "Caching renderables in interactive views increases performance."); + }); } // using imgui in an interactive view { auto const r = gv::make_renderable(pos); - gv::interactive( - [r](auto) - { - static float configurable = 0.f; + gv::interactive([r](auto) { + static float configurable = 0.f; - ImGui::SliderFloat("Height", &configurable, -3.f, 3.f); + ImGui::SliderFloat("Height", &configurable, -3.f, 3.f); - gv::view(r, tg::translation(tg::vec3(0.f, configurable, 0.f)), "interactive translation of a model"); - }); + gv::view(r, tg::translation(tg::vec3(0.f, configurable, 0.f)), "interactive translation of a model"); + }); } // an interactive textured torus with animated texture coordinates @@ -787,8 +776,7 @@ void interactive_viewer(pm::vertex_attribute<tg::pos3> const& pos) auto uv = m.vertices().make_attribute<tg::pos2>(); pm::objects::add_quad( m, - [&](pm::vertex_handle v, float x, float y) - { + [&](pm::vertex_handle v, float x, float y) { auto [cx, sx] = tg::sin_cos(tg::pi<float> * 2 * x); auto [cy, sy] = tg::sin_cos(tg::pi<float> * 2 * y); @@ -811,20 +799,18 @@ void interactive_viewer(pm::vertex_attribute<tg::pos3> const& pos) auto a = 0.f; auto animate = false; - gv::interactive( - [&](auto dt) - { - ImGui::Begin("Torus"); - ImGui::SliderFloat("angle", &a, 0.f, 360.f); - ImGui::Checkbox("Animate", &animate); - ImGui::End(); + gv::interactive([&](auto dt) { + ImGui::Begin("Torus"); + ImGui::SliderFloat("angle", &a, 0.f, 360.f); + ImGui::Checkbox("Animate", &animate); + ImGui::End(); - if (animate) - a += 5 * dt; + if (animate) + a += 5 * dt; - // texture coordinates are rotated by "a" degrees - view(pos, gv::textured(uv, tex).transform(tg::rotation_around(tg::pos2::zero, tg::degree(a))), "animated texture coordinates"); - }); + // texture coordinates are rotated by "a" degrees + view(pos, gv::textured(uv, tex).transform(tg::rotation_around(tg::pos2::zero, tg::degree(a))), "animated texture coordinates"); + }); } } @@ -937,59 +923,48 @@ void picking(pm::Mesh& m, pm::vertex_attribute<tg::pos3>& pos, pm::face_attribut auto g = gv::grid(); // Only on_left_click callback defined - gv::view(pos, col, - gv::pick().onLeftClick( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) -> gv::picking_result - { - std::cout << "Something has been picked! ON_LEFT_CLICK" - << "ID: " << (int)face_id << std::endl; - std::cout << "World_Position " << world_pos << std::endl; - std::cout << "Normal " << normal << std::endl; - gv::picking_result res; - res.pickingColor = tg::color3::cyan; - return res; - }), + gv::view(pos, col, gv::pick().onLeftClick([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) -> gv::picking_result { + std::cout << "Something has been picked! ON_LEFT_CLICK" + << "ID: " << (int)face_id << std::endl; + std::cout << "World_Position " << world_pos << std::endl; + std::cout << "Normal " << normal << std::endl; + gv::picking_result res; + res.pickingColor = tg::color3::cyan; + return res; + }), "picking MeshRenderable - callback on left click"); // Only on_left_click callback defined - LineRenderable - uncolored - gv::view(gv::lines(pos), - gv::pick().onLeftClick( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_LEFT_CLICK" - << "ID: " << int(face_id) << std::endl; - std::cout << "World_Position" << world_pos << std::endl; - std::cout << "Normal" << normal << std::endl; - }), + gv::view(gv::lines(pos), gv::pick().onLeftClick([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_LEFT_CLICK" + << "ID: " << int(face_id) << std::endl; + std::cout << "World_Position" << world_pos << std::endl; + std::cout << "Normal" << normal << std::endl; + }), "picking LineRenderable - callback on left click"); { // Only on_left_click callback defined - PointRenderable - uncolored - gv::view(gv::points(pos), - gv::pick().onLeftClick( - [&](pm::vertex_index vertex_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_LEFT_CLICK" - << "ID: " << int(vertex_id) << std::endl; - std::cout << "World_Position" << world_pos << std::endl; - std::cout << "Normal" << normal << std::endl; - return; - }), + gv::view(gv::points(pos), gv::pick().onLeftClick([&](pm::vertex_index vertex_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_LEFT_CLICK" + << "ID: " << int(vertex_id) << std::endl; + std::cout << "World_Position" << world_pos << std::endl; + std::cout << "Normal" << normal << std::endl; + return; + }), "picking PointRenderable - callback on left click - spheres"); } { // Only on_left_click callback defined - PointRenderable - uncolored - square billboards - NOT WORKING APPROPRIATELY gv::view(gv::points(pos).point_size_world(0.03f).camera_facing().square(), - gv::pick().onLeftClick( - [&](pm::vertex_index vertex_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_LEFT_CLICK" - << "ID: " << int(vertex_id) << std::endl; - std::cout << "World_Position" << world_pos << std::endl; - std::cout << "Normal" << normal << std::endl; - return; - }), + gv::pick().onLeftClick([&](pm::vertex_index vertex_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_LEFT_CLICK" + << "ID: " << int(vertex_id) << std::endl; + std::cout << "World_Position" << world_pos << std::endl; + std::cout << "Normal" << normal << std::endl; + return; + }), "picking PointRenderables - callback on left click - billboards"); } } @@ -998,25 +973,19 @@ void picking(pm::Mesh& m, pm::vertex_attribute<tg::pos3>& pos, pm::face_attribut auto g = gv::grid(); // Only on_right_click callback defined - gv::view(pos, col, - gv::pick().onRightClick( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_RIGHT_CLICK" - << "ID: " << int(face_id) << std::endl; - return; - }), + gv::view(pos, col, gv::pick().onRightClick([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_RIGHT_CLICK" + << "ID: " << int(face_id) << std::endl; + return; + }), "picking MeshRenderable - callback on right click"); // Only on_hover callback defined - gv::view(pos, col, - gv::pick().onHover( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_HOVER" - << "ID: " << (int)face_id << std::endl; - return; - }), + gv::view(pos, col, gv::pick().onHover([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_HOVER" + << "ID: " << (int)face_id << std::endl; + return; + }), "picking MeshRenderable - callback on hover"); } @@ -1033,45 +1002,40 @@ void picking(pm::Mesh& m, pm::vertex_attribute<tg::pos3>& pos, pm::face_attribut pm::vertex_attribute<tg::pos3> pos2(m2); pos2.copy_from(pos); - gv::interactive( - [&](auto) + gv::interactive([&](auto) { + gv::view(pos2, col, gv::pick().onLeftClick([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_LEFT_CLICK" + << "ID: " << int(face_id) << std::endl; + std::cout << "World_Position" << world_pos << std::endl; + std::cout << "Normal" << normal << std::endl; + + face_index_i = face_id; + world_pos_i = world_pos; + normal_i = normal; + }), + "picking interactive mode - callback on left click - delete selected face"); + + ImGui::Begin("Picking"); + + ImGui::Value("pm::face_index", face_index_i.value); + + ImGui::Value("WorldPos.x", world_pos_i.x); + ImGui::Value("WorldPos.y", world_pos_i.y); + ImGui::Value("WorldPos.z", world_pos_i.z); + + ImGui::Value("Normal.x", normal_i.x); + ImGui::Value("Normal.y", normal_i.y); + ImGui::Value("Normal.z", normal_i.z); + + if (ImGui::Button("Delete selected face")) { - gv::view(pos2, col, - gv::pick().onLeftClick( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_LEFT_CLICK" - << "ID: " << int(face_id) << std::endl; - std::cout << "World_Position" << world_pos << std::endl; - std::cout << "Normal" << normal << std::endl; - - face_index_i = face_id; - world_pos_i = world_pos; - normal_i = normal; - }), - "picking interactive mode - callback on left click - delete selected face"); - - ImGui::Begin("Picking"); - - ImGui::Value("pm::face_index", face_index_i.value); - - ImGui::Value("WorldPos.x", world_pos_i.x); - ImGui::Value("WorldPos.y", world_pos_i.y); - ImGui::Value("WorldPos.z", world_pos_i.z); - - ImGui::Value("Normal.x", normal_i.x); - ImGui::Value("Normal.y", normal_i.y); - ImGui::Value("Normal.z", normal_i.z); - - if (ImGui::Button("Delete selected face")) - { - // delete selected face - after deleting one face another face has to be picked - std::cout << "DELETE FACE" << std::endl; - m2.faces().remove(m2.faces()[face_index_i]); - } - - ImGui::End(); - }); + // delete selected face - after deleting one face another face has to be picked + std::cout << "DELETE FACE" << std::endl; + m2.faces().remove(m2.faces()[face_index_i]); + } + + ImGui::End(); + }); } { @@ -1087,74 +1051,64 @@ void picking(pm::Mesh& m, pm::vertex_attribute<tg::pos3>& pos, pm::face_attribut pm::vertex_attribute<tg::pos3> pos2(m2); pos2.copy_from(pos); - gv::interactive( - [&](auto) + gv::interactive([&](auto) { + gv::view(gv::points(pos2), + gv::pick().onLeftClick([&vertex_index_i, &world_pos_i, &normal_i](pm::vertex_index vertex_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_LEFT_CLICK" + << "ID: " << int(vertex_id) << std::endl; + std::cout << "World_Position" << world_pos << std::endl; + std::cout << "Normal" << normal << std::endl; + + vertex_index_i = vertex_id; + world_pos_i = world_pos; + normal_i = normal; + + return; + }), + "picking interactive mode - PointRenderable"); + + ImGui::Begin("Picking"); + + ImGui::Value("pm::vertex_index", vertex_index_i.value); + + ImGui::Value("WorldPos.x", world_pos_i.x); + ImGui::Value("WorldPos.y", world_pos_i.y); + ImGui::Value("WorldPos.z", world_pos_i.z); + + ImGui::Value("Normal.x", normal_i.x); + ImGui::Value("Normal.y", normal_i.y); + ImGui::Value("Normal.z", normal_i.z); + + if (ImGui::Button("Delete selected vertex")) { - gv::view(gv::points(pos2), - gv::pick().onLeftClick( - [&vertex_index_i, &world_pos_i, &normal_i](pm::vertex_index vertex_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_LEFT_CLICK" - << "ID: " << int(vertex_id) << std::endl; - std::cout << "World_Position" << world_pos << std::endl; - std::cout << "Normal" << normal << std::endl; - - vertex_index_i = vertex_id; - world_pos_i = world_pos; - normal_i = normal; - - return; - }), - "picking interactive mode - PointRenderable"); - - ImGui::Begin("Picking"); - - ImGui::Value("pm::vertex_index", vertex_index_i.value); - - ImGui::Value("WorldPos.x", world_pos_i.x); - ImGui::Value("WorldPos.y", world_pos_i.y); - ImGui::Value("WorldPos.z", world_pos_i.z); - - ImGui::Value("Normal.x", normal_i.x); - ImGui::Value("Normal.y", normal_i.y); - ImGui::Value("Normal.z", normal_i.z); - - if (ImGui::Button("Delete selected vertex")) - { - // delete selected vertex - after deleting one vertex another vertex has to be picked - std::cout << "DELETE VERTEX" << std::endl; - m2.vertices().remove(m2.vertices()[vertex_index_i]); - } - - ImGui::End(); - }); + // delete selected vertex - after deleting one vertex another vertex has to be picked + std::cout << "DELETE VERTEX" << std::endl; + m2.vertices().remove(m2.vertices()[vertex_index_i]); + } + + ImGui::End(); + }); } { // On_hover, on_right_click, and on_left_click callbacks defined simultaneously gv::view(pos, col, gv::pick() - .onLeftClick( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_LEFT_CLICK" - << "ID: " << int(face_id) << std::endl; - return; - }) - .onRightClick( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_RIGHT_CLICK" - << "ID: " << int(face_id) << std::endl; - return; - }) - .onHover( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) - { - std::cout << "Something has been picked! ON_HOVER" - << "ID: " << int(face_id) << std::endl; - return; - }), + .onLeftClick([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_LEFT_CLICK" + << "ID: " << int(face_id) << std::endl; + return; + }) + .onRightClick([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_RIGHT_CLICK" + << "ID: " << int(face_id) << std::endl; + return; + }) + .onHover([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) { + std::cout << "Something has been picked! ON_HOVER" + << "ID: " << int(face_id) << std::endl; + return; + }), "picking MeshRenderable - multiple callbacks: on left click, on right click, on hover"); } @@ -1167,18 +1121,15 @@ void picking(pm::Mesh& m, pm::vertex_attribute<tg::pos3>& pos, pm::face_attribut fa[f] = 1000 + i; i++; } - gv::view(pos, col, - gv::pick(fa).onLeftClick( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) -> gv::picking_result - { - std::cout << "Something has been picked! ON_LEFT_CLICK" - << "ID: " << (int)face_id << std::endl; - std::cout << "World_Position" << world_pos << std::endl; - std::cout << "Normal" << normal << std::endl; - gv::picking_result res; - res.pickingColor = tg::color3::cyan; - return res; - }), + gv::view(pos, col, gv::pick(fa).onLeftClick([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) -> gv::picking_result { + std::cout << "Something has been picked! ON_LEFT_CLICK" + << "ID: " << (int)face_id << std::endl; + std::cout << "World_Position" << world_pos << std::endl; + std::cout << "Normal" << normal << std::endl; + gv::picking_result res; + res.pickingColor = tg::color3::cyan; + return res; + }), "simple picking: callback on left click - user-defined IDs"); } @@ -1186,17 +1137,15 @@ void picking(pm::Mesh& m, pm::vertex_attribute<tg::pos3>& pos, pm::face_attribut auto v = gv::view(pos, "pciking multiple renderables: different callbacks defined"); // Check multiple Renderables. - gv::view(pos, gv::pick().onHover( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) -> gv::picking_result - { - std::cout << "Something has been picked! PICKER 1 " - << "ID: " << (int)face_id << std::endl; - std::cout << "World_Position" << world_pos << std::endl; - std::cout << "Normal" << normal << std::endl; - gv::picking_result res; - res.pickingColor = tg::color3::cyan; - return res; - })); + gv::view(pos, gv::pick().onHover([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) -> gv::picking_result { + std::cout << "Something has been picked! PICKER 1 " + << "ID: " << (int)face_id << std::endl; + std::cout << "World_Position" << world_pos << std::endl; + std::cout << "Normal" << normal << std::endl; + gv::picking_result res; + res.pickingColor = tg::color3::cyan; + return res; + })); pm::Mesh m2; m2.copy_from(m); @@ -1209,17 +1158,15 @@ void picking(pm::Mesh& m, pm::vertex_attribute<tg::pos3>& pos, pm::face_attribut pos2[p] = pos2[p] + tg::vec3(2, 2, 2); } - gv::view(pos2, gv::pick().onLeftClick( - [&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) -> gv::picking_result - { - std::cout << "Something has been picked! PICKER 2 " - << "ID: " << (int)face_id << std::endl; - std::cout << "World_Position" << world_pos << std::endl; - std::cout << "Normal" << normal << std::endl; - gv::picking_result res; - res.pickingColor = tg::color3::cyan; - return res; - })); + gv::view(pos2, gv::pick().onLeftClick([&](pm::face_index face_id, tg::pos3 world_pos, tg::vec3 normal) -> gv::picking_result { + std::cout << "Something has been picked! PICKER 2 " + << "ID: " << (int)face_id << std::endl; + std::cout << "World_Position" << world_pos << std::endl; + std::cout << "Normal" << normal << std::endl; + gv::picking_result res; + res.pickingColor = tg::color3::cyan; + return res; + })); } } @@ -1330,27 +1277,23 @@ void special_use_cases(pm::vertex_attribute<tg::pos3> const& pos) { auto const r = gv::make_renderable(pos); - gv::interactive( - [r](auto dt) - { - static auto time = 0.f; - time += dt; + gv::interactive([r](auto dt) { + static auto time = 0.f; + time += dt; - // gv::view_cleared creates an always cleared view, resetting accumulation each frame - gv::view_cleared(r, tg::translation(tg::vec3(tg::sin(tg::radians(time * .5f)) * .5f, 0.f, 0.f))); - }); + // gv::view_cleared creates an always cleared view, resetting accumulation each frame + gv::view_cleared(r, tg::translation(tg::vec3(tg::sin(tg::radians(time * .5f)) * .5f, 0.f, 0.f))); + }); - gv::interactive( - [r](auto) - { - static float configurable = 0.f; + gv::interactive([r](auto) { + static float configurable = 0.f; - auto changed = false; - changed |= ImGui::SliderFloat("Height", &configurable, -3.f, 3.f); + auto changed = false; + changed |= ImGui::SliderFloat("Height", &configurable, -3.f, 3.f); - // gv::clear_accumulation conditionally clears the view accumulation - gv::view(r, tg::translation(tg::vec3(0.f, configurable, 0.f)), gv::clear_accumulation(changed)); - }); + // gv::clear_accumulation conditionally clears the view accumulation + gv::view(r, tg::translation(tg::vec3(0.f, configurable, 0.f)), gv::clear_accumulation(changed)); + }); } }