Added new type of SceneRaycaster (FallbackGizmo)

to add possibility to split the Gizmo grabbers to two priority of "raycastering".
meshes with Gizmo type has highest priority then FallbackGizmo.

+ CutGizmo: Use SceneRaycaster type for CutPlane grabber
This commit is contained in:
YuSanka 2023-08-01 16:23:18 +02:00
parent 0c686f1ff9
commit 75eccfd650
4 changed files with 52 additions and 3 deletions

View File

@ -2684,6 +2684,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
if (curr_gizmo != nullptr) if (curr_gizmo != nullptr)
curr_gizmo->unregister_raycasters_for_picking(); curr_gizmo->unregister_raycasters_for_picking();
m_scene_raycaster.remove_raycasters(SceneRaycaster::EType::Gizmo); m_scene_raycaster.remove_raycasters(SceneRaycaster::EType::Gizmo);
if (curr_gizmo != nullptr && !m_selection.is_empty())
curr_gizmo->register_raycasters_for_picking();
m_scene_raycaster.remove_raycasters(SceneRaycaster::EType::FallbackGizmo);
if (curr_gizmo != nullptr && !m_selection.is_empty()) if (curr_gizmo != nullptr && !m_selection.is_empty())
curr_gizmo->register_raycasters_for_picking(); curr_gizmo->register_raycasters_for_picking();
@ -5744,6 +5747,7 @@ void GLCanvas3D::_picking_pass()
break; break;
} }
case SceneRaycaster::EType::Gizmo: case SceneRaycaster::EType::Gizmo:
case SceneRaycaster::EType::FallbackGizmo:
{ {
const Size& cnv_size = get_canvas_size(); const Size& cnv_size = get_canvas_size();
const bool inside = 0 <= m_mouse.position.x() && m_mouse.position.x() < cnv_size.get_width() && const bool inside = 0 <= m_mouse.position.x() && m_mouse.position.x() < cnv_size.get_width() &&
@ -5776,6 +5780,7 @@ void GLCanvas3D::_picking_pass()
{ {
case SceneRaycaster::EType::Bed: { object_type = "Bed"; break; } case SceneRaycaster::EType::Bed: { object_type = "Bed"; break; }
case SceneRaycaster::EType::Gizmo: { object_type = "Gizmo element"; break; } case SceneRaycaster::EType::Gizmo: { object_type = "Gizmo element"; break; }
case SceneRaycaster::EType::FallbackGizmo: { object_type = "Gizmo2 element"; break; }
case SceneRaycaster::EType::Volume: case SceneRaycaster::EType::Volume:
{ {
if (m_volumes.volumes[hit.raycaster_id]->is_wipe_tower) if (m_volumes.volumes[hit.raycaster_id]->is_wipe_tower)
@ -5830,6 +5835,8 @@ void GLCanvas3D::_picking_pass()
add_strings_row_to_table("Volumes", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table("Volumes", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text));
sprintf(buf, "%d (%d)", (int)m_scene_raycaster.gizmos_count(), (int)m_scene_raycaster.active_gizmos_count()); sprintf(buf, "%d (%d)", (int)m_scene_raycaster.gizmos_count(), (int)m_scene_raycaster.active_gizmos_count());
add_strings_row_to_table("Gizmo elements", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text)); add_strings_row_to_table("Gizmo elements", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text));
sprintf(buf, "%d (%d)", (int)m_scene_raycaster.fallback_gizmos_count(), (int)m_scene_raycaster.active_fallback_gizmos_count());
add_strings_row_to_table("Gizmo2 elements", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text));
ImGui::EndTable(); ImGui::EndTable();
} }
@ -5847,6 +5854,20 @@ void GLCanvas3D::_picking_pass()
} }
} }
std::vector<std::shared_ptr<SceneRaycasterItem>>* gizmo2_raycasters = m_scene_raycaster.get_raycasters(SceneRaycaster::EType::FallbackGizmo);
if (gizmo2_raycasters != nullptr && !gizmo2_raycasters->empty()) {
ImGui::Separator();
imgui.text("Gizmo2 raycasters IDs:");
if (ImGui::BeginTable("Gizmo2Raycasters", 3)) {
for (size_t i = 0; i < gizmo2_raycasters->size(); ++i) {
add_strings_row_to_table(std::to_string(i), ImGuiWrapper::COL_ORANGE_LIGHT,
std::to_string(SceneRaycaster::decode_id(SceneRaycaster::EType::FallbackGizmo, (*gizmo2_raycasters)[i]->get_id())), ImGui::GetStyleColorVec4(ImGuiCol_Text),
to_string(Geometry::Transformation((*gizmo2_raycasters)[i]->get_transform()).get_offset()), ImGui::GetStyleColorVec4(ImGuiCol_Text));
}
ImGui::EndTable();
}
}
imgui.end(); imgui.end();
#endif // ENABLE_RAYCAST_PICKING_DEBUG #endif // ENABLE_RAYCAST_PICKING_DEBUG
} }

View File

@ -1575,7 +1575,7 @@ void GLGizmoCut3D::on_register_raycasters_for_picking()
m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, Z, *m_sphere.mesh_raycaster, Transform3d::Identity())); m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, Z, *m_sphere.mesh_raycaster, Transform3d::Identity()));
m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CutPlane, *m_plane.mesh_raycaster, Transform3d::Identity())); m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::FallbackGizmo, CutPlane, *m_plane.mesh_raycaster, Transform3d::Identity()));
if (CutMode(m_mode) == CutMode::cutTongueAndGroove) { if (CutMode(m_mode) == CutMode::cutTongueAndGroove) {
m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CutPlaneZRotation, *m_sphere.mesh_raycaster, Transform3d::Identity())); m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CutPlaneZRotation, *m_sphere.mesh_raycaster, Transform3d::Identity()));
@ -1596,6 +1596,7 @@ void GLGizmoCut3D::on_register_raycasters_for_picking()
void GLGizmoCut3D::on_unregister_raycasters_for_picking() void GLGizmoCut3D::on_unregister_raycasters_for_picking()
{ {
m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo); m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::Gizmo);
m_parent.remove_raycasters_for_picking(SceneRaycaster::EType::FallbackGizmo);
m_raycasters.clear(); m_raycasters.clear();
// the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account // the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account
m_parent.set_raycaster_gizmos_on_top(false); m_parent.set_raycaster_gizmos_on_top(false);

View File

@ -40,6 +40,7 @@ std::shared_ptr<SceneRaycasterItem> SceneRaycaster::add_raycaster(EType type, in
case EType::Bed: { return m_bed.emplace_back(std::make_shared<SceneRaycasterItem>(encode_id(type, id), raycaster, trafo, use_back_faces)); } case EType::Bed: { return m_bed.emplace_back(std::make_shared<SceneRaycasterItem>(encode_id(type, id), raycaster, trafo, use_back_faces)); }
case EType::Volume: { return m_volumes.emplace_back(std::make_shared<SceneRaycasterItem>(encode_id(type, id), raycaster, trafo, use_back_faces)); } case EType::Volume: { return m_volumes.emplace_back(std::make_shared<SceneRaycasterItem>(encode_id(type, id), raycaster, trafo, use_back_faces)); }
case EType::Gizmo: { return m_gizmos.emplace_back(std::make_shared<SceneRaycasterItem>(encode_id(type, id), raycaster, trafo, use_back_faces)); } case EType::Gizmo: { return m_gizmos.emplace_back(std::make_shared<SceneRaycasterItem>(encode_id(type, id), raycaster, trafo, use_back_faces)); }
case EType::FallbackGizmo: { return m_fallback_gizmos.emplace_back(std::make_shared<SceneRaycasterItem>(encode_id(type, id), raycaster, trafo, use_back_faces)); }
default: { assert(false); return nullptr; } default: { assert(false); return nullptr; }
}; };
} }
@ -62,6 +63,7 @@ void SceneRaycaster::remove_raycasters(EType type)
case EType::Bed: { m_bed.clear(); break; } case EType::Bed: { m_bed.clear(); break; }
case EType::Volume: { m_volumes.clear(); break; } case EType::Volume: { m_volumes.clear(); break; }
case EType::Gizmo: { m_gizmos.clear(); break; } case EType::Gizmo: { m_gizmos.clear(); break; }
case EType::FallbackGizmo: { m_fallback_gizmos.clear(); break; }
default: { break; } default: { break; }
}; };
} }
@ -86,6 +88,12 @@ void SceneRaycaster::remove_raycaster(std::shared_ptr<SceneRaycasterItem> item)
return; return;
} }
} }
for (auto it = m_fallback_gizmos.begin(); it != m_fallback_gizmos.end(); ++it) {
if (*it == item) {
m_fallback_gizmos.erase(it);
return;
}
}
} }
SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Camera& camera, const ClippingPlane* clipping_plane) const SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Camera& camera, const ClippingPlane* clipping_plane) const
@ -174,6 +182,9 @@ SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Came
if (!m_gizmos.empty()) if (!m_gizmos.empty())
test_raycasters(EType::Gizmo, mouse_pos, camera, ret); test_raycasters(EType::Gizmo, mouse_pos, camera, ret);
if (!m_fallback_gizmos.empty() && !ret.is_valid())
test_raycasters(EType::FallbackGizmo, mouse_pos, camera, ret);
if (!m_gizmos_on_top || !ret.is_valid()) { if (!m_gizmos_on_top || !ret.is_valid()) {
if (camera.is_looking_downward() && !m_bed.empty()) if (camera.is_looking_downward() && !m_bed.empty())
test_raycasters(EType::Bed, mouse_pos, camera, ret); test_raycasters(EType::Bed, mouse_pos, camera, ret);
@ -241,6 +252,14 @@ size_t SceneRaycaster::active_gizmos_count() const {
} }
return count; return count;
} }
size_t SceneRaycaster::active_fallback_gizmos_count() const {
size_t count = 0;
for (const auto& g : m_fallback_gizmos) {
if (g->is_active())
++count;
}
return count;
}
#endif // ENABLE_RAYCAST_PICKING_DEBUG #endif // ENABLE_RAYCAST_PICKING_DEBUG
std::vector<std::shared_ptr<SceneRaycasterItem>>* SceneRaycaster::get_raycasters(EType type) std::vector<std::shared_ptr<SceneRaycasterItem>>* SceneRaycaster::get_raycasters(EType type)
@ -251,6 +270,7 @@ std::vector<std::shared_ptr<SceneRaycasterItem>>* SceneRaycaster::get_raycasters
case EType::Bed: { ret = &m_bed; break; } case EType::Bed: { ret = &m_bed; break; }
case EType::Volume: { ret = &m_volumes; break; } case EType::Volume: { ret = &m_volumes; break; }
case EType::Gizmo: { ret = &m_gizmos; break; } case EType::Gizmo: { ret = &m_gizmos; break; }
case EType::FallbackGizmo: { ret = &m_fallback_gizmos; break; }
default: { break; } default: { break; }
} }
assert(ret != nullptr); assert(ret != nullptr);
@ -265,6 +285,7 @@ const std::vector<std::shared_ptr<SceneRaycasterItem>>* SceneRaycaster::get_rayc
case EType::Bed: { ret = &m_bed; break; } case EType::Bed: { ret = &m_bed; break; }
case EType::Volume: { ret = &m_volumes; break; } case EType::Volume: { ret = &m_volumes; break; }
case EType::Gizmo: { ret = &m_gizmos; break; } case EType::Gizmo: { ret = &m_gizmos; break; }
case EType::FallbackGizmo: { ret = &m_fallback_gizmos; break; }
default: { break; } default: { break; }
} }
assert(ret != nullptr); assert(ret != nullptr);
@ -278,6 +299,7 @@ int SceneRaycaster::base_id(EType type)
case EType::Bed: { return int(EIdBase::Bed); } case EType::Bed: { return int(EIdBase::Bed); }
case EType::Volume: { return int(EIdBase::Volume); } case EType::Volume: { return int(EIdBase::Volume); }
case EType::Gizmo: { return int(EIdBase::Gizmo); } case EType::Gizmo: { return int(EIdBase::Gizmo); }
case EType::FallbackGizmo: { return int(EIdBase::FallbackGizmo); }
default: { break; } default: { break; }
}; };

View File

@ -42,14 +42,16 @@ public:
None, None,
Bed, Bed,
Volume, Volume,
Gizmo Gizmo,
FallbackGizmo // Is used for gizmo grabbers which will be hit after all grabbers of Gizmo type
}; };
enum class EIdBase enum class EIdBase
{ {
Bed = 0, Bed = 0,
Volume = 1000, Volume = 1000,
Gizmo = 1000000 Gizmo = 1000000,
FallbackGizmo = 2000000
}; };
struct HitResult struct HitResult
@ -66,6 +68,7 @@ private:
std::vector<std::shared_ptr<SceneRaycasterItem>> m_bed; std::vector<std::shared_ptr<SceneRaycasterItem>> m_bed;
std::vector<std::shared_ptr<SceneRaycasterItem>> m_volumes; std::vector<std::shared_ptr<SceneRaycasterItem>> m_volumes;
std::vector<std::shared_ptr<SceneRaycasterItem>> m_gizmos; std::vector<std::shared_ptr<SceneRaycasterItem>> m_gizmos;
std::vector<std::shared_ptr<SceneRaycasterItem>> m_fallback_gizmos;
// When set to true, if checking gizmos returns a valid hit, // When set to true, if checking gizmos returns a valid hit,
// the search is not performed on other types // the search is not performed on other types
@ -99,9 +102,11 @@ public:
size_t beds_count() const { return m_bed.size(); } size_t beds_count() const { return m_bed.size(); }
size_t volumes_count() const { return m_volumes.size(); } size_t volumes_count() const { return m_volumes.size(); }
size_t gizmos_count() const { return m_gizmos.size(); } size_t gizmos_count() const { return m_gizmos.size(); }
size_t fallback_gizmos_count() const { return m_fallback_gizmos.size(); }
size_t active_beds_count() const; size_t active_beds_count() const;
size_t active_volumes_count() const; size_t active_volumes_count() const;
size_t active_gizmos_count() const; size_t active_gizmos_count() const;
size_t active_fallback_gizmos_count() const;
#endif // ENABLE_RAYCAST_PICKING_DEBUG #endif // ENABLE_RAYCAST_PICKING_DEBUG
static int decode_id(EType type, int id); static int decode_id(EType type, int id);