ENH: Gizmo panning & scalling
jira: STUDIO-10777 / STUDIO-8274 Change-Id: I89166b441a606d2cd05a0c2d4569cb1de73a657b
This commit is contained in:
parent
a7207bef35
commit
33230fd688
|
@ -192,7 +192,7 @@ bool GLGizmoAdvancedCut::gizmo_event(SLAGizmoEventType action, const Vec2d &mous
|
|||
return false;
|
||||
}
|
||||
|
||||
bool GLGizmoAdvancedCut::on_key(wxKeyEvent &evt)
|
||||
bool GLGizmoAdvancedCut::on_key(const wxKeyEvent& evt)
|
||||
{
|
||||
bool ctrl_down = evt.GetModifiers() & wxMOD_CONTROL;
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ public:
|
|||
GLGizmoAdvancedCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
|
||||
bool gizmo_event(SLAGizmoEventType action, const Vec2d &mouse_position, bool shift_down, bool alt_down, bool control_down);
|
||||
bool on_key(wxKeyEvent &evt);
|
||||
bool on_key(const wxKeyEvent &evt) override;
|
||||
|
||||
double get_movement() const { return m_movement; }
|
||||
void finish_rotation();
|
||||
|
|
|
@ -355,6 +355,11 @@ void GLGizmoBase::set_icon_filename(const std::string &filename) {
|
|||
m_icon_filename = filename;
|
||||
}
|
||||
|
||||
bool GLGizmoBase::on_key(const wxKeyEvent& key_event)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void GLGizmoBase::set_hover_id(int id)
|
||||
{
|
||||
if (m_grabbers.empty() || (id < (int)m_grabbers.size()))
|
||||
|
|
|
@ -214,6 +214,7 @@ public:
|
|||
|
||||
virtual bool apply_clipping_plane() { return true; }
|
||||
virtual bool on_mouse(const wxMouseEvent &mouse_event) { return false; }
|
||||
virtual bool on_key(const wxKeyEvent& key_event);
|
||||
unsigned int get_sprite_id() const { return m_sprite_id; }
|
||||
|
||||
int get_hover_id() const { return m_hover_id; }
|
||||
|
|
|
@ -351,8 +351,10 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const
|
|||
// vector from the starting position to the found intersection
|
||||
Vec3d inters_vec = inters - m_starting_drag_position;
|
||||
|
||||
// finds projection of the vector along the staring direction
|
||||
projection = inters_vec.dot(starting_vec.normalized());
|
||||
projection = inters_vec.norm();
|
||||
const double sign = inters_vec.dot(starting_vec) > 1e-6f ? 1.0f : -1.0f;
|
||||
|
||||
projection = projection * sign;
|
||||
}
|
||||
|
||||
if (wxGetKeyState(WXK_SHIFT))
|
||||
|
|
|
@ -118,6 +118,27 @@ BoundingBoxf3 GLGizmoScale3D::get_bounding_box() const
|
|||
return t_aabb;
|
||||
}
|
||||
|
||||
bool GLGizmoScale3D::on_key(const wxKeyEvent& key_event)
|
||||
{
|
||||
bool b_processed = false;
|
||||
if (key_event.GetEventType() == wxEVT_KEY_DOWN) {
|
||||
if (key_event.GetKeyCode() == WXK_CONTROL) {
|
||||
if (!is_scalling_mode_locked()) {
|
||||
set_asymmetric_scalling_enable(!is_asymmetric_scalling_enabled());
|
||||
lock_scalling_mode(true);
|
||||
b_processed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (key_event.GetEventType() == wxEVT_KEY_UP) {
|
||||
if (key_event.GetKeyCode() == WXK_CONTROL) {
|
||||
lock_scalling_mode(false);
|
||||
b_processed = true;
|
||||
}
|
||||
}
|
||||
return b_processed;
|
||||
}
|
||||
|
||||
bool GLGizmoScale3D::on_init()
|
||||
{
|
||||
for (int i = 0; i < 10; ++i)
|
||||
|
@ -219,7 +240,7 @@ void GLGizmoScale3D::update_grabbers_data()
|
|||
m_instance_center = (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) ? selection.get_first_volume()->get_instance_offset() : m_center;
|
||||
|
||||
const Vec3d box_half_size = 0.5 * m_bounding_box.size();
|
||||
bool ctrl_down = wxGetKeyState(WXK_CONTROL);
|
||||
bool b_asymmetric_scalling = is_asymmetric_scalling_enabled();
|
||||
|
||||
|
||||
bool single_instance = selection.is_single_full_instance();
|
||||
|
@ -227,29 +248,29 @@ void GLGizmoScale3D::update_grabbers_data()
|
|||
|
||||
// x axis
|
||||
m_grabbers[0].center = Vec3d(-(box_half_size.x()), 0.0, -box_half_size.z());
|
||||
m_grabbers[0].color = (ctrl_down && m_hover_id == 1) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
m_grabbers[0].color = (b_asymmetric_scalling && m_hover_id == 1) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
m_grabbers[1].center = Vec3d(box_half_size.x(), 0.0, -box_half_size.z());
|
||||
m_grabbers[1].color = (ctrl_down && m_hover_id == 0) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
m_grabbers[1].color = (b_asymmetric_scalling && m_hover_id == 0) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
// y axis
|
||||
m_grabbers[2].center = Vec3d(0.0, -(box_half_size.y()), -box_half_size.z());
|
||||
m_grabbers[2].color = (ctrl_down && m_hover_id == 3) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
m_grabbers[2].color = (b_asymmetric_scalling && m_hover_id == 3) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
m_grabbers[3].center = Vec3d(0.0, box_half_size.y(), -box_half_size.z());
|
||||
m_grabbers[3].color = (ctrl_down && m_hover_id == 2) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
m_grabbers[3].color = (b_asymmetric_scalling && m_hover_id == 2) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
// z axis do not show 4
|
||||
m_grabbers[4].center = Vec3d(0.0, 0.0, -(box_half_size.z()));
|
||||
m_grabbers[4].enabled = false;
|
||||
|
||||
m_grabbers[5].center = Vec3d(0.0, 0.0, box_half_size.z());
|
||||
m_grabbers[5].color = (ctrl_down && m_hover_id == 4) ? CONSTRAINED_COLOR : AXES_COLOR[2];
|
||||
m_grabbers[5].color = (b_asymmetric_scalling && m_hover_id == 4) ? CONSTRAINED_COLOR : AXES_COLOR[2];
|
||||
// uniform
|
||||
m_grabbers[6].center = Vec3d(-box_half_size.x(), -box_half_size.y(), -box_half_size.z());
|
||||
m_grabbers[6].color = (ctrl_down && m_hover_id == 8) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||
m_grabbers[6].color = (b_asymmetric_scalling && m_hover_id == 8) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||
m_grabbers[7].center = Vec3d(box_half_size.x(), -box_half_size.y(), -box_half_size.z());
|
||||
m_grabbers[7].color = (ctrl_down && m_hover_id == 9) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||
m_grabbers[7].color = (b_asymmetric_scalling && m_hover_id == 9) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||
m_grabbers[8].center = Vec3d(box_half_size.x(), box_half_size.y(), -box_half_size.z());
|
||||
m_grabbers[8].color = (ctrl_down && m_hover_id == 6) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||
m_grabbers[8].color = (b_asymmetric_scalling && m_hover_id == 6) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||
m_grabbers[9].center = Vec3d(-box_half_size.x(), box_half_size.y(), -box_half_size.z());
|
||||
m_grabbers[9].color = (ctrl_down && m_hover_id == 7) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||
m_grabbers[9].color = (b_asymmetric_scalling && m_hover_id == 7) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||
|
||||
Transform3d t_model_matrix{ Transform3d::Identity() };
|
||||
const auto t_fullsize = get_grabber_size();
|
||||
|
@ -279,6 +300,26 @@ void GLGizmoScale3D::change_cs_by_selection() {
|
|||
}
|
||||
}
|
||||
|
||||
void GLGizmoScale3D::set_asymmetric_scalling_enable(bool is_enabled)
|
||||
{
|
||||
m_b_asymmetric_scalling = is_enabled;
|
||||
}
|
||||
|
||||
bool GLGizmoScale3D::is_asymmetric_scalling_enabled() const
|
||||
{
|
||||
return m_b_asymmetric_scalling;
|
||||
}
|
||||
|
||||
void GLGizmoScale3D::lock_scalling_mode(bool is_locked)
|
||||
{
|
||||
m_b_scalling_mode_locked = is_locked;
|
||||
}
|
||||
|
||||
bool GLGizmoScale3D::is_scalling_mode_locked() const
|
||||
{
|
||||
return m_b_scalling_mode_locked;
|
||||
}
|
||||
|
||||
void GLGizmoScale3D::on_render()
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
|
@ -289,6 +330,11 @@ void GLGizmoScale3D::on_render()
|
|||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
if (m_hover_id == -1) {
|
||||
lock_scalling_mode(false);
|
||||
set_asymmetric_scalling_enable(false);
|
||||
}
|
||||
|
||||
update_grabbers_data();
|
||||
|
||||
const auto& p_ogl_manager = wxGetApp().get_opengl_manager();
|
||||
|
@ -393,8 +439,7 @@ void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
|
|||
if (ratio > 0.0)
|
||||
{
|
||||
m_scale(axis) = m_starting.scale(axis) * ratio;
|
||||
const bool ctrl_down = wxGetKeyState(WXK_CONTROL);
|
||||
if (ctrl_down && abs(ratio-1.0f)>0.001) {
|
||||
if (is_asymmetric_scalling_enabled() && abs(ratio - 1.0f)>0.001) {
|
||||
double local_offset = 0.5 * (m_scale(axis) - m_starting.scale(axis)) * m_starting.box.size()(axis);
|
||||
if (m_hover_id == 2 * axis) {
|
||||
local_offset *= -1.0;
|
||||
|
@ -433,8 +478,7 @@ double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
|
|||
{
|
||||
double ratio = 0.0;
|
||||
|
||||
const bool ctrl_down = wxGetKeyState(WXK_CONTROL);
|
||||
Vec3d pivot = (ctrl_down && (m_hover_id < 6)) ? m_starting.constraint_position : m_starting.plane_center; // plane_center = bottom center
|
||||
Vec3d pivot = (is_asymmetric_scalling_enabled() && (m_hover_id < 6)) ? m_starting.constraint_position : m_starting.plane_center; // plane_center = bottom center
|
||||
Vec3d starting_vec = m_starting.drag_position - pivot;
|
||||
double len_starting_vec = starting_vec.norm();
|
||||
if (len_starting_vec != 0.0)
|
||||
|
@ -444,10 +488,10 @@ double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
|
|||
// vector from the starting position to the found intersection
|
||||
Vec3d inters_vec = inters - m_starting.drag_position;
|
||||
|
||||
// finds projection of the vector along the staring direction
|
||||
double proj = inters_vec.dot(starting_vec.normalized());
|
||||
double proj = inters_vec.norm();
|
||||
const double sign = inters_vec.dot(starting_vec) > 1e-6f ? 1.0f : -1.0f;
|
||||
|
||||
ratio = (len_starting_vec + proj) / len_starting_vec;
|
||||
ratio = (len_starting_vec + proj * sign) / len_starting_vec;
|
||||
}
|
||||
|
||||
if (wxGetKeyState(WXK_SHIFT))
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
void data_changed(bool is_serializing) override;
|
||||
void enable_ununiversal_scale(bool enable);
|
||||
BoundingBoxf3 get_bounding_box() const override;
|
||||
|
||||
bool on_key(const wxKeyEvent& key_event) override;
|
||||
protected:
|
||||
virtual bool on_init() override;
|
||||
virtual std::string on_get_name() const override;
|
||||
|
@ -91,8 +93,14 @@ private:
|
|||
double calc_ratio(const UpdateData& data) const;
|
||||
void update_grabbers_data();
|
||||
void change_cs_by_selection(); // cs mean Coordinate System
|
||||
void set_asymmetric_scalling_enable(bool is_enabled);
|
||||
bool is_asymmetric_scalling_enabled() const;
|
||||
void lock_scalling_mode(bool is_locked);
|
||||
bool is_scalling_mode_locked() const;
|
||||
private:
|
||||
int m_last_selected_obejct_idx, m_last_selected_volume_idx;
|
||||
bool m_b_asymmetric_scalling{ false };
|
||||
bool m_b_scalling_mode_locked{ false };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1395,11 +1395,13 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
|
|||
int keyCode = evt.GetKeyCode();
|
||||
bool processed = false;
|
||||
|
||||
// todo: zhimin Each gizmo should handle key event in it own on_key() function
|
||||
if (m_current == Cut) {
|
||||
if (GLGizmoAdvancedCut *gizmo_cut = dynamic_cast<GLGizmoAdvancedCut *>(get_current())) {
|
||||
return gizmo_cut->on_key(evt);
|
||||
}
|
||||
auto p_current_gizmo = get_current();
|
||||
if (p_current_gizmo) {
|
||||
processed = p_current_gizmo->on_key(evt);
|
||||
}
|
||||
if (processed) {
|
||||
m_parent.set_as_dirty();
|
||||
return processed;
|
||||
}
|
||||
|
||||
if (evt.GetEventType() == wxEVT_KEY_UP)
|
||||
|
|
Loading…
Reference in New Issue