Skip to content
Snippets Groups Projects
Commit 0a1b1692 authored by Philip Trettner's avatar Philip Trettner
Browse files

Merge branch 'ak/develop' into 'develop'

picking samples

See merge request Glow/glow-samples!16
parents f75647c7 1acb107f
Branches
No related tags found
1 merge request!16picking samples
Pipeline #22158 passed
......@@ -33,5 +33,8 @@
url = https://github.com/g-truc/glm
[submodule "extern/typed-geometry"]
path = extern/typed-geometry
url = https://www.graphics.rwth-aachen.de:9000/ptrettner/typed-geometry.git
url = https://github.com/project-arcana/typed-geometry.git
branch = develop
[submodule "extern/clean-core"]
path = extern/clean-core
url = https://github.com/project-arcana/clean-core.git
......@@ -49,6 +49,9 @@ if (GCC)
endif()
endif()
# Add clean-core lib
add_subdirectory(extern/clean-core)
# Add typed geometry math lib
add_subdirectory(extern/typed-geometry)
......@@ -119,6 +122,7 @@ if (GLOW_SAMPLES_TESTS)
add_executable(glow-tests ${SOURCES})
target_link_libraries(glow-tests PUBLIC
clean-core
typed-geometry
glm
polymesh
......
Subproject commit b3602fb50a1a2bdc4be2e487e469d5a23946cd6c
eigen @ 01f91925
Subproject commit 64fdd839aa0dc18483fdf23f4d7c5c3c414948b1
Subproject commit 01f91925c0cf2aca052b592f75fa088d7ac45da7
Subproject commit 1d95acdf565f65894f38b8742afde8dbbb80baef
Subproject commit dd8a678a66f1967372e5a5e3deac41ebf65ee127
glow @ 6454151b
Subproject commit 8f61a37a14c2bf66b5cdd894fa82017752322f79
Subproject commit 6454151bd41eb2c7e1dfc079b90f27fc62be77d6
glow-extras @ 3ad42b0f
Subproject commit 48afcb1fdbcaf874f7d58d86545525bca554696c
Subproject commit 3ad42b0f2b1744bfab95500d86b1e93ae5ceb959
imgui @ 440ba209
Subproject commit 8ca0ab36f8a5072b8dfaf569646233166f507c84
Subproject commit 440ba209b1794c54699fd6c62be984c4f5fd6a5f
polymesh @ 77b5ad3b
Subproject commit 76e20b6b8aa4b80cca568922dc5907a49c2136b0
Subproject commit 77b5ad3b1454a0184fd91215982d88a150b65d98
Subproject commit 36314b73b45aba62252fabfc142bd18b21d21acf
Subproject commit abaaa145c9d0902397d5226235a64f321fa0b364
......@@ -14,6 +14,7 @@
#include <glow-extras/vector/graphics2D.hh>
#include <glow-extras/vector/image2D.hh>
#include <glow-extras/viewer/canvas.hh>
#include <glow-extras/viewer/picking.hh>
#include <glow-extras/viewer/view.hh>
#include <GLFW/glfw3.h>
......@@ -23,6 +24,7 @@
// path to sample files
std::string const dataPath = glow::util::pathOf(__FILE__) + "/../../../data/";
void simple_view(pm::vertex_attribute<tg::pos3> const& pos)
{
// the simplest possible view: just a mesh
......@@ -903,9 +905,266 @@ void custom_renderables()
// TODO
}
void picking()
void picking(pm::Mesh& m, pm::vertex_attribute<tg::pos3>& pos, pm::face_attribute<tg::color3> const& col)
{
// TODO
// gv::view(obj, args, gv::pick().on...([&](pm::face_index, tg::pos3, tg::vec3){...}), ...);
// adds a Picker to a Renderable (MeshRenderable, PointRenderable, LineRenderable) that enables the picking of individual primitives and the visual representation
// every time a primitive gets picked, the callback function defined in the gv::pick().on...() call will be executed
// picking can be defined on up to two buttons and on hover (gv::pick().onLeftClick(...), gv::pick().onRightClick(...), gv::pick().onHover(...)).
// callback functions need to have the signature as given above and might return a gv::view::picking_result or void.
// gv::view::picking_result as return type can change the visual appearence of the picked primitive via modifying the member attributes pickingColor, borderColor, and borderWidth;
//
// in interactive mode (gv::interactive()) operations on picked primitives can be performed
{
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;
}),
"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;
}),
"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;
}),
"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;
}),
"picking PointRenderables - callback on left click - billboards");
}
}
{
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;
}),
"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;
}),
"picking MeshRenderable - callback on hover");
}
{
/* Picking in interactive mode with ImGui example */
pm::face_index face_index_i;
uint32_t face_id_i;
tg::pos3 world_pos_i;
tg::vec3 normal_i;
pm::Mesh m2;
m2.copy_from(m);
pm::vertex_attribute<tg::pos3> pos2(m2);
pos2.copy_from(pos);
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"))
{
// 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();
});
}
{
/* Picking in interactive mode with ImGui example.*/
pm::vertex_index vertex_index_i;
uint32_t vertex_id_i;
tg::pos3 world_pos_i;
tg::vec3 normal_i;
pm::Mesh m2;
m2.copy_from(m);
pm::vertex_attribute<tg::pos3> pos2(m2);
pos2.copy_from(pos);
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"))
{
// 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;
}),
"picking MeshRenderable - multiple callbacks: on left click, on right click, on hover");
}
{
// User-defined Picking IDs - MeshRenderable
pm::face_attribute<int32_t> fa = pm::face_attribute<int32_t>(m);
int i = 0;
for (auto f : m.faces())
{
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;
}),
"simple picking: callback on left click - user-defined IDs");
}
{
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;
}));
pm::Mesh m2;
m2.copy_from(m);
pm::vertex_attribute<tg::pos3> pos2(m2);
pos2.copy_from(pos);
for (auto p : m2.vertices())
{
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;
}));
}
}
void headless_screenshot(pm::vertex_attribute<tg::pos3> const& pos)
......@@ -1086,7 +1345,17 @@ int main()
pm::Mesh m;
auto pos = m.vertices().make_attribute<tg::pos3>();
load(dataPath + "suzanne.obj", m, pos);
normalize(pos); // make it -1..1
normalize(pos); // make it -1..1*/
auto col = pm::face_attribute<tg::color3>(m);
// initially random colors for faces (picking sample)
auto r = tg::rng();
for (auto x : m.faces())
{
tg::color3 color;
color = tg::uniform<tg::color3>(r);
col[x] = color;
}
// basic demos
{
......@@ -1118,6 +1387,8 @@ int main()
{
vector_graphics();
picking(m, pos, col);
custom_renderables();
special_use_cases(pos);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment