mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-14 10:17:55 -06:00
Tech ENABLE_RAYCAST_PICKING - Rendering for rectangle selection made only inside the rectangle, on systems supporting framebuffers
Various other refactorings & fixes (cherry picked from commit prusa3d/PrusaSlicer@39b1222b22)
This commit is contained in:
parent
f0199159e7
commit
d2d77456ac
12 changed files with 289 additions and 105 deletions
|
@ -133,41 +133,41 @@ public:
|
||||||
static const ColorRGBA Z() { return { 0.0f, 0.0f, 0.75f, 1.0f }; }
|
static const ColorRGBA Z() { return { 0.0f, 0.0f, 0.75f, 1.0f }; }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ColorRGB operator * (float value, const ColorRGB& other);
|
ColorRGB operator * (float value, const ColorRGB& other);
|
||||||
extern ColorRGBA operator * (float value, const ColorRGBA& other);
|
ColorRGBA operator * (float value, const ColorRGBA& other);
|
||||||
|
|
||||||
extern ColorRGB lerp(const ColorRGB& a, const ColorRGB& b, float t);
|
ColorRGB lerp(const ColorRGB& a, const ColorRGB& b, float t);
|
||||||
extern ColorRGBA lerp(const ColorRGBA& a, const ColorRGBA& b, float t);
|
ColorRGBA lerp(const ColorRGBA& a, const ColorRGBA& b, float t);
|
||||||
|
|
||||||
extern ColorRGB complementary(const ColorRGB& color);
|
ColorRGB complementary(const ColorRGB& color);
|
||||||
extern ColorRGBA complementary(const ColorRGBA& color);
|
ColorRGBA complementary(const ColorRGBA& color);
|
||||||
|
|
||||||
extern ColorRGB saturate(const ColorRGB& color, float factor);
|
ColorRGB saturate(const ColorRGB& color, float factor);
|
||||||
extern ColorRGBA saturate(const ColorRGBA& color, float factor);
|
ColorRGBA saturate(const ColorRGBA& color, float factor);
|
||||||
|
|
||||||
extern ColorRGB opposite(const ColorRGB& color);
|
ColorRGB opposite(const ColorRGB& color);
|
||||||
extern ColorRGB opposite(const ColorRGB& a, const ColorRGB& b);
|
ColorRGB opposite(const ColorRGB& a, const ColorRGB& b);
|
||||||
|
|
||||||
extern bool can_decode_color(const std::string& color);
|
bool can_decode_color(const std::string& color);
|
||||||
|
|
||||||
extern bool decode_color(const std::string& color_in, ColorRGB& color_out);
|
bool decode_color(const std::string& color_in, ColorRGB& color_out);
|
||||||
extern bool decode_color(const std::string& color_in, ColorRGBA& color_out);
|
bool decode_color(const std::string& color_in, ColorRGBA& color_out);
|
||||||
|
|
||||||
extern bool decode_colors(const std::vector<std::string>& colors_in, std::vector<ColorRGB>& colors_out);
|
bool decode_colors(const std::vector<std::string>& colors_in, std::vector<ColorRGB>& colors_out);
|
||||||
extern bool decode_colors(const std::vector<std::string>& colors_in, std::vector<ColorRGBA>& colors_out);
|
bool decode_colors(const std::vector<std::string>& colors_in, std::vector<ColorRGBA>& colors_out);
|
||||||
|
|
||||||
extern std::string encode_color(const ColorRGB& color);
|
std::string encode_color(const ColorRGB& color);
|
||||||
extern std::string encode_color(const ColorRGBA& color);
|
std::string encode_color(const ColorRGBA& color);
|
||||||
|
|
||||||
extern ColorRGB to_rgb(const ColorRGBA& other_rgba);
|
ColorRGB to_rgb(const ColorRGBA& other_rgba);
|
||||||
extern ColorRGBA to_rgba(const ColorRGB& other_rgb);
|
ColorRGBA to_rgba(const ColorRGB& other_rgb);
|
||||||
extern ColorRGBA to_rgba(const ColorRGB& other_rgb, float alpha);
|
ColorRGBA to_rgba(const ColorRGB& other_rgb, float alpha);
|
||||||
|
|
||||||
extern ColorRGBA picking_decode(unsigned int id);
|
ColorRGBA picking_decode(unsigned int id);
|
||||||
extern unsigned int picking_encode(unsigned char r, unsigned char g, unsigned char b);
|
unsigned int picking_encode(unsigned char r, unsigned char g, unsigned char b);
|
||||||
// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components
|
// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components
|
||||||
// were not interpolated by alpha blending or multi sampling.
|
// were not interpolated by alpha blending or multi sampling.
|
||||||
extern unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue);
|
unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue);
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
|
|
@ -704,7 +704,6 @@ void Bed3D::render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, co
|
||||||
|
|
||||||
void Bed3D::render_default(bool bottom, const Transform3d& view_matrix, const Transform3d& projection_matrix)
|
void Bed3D::render_default(bool bottom, const Transform3d& view_matrix, const Transform3d& projection_matrix)
|
||||||
{
|
{
|
||||||
bool picking = false;
|
|
||||||
m_texture.reset();
|
m_texture.reset();
|
||||||
|
|
||||||
update_bed_triangles();
|
update_bed_triangles();
|
||||||
|
|
|
@ -106,6 +106,78 @@ void Camera::select_view(const std::string& direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Camera::get_near_left() const
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case EType::Perspective:
|
||||||
|
return m_frustrum_zs.first * (m_projection_matrix.matrix()(0, 2) - 1.0) / m_projection_matrix.matrix()(0, 0);
|
||||||
|
default:
|
||||||
|
case EType::Ortho:
|
||||||
|
return -1.0 / m_projection_matrix.matrix()(0, 0) - 0.5 * m_projection_matrix.matrix()(0, 0) * m_projection_matrix.matrix()(0, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double Camera::get_near_right() const
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case EType::Perspective:
|
||||||
|
return m_frustrum_zs.first * (m_projection_matrix.matrix()(0, 2) + 1.0) / m_projection_matrix.matrix()(0, 0);
|
||||||
|
default:
|
||||||
|
case EType::Ortho:
|
||||||
|
return 1.0 / m_projection_matrix.matrix()(0, 0) - 0.5 * m_projection_matrix.matrix()(0, 0) * m_projection_matrix.matrix()(0, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double Camera::get_near_top() const
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case EType::Perspective:
|
||||||
|
return m_frustrum_zs.first * (m_projection_matrix.matrix()(1, 2) + 1.0) / m_projection_matrix.matrix()(1, 1);
|
||||||
|
default:
|
||||||
|
case EType::Ortho:
|
||||||
|
return 1.0 / m_projection_matrix.matrix()(1, 1) - 0.5 * m_projection_matrix.matrix()(1, 1) * m_projection_matrix.matrix()(1, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double Camera::get_near_bottom() const
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case EType::Perspective:
|
||||||
|
return m_frustrum_zs.first * (m_projection_matrix.matrix()(1, 2) - 1.0) / m_projection_matrix.matrix()(1, 1);
|
||||||
|
default:
|
||||||
|
case EType::Ortho:
|
||||||
|
return -1.0 / m_projection_matrix.matrix()(1, 1) - 0.5 * m_projection_matrix.matrix()(1, 1) * m_projection_matrix.matrix()(1, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double Camera::get_near_width() const
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case EType::Perspective:
|
||||||
|
return 2.0 * m_frustrum_zs.first / m_projection_matrix.matrix()(0, 0);
|
||||||
|
default:
|
||||||
|
case EType::Ortho:
|
||||||
|
return 2.0 / m_projection_matrix.matrix()(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double Camera::get_near_height() const
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case EType::Perspective:
|
||||||
|
return 2.0 * m_frustrum_zs.first / m_projection_matrix.matrix()(1, 1);
|
||||||
|
default:
|
||||||
|
case EType::Ortho:
|
||||||
|
return 2.0 / m_projection_matrix.matrix()(1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double Camera::get_fov() const
|
double Camera::get_fov() const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
|
@ -118,12 +190,16 @@ double Camera::get_fov() const
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h)
|
void Camera::set_viewport(int x, int y, unsigned int w, unsigned int h)
|
||||||
{
|
{
|
||||||
glsafe(::glViewport(0, 0, w, h));
|
|
||||||
m_viewport = { 0, 0, int(w), int(h) };
|
m_viewport = { 0, 0, int(w), int(h) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::apply_viewport() const
|
||||||
|
{
|
||||||
|
glsafe(::glViewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]));
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double far_z)
|
void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double far_z)
|
||||||
{
|
{
|
||||||
double w = 0.0;
|
double w = 0.0;
|
||||||
|
@ -163,30 +239,33 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply_projection(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::apply_projection(double left, double right, double bottom, double top, double near_z, double far_z)
|
||||||
|
{
|
||||||
|
assert(left != right && bottom != top && near_z != far_z);
|
||||||
|
const double inv_dx = 1.0 / (right - left);
|
||||||
|
const double inv_dy = 1.0 / (top - bottom);
|
||||||
|
const double inv_dz = 1.0 / (far_z - near_z);
|
||||||
|
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case EType::Ortho:
|
case EType::Ortho:
|
||||||
{
|
{
|
||||||
const double dz = m_frustrum_zs.second - m_frustrum_zs.first;
|
m_projection_matrix.matrix() << 2.0 * inv_dx, 0.0, 0.0, -(left + right) * inv_dx,
|
||||||
const double zz = m_frustrum_zs.first + m_frustrum_zs.second;
|
0.0, 2.0 * inv_dy, 0.0, -(bottom + top) * inv_dy,
|
||||||
m_projection_matrix.matrix() << 1.0 / w, 0.0, 0.0, 0.0,
|
0.0, 0.0, -2.0 * inv_dz, -(near_z + far_z) * inv_dz,
|
||||||
0.0, 1.0 / h, 0.0, 0.0,
|
0.0, 0.0, 0.0, 1.0;
|
||||||
0.0, 0.0, -2.0 / dz, -zz / dz,
|
|
||||||
0.0, 0.0, 0.0, 1.0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EType::Perspective:
|
case EType::Perspective:
|
||||||
{
|
{
|
||||||
const double n = m_frustrum_zs.first;
|
m_projection_matrix.matrix() << 2.0 * near_z * inv_dx, 0.0, (left + right) * inv_dx, 0.0,
|
||||||
const double f = m_frustrum_zs.second;
|
0.0, 2.0 * near_z * inv_dy, (bottom + top) * inv_dy, 0.0,
|
||||||
const double dz = f - n;
|
0.0, 0.0, -(near_z + far_z) * inv_dz, -2.0 * near_z * far_z * inv_dz,
|
||||||
const double zz = n + f;
|
0.0, 0.0, -1.0, 0.0;
|
||||||
const double fn = n * f;
|
|
||||||
m_projection_matrix.matrix() << n / w, 0.0, 0.0, 0.0,
|
|
||||||
0.0, n / h, 0.0, 0.0,
|
|
||||||
0.0, 0.0, -zz / dz, -2.0 * fn / dz,
|
|
||||||
0.0, 0.0, -1.0, 0.0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,13 +107,23 @@ public:
|
||||||
double get_far_z() const { return m_frustrum_zs.second; }
|
double get_far_z() const { return m_frustrum_zs.second; }
|
||||||
const std::pair<double, double>& get_z_range() const { return m_frustrum_zs; }
|
const std::pair<double, double>& get_z_range() const { return m_frustrum_zs; }
|
||||||
|
|
||||||
|
double get_near_left() const;
|
||||||
|
double get_near_right() const;
|
||||||
|
double get_near_top() const;
|
||||||
|
double get_near_bottom() const;
|
||||||
|
double get_near_width() const;
|
||||||
|
double get_near_height() const;
|
||||||
|
|
||||||
double get_fov() const;
|
double get_fov() const;
|
||||||
|
|
||||||
void apply_viewport(int x, int y, unsigned int w, unsigned int h);
|
void set_viewport(int x, int y, unsigned int w, unsigned int h);
|
||||||
|
void apply_viewport() const;
|
||||||
// Calculates and applies the projection matrix tighting the frustrum z range around the given box.
|
// Calculates and applies the projection matrix tighting the frustrum z range around the given box.
|
||||||
// If larger z span is needed, pass the desired values of near and far z (negative values are ignored)
|
// If larger z span is needed, pass the desired values of near and far z (negative values are ignored)
|
||||||
void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0);
|
void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0);
|
||||||
|
|
||||||
|
void apply_projection(double left, double right, double bottom, double top, double near_z, double far_z);
|
||||||
|
|
||||||
void zoom_to_box(const BoundingBoxf3& box, double margin_factor = DefaultZoomToBoxMarginFactor);
|
void zoom_to_box(const BoundingBoxf3& box, double margin_factor = DefaultZoomToBoxMarginFactor);
|
||||||
void zoom_to_volumes(const GLVolumePtrs& volumes, double margin_factor = DefaultZoomToVolumesMarginFactor);
|
void zoom_to_volumes(const GLVolumePtrs& volumes, double margin_factor = DefaultZoomToVolumesMarginFactor);
|
||||||
|
|
||||||
|
|
|
@ -1305,7 +1305,8 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
Camera camera;
|
Camera camera;
|
||||||
camera.apply_viewport(0,0,thumbnail_data.width, thumbnail_data.height);
|
camera.set_viewport(0, 0, thumbnail_data.width, thumbnail_data.height);
|
||||||
|
camera.apply_viewport();
|
||||||
camera.set_scene_box(plate_box);
|
camera.set_scene_box(plate_box);
|
||||||
camera.set_type(Camera::EType::Ortho);
|
camera.set_type(Camera::EType::Ortho);
|
||||||
camera.set_target(center);
|
camera.set_target(center);
|
||||||
|
|
|
@ -1787,7 +1787,8 @@ void GLCanvas3D::render(bool only_init)
|
||||||
// and the viewport was set incorrectly, leading to tripping glAsserts further down
|
// and the viewport was set incorrectly, leading to tripping glAsserts further down
|
||||||
// the road (in apply_projection). That's why the minimum size is forced to 10.
|
// the road (in apply_projection). That's why the minimum size is forced to 10.
|
||||||
Camera& camera = wxGetApp().plater()->get_camera();
|
Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
camera.apply_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height()));
|
camera.set_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height()));
|
||||||
|
camera.apply_viewport();
|
||||||
|
|
||||||
if (camera.requires_zoom_to_bed) {
|
if (camera.requires_zoom_to_bed) {
|
||||||
zoom_to_bed();
|
zoom_to_bed();
|
||||||
|
@ -1896,7 +1897,7 @@ void GLCanvas3D::render(bool only_init)
|
||||||
_render_current_gizmo();
|
_render_current_gizmo();
|
||||||
|
|
||||||
#if ENABLE_RAYCAST_PICKING_DEBUG
|
#if ENABLE_RAYCAST_PICKING_DEBUG
|
||||||
if (m_picking_enabled && !m_mouse.dragging)
|
if (m_picking_enabled && !m_mouse.dragging && !m_gizmos.is_dragging() && !m_rectangle_selection.is_dragging())
|
||||||
m_scene_raycaster.render_hit(camera);
|
m_scene_raycaster.render_hit(camera);
|
||||||
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
||||||
|
|
||||||
|
@ -5540,7 +5541,8 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
||||||
//BBS modify scene box to plate scene bounding box
|
//BBS modify scene box to plate scene bounding box
|
||||||
//plate_build_volume.min(2) = - plate_build_volume.max(2);
|
//plate_build_volume.min(2) = - plate_build_volume.max(2);
|
||||||
camera.set_scene_box(plate_build_volume);
|
camera.set_scene_box(plate_build_volume);
|
||||||
camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height);
|
camera.set_viewport(0, 0, thumbnail_data.width, thumbnail_data.height);
|
||||||
|
camera.apply_viewport();
|
||||||
|
|
||||||
//BoundingBoxf3 plate_box = plate->get_bounding_box(false);
|
//BoundingBoxf3 plate_box = plate->get_bounding_box(false);
|
||||||
//plate_box.min.z() = 0.0;
|
//plate_box.min.z() = 0.0;
|
||||||
|
@ -5911,7 +5913,7 @@ void GLCanvas3D::render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned
|
||||||
#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
|
#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
|
||||||
|
|
||||||
// restore the default framebuffer size to avoid flickering on the 3D scene
|
// restore the default framebuffer size to avoid flickering on the 3D scene
|
||||||
//wxGetApp().plater()->get_camera().apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height());
|
//wxGetApp().plater()->get_camera().apply_viewport();
|
||||||
}
|
}
|
||||||
|
|
||||||
//BBS: GUI refractor
|
//BBS: GUI refractor
|
||||||
|
@ -6412,11 +6414,13 @@ void GLCanvas3D::_refresh_if_shown_on_screen()
|
||||||
|
|
||||||
void GLCanvas3D::_picking_pass()
|
void GLCanvas3D::_picking_pass()
|
||||||
{
|
{
|
||||||
if (!m_picking_enabled || m_mouse.dragging || m_mouse.position == Vec2d(DBL_MAX, DBL_MAX)) {
|
if (!m_picking_enabled || m_mouse.dragging || m_mouse.position == Vec2d(DBL_MAX, DBL_MAX) && !m_gizmos.is_dragging()) {
|
||||||
|
#if ENABLE_RAYCAST_PICKING_DEBUG
|
||||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||||
imgui.begin(std::string("Hit result"), ImGuiWindowFlags_AlwaysAutoResize);
|
imgui.begin(std::string("Hit result"), ImGuiWindowFlags_AlwaysAutoResize);
|
||||||
imgui.text("Picking disabled");
|
imgui.text("Picking disabled");
|
||||||
imgui.end();
|
imgui.end();
|
||||||
|
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6502,6 +6506,7 @@ void GLCanvas3D::_picking_pass()
|
||||||
object_type = "Volume";
|
object_type = "Volume";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default: { break; }
|
||||||
}
|
}
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
if (hit.type != SceneRaycaster::EType::None) {
|
if (hit.type != SceneRaycaster::EType::None) {
|
||||||
|
@ -6536,6 +6541,56 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
|
||||||
std::set<int> idxs;
|
std::set<int> idxs;
|
||||||
|
|
||||||
if (m_picking_enabled) {
|
if (m_picking_enabled) {
|
||||||
|
const size_t width = std::max<size_t>(m_rectangle_selection.get_width(), 1);
|
||||||
|
const size_t height = std::max<size_t>(m_rectangle_selection.get_height(), 1);
|
||||||
|
|
||||||
|
const OpenGLManager::EFramebufferType framebuffers_type = OpenGLManager::get_framebuffers_type();
|
||||||
|
bool use_framebuffer = framebuffers_type != OpenGLManager::EFramebufferType::Unknown;
|
||||||
|
|
||||||
|
GLuint render_fbo = 0;
|
||||||
|
GLuint render_tex = 0;
|
||||||
|
GLuint render_depth = 0;
|
||||||
|
if (use_framebuffer) {
|
||||||
|
// setup a framebuffer which covers only the selection rectangle
|
||||||
|
if (framebuffers_type == OpenGLManager::EFramebufferType::Arb) {
|
||||||
|
glsafe(::glGenFramebuffers(1, &render_fbo));
|
||||||
|
glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, render_fbo));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
glsafe(::glGenFramebuffersEXT(1, &render_fbo));
|
||||||
|
glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, render_fbo));
|
||||||
|
}
|
||||||
|
glsafe(::glGenTextures(1, &render_tex));
|
||||||
|
glsafe(::glBindTexture(GL_TEXTURE_2D, render_tex));
|
||||||
|
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr));
|
||||||
|
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
|
||||||
|
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
|
||||||
|
if (framebuffers_type == OpenGLManager::EFramebufferType::Arb) {
|
||||||
|
glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_tex, 0));
|
||||||
|
glsafe(::glGenRenderbuffers(1, &render_depth));
|
||||||
|
glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, render_depth));
|
||||||
|
glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height));
|
||||||
|
glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, render_tex, 0));
|
||||||
|
glsafe(::glGenRenderbuffersEXT(1, &render_depth));
|
||||||
|
glsafe(::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_depth));
|
||||||
|
glsafe(::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height));
|
||||||
|
glsafe(::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, render_depth));
|
||||||
|
}
|
||||||
|
const GLenum drawBufs[] = { GL_COLOR_ATTACHMENT0 };
|
||||||
|
glsafe(::glDrawBuffers(1, drawBufs));
|
||||||
|
if (framebuffers_type == OpenGLManager::EFramebufferType::Arb) {
|
||||||
|
if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
use_framebuffer = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||||
|
use_framebuffer = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_multisample_allowed)
|
if (m_multisample_allowed)
|
||||||
// This flag is often ignored by NVIDIA drivers if rendering into a screen buffer.
|
// This flag is often ignored by NVIDIA drivers if rendering into a screen buffer.
|
||||||
glsafe(::glDisable(GL_MULTISAMPLE));
|
glsafe(::glDisable(GL_MULTISAMPLE));
|
||||||
|
@ -6545,20 +6600,48 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
|
||||||
|
|
||||||
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||||
|
|
||||||
_render_volumes_for_picking();
|
Camera& main_camera = wxGetApp().plater()->get_camera();
|
||||||
|
Camera framebuffer_camera;
|
||||||
|
Camera* camera = &main_camera;
|
||||||
|
if (use_framebuffer) {
|
||||||
|
// setup a camera which covers only the selection rectangle
|
||||||
|
const std::array<int, 4>& viewport = camera->get_viewport();
|
||||||
|
const double near_left = camera->get_near_left();
|
||||||
|
const double near_bottom = camera->get_near_bottom();
|
||||||
|
const double near_width = camera->get_near_width();
|
||||||
|
const double near_height = camera->get_near_height();
|
||||||
|
|
||||||
|
const double ratio_x = near_width / double(viewport[2]);
|
||||||
|
const double ratio_y = near_height / double(viewport[3]);
|
||||||
|
|
||||||
|
const double rect_near_left = near_left + double(m_rectangle_selection.get_left()) * ratio_x;
|
||||||
|
const double rect_near_bottom = near_bottom + (double(viewport[3]) - double(m_rectangle_selection.get_bottom())) * ratio_y;
|
||||||
|
double rect_near_right = near_left + double(m_rectangle_selection.get_right()) * ratio_x;
|
||||||
|
double rect_near_top = near_bottom + (double(viewport[3]) - double(m_rectangle_selection.get_top())) * ratio_y;
|
||||||
|
|
||||||
|
if (rect_near_left == rect_near_right)
|
||||||
|
rect_near_right = rect_near_left + ratio_x;
|
||||||
|
if (rect_near_bottom == rect_near_top)
|
||||||
|
rect_near_top = rect_near_bottom + ratio_y;
|
||||||
|
|
||||||
|
framebuffer_camera.look_at(camera->get_position(), camera->get_target(), camera->get_dir_up());
|
||||||
|
framebuffer_camera.apply_projection(rect_near_left, rect_near_right, rect_near_bottom, rect_near_top, camera->get_near_z(), camera->get_far_z());
|
||||||
|
framebuffer_camera.set_viewport(0, 0, width, height);
|
||||||
|
framebuffer_camera.apply_viewport();
|
||||||
|
camera = &framebuffer_camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
_render_volumes_for_picking(*camera);
|
||||||
//BBS: remove the bed picking logic
|
//BBS: remove the bed picking logic
|
||||||
//_render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward());
|
//_render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward());
|
||||||
|
|
||||||
if (m_multisample_allowed)
|
if (m_multisample_allowed)
|
||||||
glsafe(::glEnable(GL_MULTISAMPLE));
|
glsafe(::glEnable(GL_MULTISAMPLE));
|
||||||
|
|
||||||
int width = std::max((int)m_rectangle_selection.get_width(), 1);
|
const size_t px_count = width * height;
|
||||||
int height = std::max((int)m_rectangle_selection.get_height(), 1);
|
|
||||||
int px_count = width * height;
|
|
||||||
|
|
||||||
int left = (int)m_rectangle_selection.get_left();
|
const size_t left = use_framebuffer ? 0 : (size_t)m_rectangle_selection.get_left();
|
||||||
int top = get_canvas_size().get_height() - (int)m_rectangle_selection.get_top();
|
const size_t top = use_framebuffer ? 0 : (size_t)get_canvas_size().get_height() - (size_t)m_rectangle_selection.get_top();
|
||||||
if (left >= 0 && top >= 0) {
|
|
||||||
#define USE_PARALLEL 1
|
#define USE_PARALLEL 1
|
||||||
#if USE_PARALLEL
|
#if USE_PARALLEL
|
||||||
struct Pixel
|
struct Pixel
|
||||||
|
@ -6602,7 +6685,26 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
|
||||||
idxs.insert(volume_id);
|
idxs.insert(volume_id);
|
||||||
}
|
}
|
||||||
#endif // USE_PARALLEL
|
#endif // USE_PARALLEL
|
||||||
}
|
if (camera != &main_camera)
|
||||||
|
main_camera.apply_viewport();
|
||||||
|
|
||||||
|
if (framebuffers_type == OpenGLManager::EFramebufferType::Arb) {
|
||||||
|
glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||||
|
if (render_depth != 0)
|
||||||
|
glsafe(::glDeleteRenderbuffers(1, &render_depth));
|
||||||
|
if (render_fbo != 0)
|
||||||
|
glsafe(::glDeleteFramebuffers(1, &render_fbo));
|
||||||
|
}
|
||||||
|
else if (framebuffers_type == OpenGLManager::EFramebufferType::Ext) {
|
||||||
|
glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||||
|
if (render_depth != 0)
|
||||||
|
glsafe(::glDeleteRenderbuffersEXT(1, &render_depth));
|
||||||
|
if (render_fbo != 0)
|
||||||
|
glsafe(::glDeleteFramebuffersEXT(1, &render_fbo));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (render_tex != 0)
|
||||||
|
glsafe(::glDeleteTextures(1, &render_tex));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_hover_volume_idxs.assign(idxs.begin(), idxs.end());
|
m_hover_volume_idxs.assign(idxs.begin(), idxs.end());
|
||||||
|
@ -7194,7 +7296,7 @@ void GLCanvas3D::_render_style_editor()
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::_render_volumes_for_picking() const
|
void GLCanvas3D::_render_volumes_for_picking(const Camera& camera) const
|
||||||
{
|
{
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_clip");
|
GLShaderProgram* shader = wxGetApp().get_shader("flat_clip");
|
||||||
if (shader == nullptr)
|
if (shader == nullptr)
|
||||||
|
@ -7203,7 +7305,7 @@ void GLCanvas3D::_render_volumes_for_picking() const
|
||||||
// do not cull backfaces to show broken geometry, if any
|
// do not cull backfaces to show broken geometry, if any
|
||||||
glsafe(::glDisable(GL_CULL_FACE));
|
glsafe(::glDisable(GL_CULL_FACE));
|
||||||
|
|
||||||
const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix();
|
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||||
for (size_t type = 0; type < 2; ++ type) {
|
for (size_t type = 0; type < 2; ++ type) {
|
||||||
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::ERenderType::Opaque : GLVolumeCollection::ERenderType::Transparent, view_matrix);
|
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::ERenderType::Opaque : GLVolumeCollection::ERenderType::Transparent, view_matrix);
|
||||||
for (const GLVolumeWithIdAndZ& volume : to_render)
|
for (const GLVolumeWithIdAndZ& volume : to_render)
|
||||||
|
@ -7216,8 +7318,7 @@ void GLCanvas3D::_render_volumes_for_picking() const
|
||||||
//const unsigned int id = 1 + volume.second.first;
|
//const unsigned int id = 1 + volume.second.first;
|
||||||
volume.first->model.set_color(picking_decode(id));
|
volume.first->model.set_color(picking_decode(id));
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
shader->set_uniform("view_model_matrix", view_matrix * volume.first->world_matrix());
|
||||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * volume.first->world_matrix());
|
|
||||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||||
shader->set_uniform("volume_world_matrix", volume.first->world_matrix());
|
shader->set_uniform("volume_world_matrix", volume.first->world_matrix());
|
||||||
shader->set_uniform("z_range", m_volumes.get_z_range());
|
shader->set_uniform("z_range", m_volumes.get_z_range());
|
||||||
|
|
|
@ -725,16 +725,20 @@ public:
|
||||||
bool init();
|
bool init();
|
||||||
void post_event(wxEvent &&event);
|
void post_event(wxEvent &&event);
|
||||||
|
|
||||||
std::shared_ptr<SceneRaycasterItem> add_raycaster_for_picking(SceneRaycaster::EType type, PickingId id, const MeshRaycaster& raycaster, const Transform3d& trafo) {
|
std::shared_ptr<SceneRaycasterItem> add_raycaster_for_picking(SceneRaycaster::EType type, int id, const MeshRaycaster& raycaster, const Transform3d& trafo) {
|
||||||
return m_scene_raycaster.add_raycaster(type, id, raycaster, trafo);
|
return m_scene_raycaster.add_raycaster(type, id, raycaster, trafo);
|
||||||
}
|
}
|
||||||
void remove_raycasters_for_picking(SceneRaycaster::EType type, PickingId 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);
|
||||||
}
|
}
|
||||||
void remove_raycasters_for_picking(SceneRaycaster::EType type) {
|
void remove_raycasters_for_picking(SceneRaycaster::EType type) {
|
||||||
m_scene_raycaster.remove_raycasters(type);
|
m_scene_raycaster.remove_raycasters(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<SceneRaycasterItem>>* get_raycasters_for_picking(SceneRaycaster::EType type) {
|
||||||
|
return m_scene_raycaster.get_raycasters(type);
|
||||||
|
}
|
||||||
|
|
||||||
void set_raycaster_gizmos_on_top(bool value) {
|
void set_raycaster_gizmos_on_top(bool value) {
|
||||||
m_scene_raycaster.set_gizmos_on_top(value);
|
m_scene_raycaster.set_gizmos_on_top(value);
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1148,7 @@ private:
|
||||||
void _check_and_update_toolbar_icon_scale();
|
void _check_and_update_toolbar_icon_scale();
|
||||||
void _render_overlays();
|
void _render_overlays();
|
||||||
void _render_style_editor();
|
void _render_style_editor();
|
||||||
void _render_volumes_for_picking() const;
|
void _render_volumes_for_picking(const Camera& camera) const;
|
||||||
void _render_current_gizmo() const;
|
void _render_current_gizmo() const;
|
||||||
void _render_gizmos_overlay();
|
void _render_gizmos_overlay();
|
||||||
void _render_main_toolbar();
|
void _render_main_toolbar();
|
||||||
|
|
|
@ -104,7 +104,7 @@ PickingModel &GLGizmoBase::Grabber::get_cube()
|
||||||
return s_cube;
|
return s_cube;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoBase::Grabber::register_raycasters_for_picking(PickingId id)
|
void GLGizmoBase::Grabber::register_raycasters_for_picking(int id)
|
||||||
{
|
{
|
||||||
picking_id = id;
|
picking_id = id;
|
||||||
// registration will happen on next call to render()
|
// registration will happen on next call to render()
|
||||||
|
|
|
@ -87,7 +87,7 @@ protected:
|
||||||
ColorRGBA hover_color{GRABBER_HOVER_COL};
|
ColorRGBA hover_color{GRABBER_HOVER_COL};
|
||||||
EGrabberExtension extensions{ EGrabberExtension::None };
|
EGrabberExtension extensions{ EGrabberExtension::None };
|
||||||
// the picking id shared by all the elements
|
// the picking id shared by all the elements
|
||||||
PickingId picking_id{ -1 };
|
int picking_id{ -1 };
|
||||||
std::array<std::shared_ptr<SceneRaycasterItem>, GRABBER_ELEMENTS_MAX_COUNT> raycasters = { nullptr };
|
std::array<std::shared_ptr<SceneRaycasterItem>, GRABBER_ELEMENTS_MAX_COUNT> raycasters = { nullptr };
|
||||||
|
|
||||||
Grabber() = default;
|
Grabber() = default;
|
||||||
|
@ -99,7 +99,7 @@ protected:
|
||||||
float get_dragging_half_size(float size) const;
|
float get_dragging_half_size(float size) const;
|
||||||
PickingModel &get_cube();
|
PickingModel &get_cube();
|
||||||
|
|
||||||
void register_raycasters_for_picking(PickingId id);
|
void register_raycasters_for_picking(int id);
|
||||||
void unregister_raycasters_for_picking();
|
void unregister_raycasters_for_picking();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -26,7 +26,7 @@ private:
|
||||||
PickingModel vbo;
|
PickingModel vbo;
|
||||||
Vec3d normal;
|
Vec3d normal;
|
||||||
float area;
|
float area;
|
||||||
PickingId picking_id{ -1 };
|
int picking_id{ -1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
// This holds information to decide whether recalculation is necessary:
|
// This holds information to decide whether recalculation is necessary:
|
||||||
|
|
|
@ -31,7 +31,7 @@ SceneRaycaster::SceneRaycaster() {
|
||||||
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SceneRaycasterItem> SceneRaycaster::add_raycaster(EType type, PickingId id, const MeshRaycaster& raycaster, const Transform3d& trafo)
|
std::shared_ptr<SceneRaycasterItem> SceneRaycaster::add_raycaster(EType type, int id, const MeshRaycaster& raycaster, const Transform3d& trafo)
|
||||||
{
|
{
|
||||||
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)); }
|
||||||
|
@ -41,7 +41,7 @@ std::shared_ptr<SceneRaycasterItem> SceneRaycaster::add_raycaster(EType type, Pi
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRaycaster::remove_raycasters(EType type, PickingId id)
|
void SceneRaycaster::remove_raycasters(EType type, int id)
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<SceneRaycasterItem>>* raycasters = get_raycasters(type);
|
std::vector<std::shared_ptr<SceneRaycasterItem>>* raycasters = get_raycasters(type);
|
||||||
auto it = raycasters->begin();
|
auto it = raycasters->begin();
|
||||||
|
@ -102,7 +102,7 @@ SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Came
|
||||||
|
|
||||||
HitResult ret;
|
HitResult ret;
|
||||||
|
|
||||||
auto test_raycasters = [&](EType type) {
|
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);
|
||||||
HitResult current_hit = { type };
|
HitResult current_hit = { type };
|
||||||
|
@ -115,7 +115,6 @@ SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Came
|
||||||
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)) {
|
if (is_closest(camera, current_hit.position)) {
|
||||||
const Transform3d matrix = camera.get_view_matrix() * trafo;
|
|
||||||
const Matrix3d normal_matrix = (Matrix3d)trafo.matrix().block(0, 0, 3, 3).inverse().transpose();
|
const Matrix3d normal_matrix = (Matrix3d)trafo.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||||
current_hit.normal = (normal_matrix * current_hit.normal.cast<double>()).normalized().cast<float>();
|
current_hit.normal = (normal_matrix * current_hit.normal.cast<double>()).normalized().cast<float>();
|
||||||
ret = current_hit;
|
ret = current_hit;
|
||||||
|
@ -125,13 +124,13 @@ SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Came
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!m_gizmos.empty())
|
if (!m_gizmos.empty())
|
||||||
test_raycasters(EType::Gizmo);
|
test_raycasters(EType::Gizmo, 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);
|
test_raycasters(EType::Bed, mouse_pos, camera, ret);
|
||||||
if (!m_volumes.empty())
|
if (!m_volumes.empty())
|
||||||
test_raycasters(EType::Volume);
|
test_raycasters(EType::Volume, mouse_pos, camera, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret.is_valid())
|
if (ret.is_valid())
|
||||||
|
@ -146,7 +145,7 @@ SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Came
|
||||||
#if ENABLE_RAYCAST_PICKING_DEBUG
|
#if ENABLE_RAYCAST_PICKING_DEBUG
|
||||||
void SceneRaycaster::render_hit(const Camera& camera)
|
void SceneRaycaster::render_hit(const Camera& camera)
|
||||||
{
|
{
|
||||||
if (!m_last_hit.has_value() || !m_last_hit.value().is_valid())
|
if (!m_last_hit.has_value() || !(*m_last_hit).is_valid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||||
|
@ -154,14 +153,14 @@ void SceneRaycaster::render_hit(const Camera& camera)
|
||||||
|
|
||||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||||
|
|
||||||
const Transform3d sphere_view_model_matrix = camera.get_view_matrix() * Geometry::translation_transform(m_last_hit.value().position.cast<double>()) *
|
const Transform3d sphere_view_model_matrix = camera.get_view_matrix() * Geometry::translation_transform((*m_last_hit).position.cast<double>()) *
|
||||||
Geometry::scale_transform(4.0 * camera.get_inv_zoom());
|
Geometry::scale_transform(4.0 * camera.get_inv_zoom());
|
||||||
shader->set_uniform("view_model_matrix", sphere_view_model_matrix);
|
shader->set_uniform("view_model_matrix", sphere_view_model_matrix);
|
||||||
m_sphere.render();
|
m_sphere.render();
|
||||||
|
|
||||||
Eigen::Quaterniond q;
|
Eigen::Quaterniond q;
|
||||||
Transform3d m = Transform3d::Identity();
|
Transform3d m = Transform3d::Identity();
|
||||||
m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3d::UnitZ(), m_last_hit.value().normal.cast<double>()).toRotationMatrix();
|
m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3d::UnitZ(), (*m_last_hit).normal.cast<double>()).toRotationMatrix();
|
||||||
|
|
||||||
const Transform3d line_view_model_matrix = sphere_view_model_matrix * m * Geometry::scale_transform(10.0);
|
const Transform3d line_view_model_matrix = sphere_view_model_matrix * m * Geometry::scale_transform(10.0);
|
||||||
shader->set_uniform("view_model_matrix", line_view_model_matrix);
|
shader->set_uniform("view_model_matrix", line_view_model_matrix);
|
||||||
|
@ -185,28 +184,22 @@ std::vector<std::shared_ptr<SceneRaycasterItem>>* SceneRaycaster::get_raycasters
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
PickingId SceneRaycaster::base_id(EType type)
|
int SceneRaycaster::base_id(EType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case EType::Bed: { return PickingId(EPickingIdBase::Bed); }
|
case EType::Bed: { return int(EIdBase::Bed); }
|
||||||
case EType::Volume: { return PickingId(EPickingIdBase::Volume); }
|
case EType::Volume: { return int(EIdBase::Volume); }
|
||||||
case EType::Gizmo: { return PickingId(EPickingIdBase::Gizmo); }
|
case EType::Gizmo: { return int(EIdBase::Gizmo); }
|
||||||
|
default: { break; }
|
||||||
};
|
};
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PickingId SceneRaycaster::encode_id(EType type, PickingId id)
|
int SceneRaycaster::encode_id(EType type, int id) { return base_id(type) + id; }
|
||||||
{
|
int SceneRaycaster::decode_id(EType type, int id) { return id - base_id(type); }
|
||||||
return base_id(type) + id;
|
|
||||||
}
|
|
||||||
|
|
||||||
PickingId SceneRaycaster::decode_id(EType type, PickingId id)
|
|
||||||
{
|
|
||||||
return id - base_id(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "MeshUtils.hpp"
|
#include "MeshUtils.hpp"
|
||||||
#include "GLModel.hpp"
|
#include "GLModel.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -13,21 +12,19 @@ namespace GUI {
|
||||||
|
|
||||||
struct Camera;
|
struct Camera;
|
||||||
|
|
||||||
using PickingId = int;
|
|
||||||
|
|
||||||
class SceneRaycasterItem
|
class SceneRaycasterItem
|
||||||
{
|
{
|
||||||
PickingId m_id{ -1 };
|
int m_id{ -1 };
|
||||||
bool m_active{ true };
|
bool m_active{ true };
|
||||||
const MeshRaycaster* m_raycaster;
|
const MeshRaycaster* m_raycaster;
|
||||||
Transform3d m_trafo;
|
Transform3d m_trafo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SceneRaycasterItem(PickingId id, const MeshRaycaster& raycaster, const Transform3d& trafo)
|
SceneRaycasterItem(int id, const MeshRaycaster& raycaster, const Transform3d& trafo)
|
||||||
: m_id(id), m_raycaster(&raycaster), m_trafo(trafo)
|
: m_id(id), m_raycaster(&raycaster), m_trafo(trafo)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PickingId 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; }
|
||||||
const MeshRaycaster* get_raycaster() const { return m_raycaster; }
|
const MeshRaycaster* get_raycaster() const { return m_raycaster; }
|
||||||
|
@ -46,7 +43,7 @@ public:
|
||||||
Gizmo
|
Gizmo
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EPickingIdBase
|
enum class EIdBase
|
||||||
{
|
{
|
||||||
Bed = 0,
|
Bed = 0,
|
||||||
Volume = 1000,
|
Volume = 1000,
|
||||||
|
@ -56,7 +53,7 @@ public:
|
||||||
struct HitResult
|
struct HitResult
|
||||||
{
|
{
|
||||||
EType type{ EType::None };
|
EType type{ EType::None };
|
||||||
PickingId raycaster_id{ -1 };
|
int raycaster_id{ -1 };
|
||||||
Vec3f position{ Vec3f::Zero() };
|
Vec3f position{ Vec3f::Zero() };
|
||||||
Vec3f normal{ Vec3f::Zero() };
|
Vec3f normal{ Vec3f::Zero() };
|
||||||
|
|
||||||
|
@ -81,11 +78,13 @@ private:
|
||||||
public:
|
public:
|
||||||
SceneRaycaster();
|
SceneRaycaster();
|
||||||
|
|
||||||
std::shared_ptr<SceneRaycasterItem> add_raycaster(EType type, PickingId 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);
|
||||||
void remove_raycasters(EType type, PickingId 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);
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<SceneRaycasterItem>>* get_raycasters(EType type);
|
||||||
|
|
||||||
void set_gizmos_on_top(bool value) { m_gizmos_on_top = value; }
|
void set_gizmos_on_top(bool value) { m_gizmos_on_top = value; }
|
||||||
|
|
||||||
HitResult hit(const Vec2d& mouse_pos, const Camera& camera, const ClippingPlane* clipping_plane = nullptr);
|
HitResult hit(const Vec2d& mouse_pos, const Camera& camera, const ClippingPlane* clipping_plane = nullptr);
|
||||||
|
@ -99,11 +98,9 @@ public:
|
||||||
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::shared_ptr<SceneRaycasterItem>>* get_raycasters(EType type);
|
static int encode_id(EType type, int id);
|
||||||
|
static int decode_id(EType type, int id);
|
||||||
static PickingId encode_id(EType type, PickingId id);
|
static int base_id(EType type);
|
||||||
static PickingId decode_id(EType type, PickingId id);
|
|
||||||
static PickingId base_id(EType type);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue