Tech ENABLE_RAYCAST_PICKING - Gizmo flatten: fixed update of raycasters transformations
This commit is contained in:
parent
b9caacfdd9
commit
2a2d442b28
@ -659,8 +659,9 @@ public:
|
|||||||
void post_event(wxEvent &&event);
|
void post_event(wxEvent &&event);
|
||||||
|
|
||||||
#if ENABLE_RAYCAST_PICKING
|
#if ENABLE_RAYCAST_PICKING
|
||||||
std::shared_ptr<SceneRaycasterItem> add_raycaster_for_picking(SceneRaycaster::EType type, int id, const MeshRaycaster& raycaster, const Transform3d& trafo) {
|
std::shared_ptr<SceneRaycasterItem> add_raycaster_for_picking(SceneRaycaster::EType type, int id, const MeshRaycaster& raycaster,
|
||||||
return m_scene_raycaster.add_raycaster(type, id, raycaster, trafo);
|
const Transform3d& trafo, bool use_back_faces = false) {
|
||||||
|
return m_scene_raycaster.add_raycaster(type, id, raycaster, trafo, use_back_faces);
|
||||||
}
|
}
|
||||||
void remove_raycasters_for_picking(SceneRaycaster::EType type, int id) {
|
void remove_raycasters_for_picking(SceneRaycaster::EType type, int id) {
|
||||||
m_scene_raycaster.remove_raycasters(type, id);
|
m_scene_raycaster.remove_raycasters(type, id);
|
||||||
|
@ -116,24 +116,25 @@ void GLGizmoFlatten::on_render()
|
|||||||
glsafe(::glEnable(GL_BLEND));
|
glsafe(::glEnable(GL_BLEND));
|
||||||
|
|
||||||
if (selection.is_single_full_instance()) {
|
if (selection.is_single_full_instance()) {
|
||||||
const Transform3d& m = selection.get_first_volume()->get_instance_transformation().get_matrix();
|
const Transform3d& inst_matrix = selection.get_first_volume()->get_instance_transformation().get_matrix();
|
||||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
const Transform3d view_model_matrix = camera.get_view_matrix() *
|
const Transform3d model_matrix = Geometry::assemble_transform(selection.get_first_volume()->get_sla_shift_z() * Vec3d::UnitZ()) * inst_matrix;
|
||||||
Geometry::assemble_transform(selection.get_first_volume()->get_sla_shift_z() * Vec3d::UnitZ()) * m;
|
const Transform3d view_model_matrix = camera.get_view_matrix() * model_matrix;
|
||||||
|
|
||||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||||
#else
|
#else
|
||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
glsafe(::glTranslatef(0.f, 0.f, selection.get_first_volume()->get_sla_shift_z()));
|
glsafe(::glTranslatef(0.f, 0.f, selection.get_first_volume()->get_sla_shift_z()));
|
||||||
glsafe(::glMultMatrixd(m.data()));
|
glsafe(::glMultMatrixd(inst_matrix.data()));
|
||||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||||
if (this->is_plane_update_necessary())
|
if (this->is_plane_update_necessary())
|
||||||
update_planes();
|
update_planes();
|
||||||
for (int i = 0; i < (int)m_planes.size(); ++i) {
|
for (int i = 0; i < (int)m_planes.size(); ++i) {
|
||||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||||
#if ENABLE_RAYCAST_PICKING
|
#if ENABLE_RAYCAST_PICKING
|
||||||
|
m_planes_casters[i]->set_transform(model_matrix);
|
||||||
m_planes[i].vbo.model.set_color(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR : DEFAULT_PLANE_COLOR);
|
m_planes[i].vbo.model.set_color(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR : DEFAULT_PLANE_COLOR);
|
||||||
m_planes[i].vbo.model.render();
|
m_planes[i].vbo.model.render();
|
||||||
#else
|
#else
|
||||||
@ -165,13 +166,15 @@ void GLGizmoFlatten::on_register_raycasters_for_picking()
|
|||||||
// 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(true);
|
m_parent.set_raycaster_gizmos_on_top(true);
|
||||||
|
|
||||||
|
assert(m_planes_casters.empty());
|
||||||
|
|
||||||
if (!m_planes.empty()) {
|
if (!m_planes.empty()) {
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
const Transform3d matrix = Geometry::assemble_transform(selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z() * Vec3d::UnitZ()) *
|
const Transform3d matrix = Geometry::assemble_transform(selection.get_first_volume()->get_sla_shift_z() * Vec3d::UnitZ()) *
|
||||||
selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix();
|
selection.get_first_volume()->get_instance_transformation().get_matrix();
|
||||||
|
|
||||||
for (int i = 0; i < (int)m_planes.size(); ++i) {
|
for (int i = 0; i < (int)m_planes.size(); ++i) {
|
||||||
m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, i, *m_planes[i].vbo.mesh_raycaster, matrix);
|
m_planes_casters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, i, *m_planes[i].vbo.mesh_raycaster, matrix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,6 +183,7 @@ void GLGizmoFlatten::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.set_raycaster_gizmos_on_top(false);
|
m_parent.set_raycaster_gizmos_on_top(false);
|
||||||
|
m_planes_casters.clear();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void GLGizmoFlatten::on_render_for_picking()
|
void GLGizmoFlatten::on_render_for_picking()
|
||||||
@ -238,7 +242,6 @@ void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object)
|
|||||||
{
|
{
|
||||||
if (model_object != m_old_model_object) {
|
if (model_object != m_old_model_object) {
|
||||||
m_planes.clear();
|
m_planes.clear();
|
||||||
m_planes_valid = false;
|
|
||||||
#if ENABLE_RAYCAST_PICKING
|
#if ENABLE_RAYCAST_PICKING
|
||||||
on_unregister_raycasters_for_picking();
|
on_unregister_raycasters_for_picking();
|
||||||
#endif // ENABLE_RAYCAST_PICKING
|
#endif // ENABLE_RAYCAST_PICKING
|
||||||
@ -498,7 +501,6 @@ void GLGizmoFlatten::update_planes()
|
|||||||
#if ENABLE_RAYCAST_PICKING
|
#if ENABLE_RAYCAST_PICKING
|
||||||
on_register_raycasters_for_picking();
|
on_register_raycasters_for_picking();
|
||||||
#endif // ENABLE_RAYCAST_PICKING
|
#endif // ENABLE_RAYCAST_PICKING
|
||||||
m_planes_valid = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -508,8 +510,8 @@ bool GLGizmoFlatten::is_plane_update_necessary() const
|
|||||||
if (m_state != On || ! mo || mo->instances.empty())
|
if (m_state != On || ! mo || mo->instances.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (! m_planes_valid || mo != m_old_model_object
|
if (m_planes.empty() || mo != m_old_model_object
|
||||||
|| mo->volumes.size() != m_volumes_matrices.size())
|
|| mo->volumes.size() != m_volumes_matrices.size())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// We want to recalculate when the scale changes - some planes could (dis)appear.
|
// We want to recalculate when the scale changes - some planes could (dis)appear.
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "slic3r/GUI/3DScene.hpp"
|
#include "slic3r/GUI/3DScene.hpp"
|
||||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||||
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
enum class ModelVolumeType : int;
|
enum class ModelVolumeType : int;
|
||||||
@ -51,8 +50,10 @@ private:
|
|||||||
Vec3d m_first_instance_mirror;
|
Vec3d m_first_instance_mirror;
|
||||||
|
|
||||||
std::vector<PlaneData> m_planes;
|
std::vector<PlaneData> m_planes;
|
||||||
|
#if ENABLE_RAYCAST_PICKING
|
||||||
|
std::vector<std::shared_ptr<SceneRaycasterItem>> m_planes_casters;
|
||||||
|
#endif // ENABLE_RAYCAST_PICKING
|
||||||
bool m_mouse_left_down = false; // for detection left_up of this gizmo
|
bool m_mouse_left_down = false; // for detection left_up of this gizmo
|
||||||
bool m_planes_valid = false;
|
|
||||||
const ModelObject* m_old_model_object = nullptr;
|
const ModelObject* m_old_model_object = nullptr;
|
||||||
std::vector<const Transform3d*> instances_matrices;
|
std::vector<const Transform3d*> instances_matrices;
|
||||||
|
|
||||||
|
@ -33,13 +33,14 @@ SceneRaycaster::SceneRaycaster() {
|
|||||||
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SceneRaycasterItem> SceneRaycaster::add_raycaster(EType type, int id, const MeshRaycaster& raycaster, const Transform3d& trafo)
|
std::shared_ptr<SceneRaycasterItem> SceneRaycaster::add_raycaster(EType type, int id, const MeshRaycaster& raycaster,
|
||||||
|
const Transform3d& trafo, bool use_back_faces)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case EType::Bed: { return m_bed.emplace_back(std::make_shared<SceneRaycasterItem>(encode_id(type, id), raycaster, trafo)); }
|
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)); }
|
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)); }
|
case EType::Gizmo: { return m_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; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,6 +108,7 @@ SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Came
|
|||||||
auto test_raycasters = [this, is_closest, clipping_plane](EType type, const Vec2d& mouse_pos, const Camera& camera, HitResult& ret) {
|
auto test_raycasters = [this, is_closest, clipping_plane](EType type, const Vec2d& mouse_pos, const Camera& camera, HitResult& ret) {
|
||||||
const ClippingPlane* clip_plane = (clipping_plane != nullptr && type == EType::Volume) ? clipping_plane : nullptr;
|
const ClippingPlane* clip_plane = (clipping_plane != nullptr && type == EType::Volume) ? clipping_plane : nullptr;
|
||||||
std::vector<std::shared_ptr<SceneRaycasterItem>>* raycasters = get_raycasters(type);
|
std::vector<std::shared_ptr<SceneRaycasterItem>>* raycasters = get_raycasters(type);
|
||||||
|
const Vec3f camera_forward = camera.get_dir_forward().cast<float>();
|
||||||
HitResult current_hit = { type };
|
HitResult current_hit = { type };
|
||||||
for (std::shared_ptr<SceneRaycasterItem> item : *raycasters) {
|
for (std::shared_ptr<SceneRaycasterItem> item : *raycasters) {
|
||||||
if (!item->is_active())
|
if (!item->is_active())
|
||||||
@ -116,10 +118,11 @@ SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Came
|
|||||||
const Transform3d& trafo = item->get_transform();
|
const Transform3d& trafo = item->get_transform();
|
||||||
if (item->get_raycaster()->closest_hit(mouse_pos, trafo, camera, current_hit.position, current_hit.normal, clip_plane)) {
|
if (item->get_raycaster()->closest_hit(mouse_pos, trafo, camera, current_hit.position, current_hit.normal, clip_plane)) {
|
||||||
current_hit.position = (trafo * current_hit.position.cast<double>()).cast<float>();
|
current_hit.position = (trafo * current_hit.position.cast<double>()).cast<float>();
|
||||||
if (is_closest(camera, current_hit.position)) {
|
current_hit.normal = (trafo.matrix().block(0, 0, 3, 3).inverse().transpose() * current_hit.normal.cast<double>()).normalized().cast<float>();
|
||||||
const Matrix3d normal_matrix = (Matrix3d)trafo.matrix().block(0, 0, 3, 3).inverse().transpose();
|
if (item->use_back_faces() || current_hit.normal.dot(camera_forward) < 0.0f){
|
||||||
current_hit.normal = (normal_matrix * current_hit.normal.cast<double>()).normalized().cast<float>();
|
if (is_closest(camera, current_hit.position)) {
|
||||||
ret = current_hit;
|
ret = current_hit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,17 +18,19 @@ class SceneRaycasterItem
|
|||||||
{
|
{
|
||||||
int m_id{ -1 };
|
int m_id{ -1 };
|
||||||
bool m_active{ true };
|
bool m_active{ true };
|
||||||
|
bool m_use_back_faces{ false };
|
||||||
const MeshRaycaster* m_raycaster;
|
const MeshRaycaster* m_raycaster;
|
||||||
Transform3d m_trafo;
|
Transform3d m_trafo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SceneRaycasterItem(int id, const MeshRaycaster& raycaster, const Transform3d& trafo)
|
SceneRaycasterItem(int id, const MeshRaycaster& raycaster, const Transform3d& trafo, bool use_back_faces = false)
|
||||||
: m_id(id), m_raycaster(&raycaster), m_trafo(trafo)
|
: m_id(id), m_raycaster(&raycaster), m_trafo(trafo), m_use_back_faces(use_back_faces)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int get_id() const { return m_id; }
|
int get_id() const { return m_id; }
|
||||||
bool is_active() const { return m_active; }
|
bool is_active() const { return m_active; }
|
||||||
void set_active(bool active) { m_active = active; }
|
void set_active(bool active) { m_active = active; }
|
||||||
|
bool use_back_faces() const { return m_use_back_faces; }
|
||||||
const MeshRaycaster* get_raycaster() const { return m_raycaster; }
|
const MeshRaycaster* get_raycaster() const { return m_raycaster; }
|
||||||
const Transform3d& get_transform() const { return m_trafo; }
|
const Transform3d& get_transform() const { return m_trafo; }
|
||||||
void set_transform(const Transform3d& trafo) { m_trafo = trafo; }
|
void set_transform(const Transform3d& trafo) { m_trafo = trafo; }
|
||||||
@ -80,7 +82,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
SceneRaycaster();
|
SceneRaycaster();
|
||||||
|
|
||||||
std::shared_ptr<SceneRaycasterItem> add_raycaster(EType type, int picking_id, const MeshRaycaster& raycaster, const Transform3d& trafo);
|
std::shared_ptr<SceneRaycasterItem> add_raycaster(EType type, int picking_id, const MeshRaycaster& raycaster,
|
||||||
|
const Transform3d& trafo, bool use_back_faces = false);
|
||||||
void remove_raycasters(EType type, int id);
|
void remove_raycasters(EType type, int id);
|
||||||
void remove_raycasters(EType type);
|
void remove_raycasters(EType type);
|
||||||
void remove_raycaster(std::shared_ptr<SceneRaycasterItem> item);
|
void remove_raycaster(std::shared_ptr<SceneRaycasterItem> item);
|
||||||
|
Loading…
Reference in New Issue
Block a user