ENABLE_3DCONNEXION_DEVICES -> Added translation and rotation customizable parameter deadzone

This commit is contained in:
Enrico Turri 2019-10-08 14:32:05 +02:00
parent b7db5a9558
commit 4ec6199ef1
5 changed files with 116 additions and 34 deletions

View file

@ -272,7 +272,7 @@ void AppConfig::set_recent_projects(const std::vector<std::string>& recent_proje
}
#if ENABLE_3DCONNEXION_DEVICES
void AppConfig::set_mouse_device(const std::string& name, double translation_speed, float rotation_speed)
void AppConfig::set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, float rotation_speed, float rotation_deadzone)
{
std::string key = std::string("mouse_device:") + name;
auto it = m_storage.find(key);
@ -281,10 +281,12 @@ void AppConfig::set_mouse_device(const std::string& name, double translation_spe
it->second.clear();
it->second["translation_speed"] = std::to_string(translation_speed);
it->second["translation_deadzone"] = std::to_string(translation_deadzone);
it->second["rotation_speed"] = std::to_string(rotation_speed);
it->second["rotation_deadzone"] = std::to_string(rotation_deadzone);
}
bool AppConfig::get_mouse_device_translation_speed(const std::string& name, double& translation_speed)
bool AppConfig::get_mouse_device_translation_speed(const std::string& name, double& speed)
{
std::string key = std::string("mouse_device:") + name;
auto it = m_storage.find(key);
@ -295,11 +297,26 @@ bool AppConfig::get_mouse_device_translation_speed(const std::string& name, doub
if (it_val == it->second.end())
return false;
translation_speed = ::atof(it_val->second.c_str());
speed = ::atof(it_val->second.c_str());
return true;
}
bool AppConfig::get_mouse_device_rotation_speed(const std::string& name, float& rotation_speed)
bool AppConfig::get_mouse_device_translation_deadzone(const std::string& name, double& deadzone)
{
std::string key = std::string("mouse_device:") + name;
auto it = m_storage.find(key);
if (it == m_storage.end())
return false;
auto it_val = it->second.find("translation_deadzone");
if (it_val == it->second.end())
return false;
deadzone = ::atof(it_val->second.c_str());
return true;
}
bool AppConfig::get_mouse_device_rotation_speed(const std::string& name, float& speed)
{
std::string key = std::string("mouse_device:") + name;
auto it = m_storage.find(key);
@ -310,7 +327,22 @@ bool AppConfig::get_mouse_device_rotation_speed(const std::string& name, float&
if (it_val == it->second.end())
return false;
rotation_speed = (float)::atof(it_val->second.c_str());
speed = (float)::atof(it_val->second.c_str());
return true;
}
bool AppConfig::get_mouse_device_rotation_deadzone(const std::string& name, float& deadzone)
{
std::string key = std::string("mouse_device:") + name;
auto it = m_storage.find(key);
if (it == m_storage.end())
return false;
auto it_val = it->second.find("rotation_deadzone");
if (it_val == it->second.end())
return false;
deadzone = (float)::atof(it_val->second.c_str());
return true;
}
#endif // ENABLE_3DCONNEXION_DEVICES

View file

@ -132,9 +132,11 @@ public:
void set_recent_projects(const std::vector<std::string>& recent_projects);
#if ENABLE_3DCONNEXION_DEVICES
void set_mouse_device(const std::string& name, double translation_speed, float rotation_speed);
bool get_mouse_device_translation_speed(const std::string& name, double& translation_speed);
bool get_mouse_device_rotation_speed(const std::string& name, float& rotation_speed);
void set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, float rotation_speed, float rotation_deadzone);
bool get_mouse_device_translation_speed(const std::string& name, double& speed);
bool get_mouse_device_translation_deadzone(const std::string& name, double& deadzone);
bool get_mouse_device_rotation_speed(const std::string& name, float& speed);
bool get_mouse_device_rotation_deadzone(const std::string& name, float& deadzone);
#endif // ENABLE_3DCONNEXION_DEVICES
static const std::string SECTION_FILAMENTS;

View file

@ -2399,6 +2399,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
{
Mouse3DController& controller = wxGetApp().plater()->get_mouse3d_controller();
controller.show_settings_dialog(!controller.is_settings_dialog_shown());
m_dirty = true;
break;
}
#endif // ENABLE_3DCONNEXION_DEVICES

View file

@ -52,11 +52,15 @@ namespace Slic3r {
namespace GUI {
const double Mouse3DController::State::DefaultTranslationScale = 2.5;
const double Mouse3DController::State::MaxTranslationDeadzone = 0.1;
const double Mouse3DController::State::DefaultTranslationDeadzone = 0.5 * Mouse3DController::State::MaxTranslationDeadzone;
const float Mouse3DController::State::DefaultRotationScale = 1.0f;
const float Mouse3DController::State::MaxRotationDeadzone = 0.1f;
const float Mouse3DController::State::DefaultRotationDeadzone = 0.5f * Mouse3DController::State::MaxRotationDeadzone;
Mouse3DController::State::State()
: m_translation_scale(DefaultTranslationScale)
, m_rotation_scale(DefaultRotationScale)
: m_translation_params(DefaultTranslationScale, DefaultTranslationDeadzone)
, m_rotation_params(DefaultRotationScale, DefaultRotationDeadzone)
, m_mouse_wheel_counter(0)
{
}
@ -87,7 +91,7 @@ bool Mouse3DController::State::apply(Camera& camera)
if (has_translation())
{
const Vec3d& translation = m_translation.front();
camera.set_target(camera.get_target() + m_translation_scale * (translation(0) * camera.get_dir_right() + translation(1) * camera.get_dir_forward() + translation(2) * camera.get_dir_up()));
camera.set_target(camera.get_target() + m_translation_params.scale * (translation(0) * camera.get_dir_right() + translation(1) * camera.get_dir_forward() + translation(2) * camera.get_dir_up()));
m_translation.pop();
ret = true;
}
@ -95,8 +99,8 @@ bool Mouse3DController::State::apply(Camera& camera)
if (has_rotation())
{
const Vec3f& rotation = m_rotation.front();
float theta = m_rotation_scale * rotation(0);
float phi = m_rotation_scale * rotation(2);
float theta = m_rotation_params.scale * rotation(0);
float phi = m_rotation_params.scale * rotation(2);
float sign = camera.inverted_phi ? -1.0f : 1.0f;
camera.phi += sign * phi;
camera.set_theta(camera.get_theta() + theta, wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA);
@ -207,13 +211,26 @@ void Mouse3DController::render_settings_dialog(unsigned int canvas_width, unsign
imgui.text(_(L("Speed:")));
ImGui::PopStyleColor();
float translation = (float)m_state.get_translation_scale() / State::DefaultTranslationScale;
if (ImGui::SliderFloat(_(L("Translation")), &translation, 0.5f, 2.0f, "%.1f"))
m_state.set_translation_scale(State::DefaultTranslationScale * (double)translation);
float translation_scale = (float)m_state.get_translation_scale() / State::DefaultTranslationScale;
if (ImGui::SliderFloat(_(L("Translation##1")), &translation_scale, 0.5f, 2.0f, "%.1f"))
m_state.set_translation_scale(State::DefaultTranslationScale * (double)translation_scale);
float rotation = m_state.get_rotation_scale() / State::DefaultRotationScale;
if (ImGui::SliderFloat(_(L("Rotation")), &rotation, 0.5f, 2.0f, "%.1f"))
m_state.set_rotation_scale(State::DefaultRotationScale * rotation);
float rotation_scale = m_state.get_rotation_scale() / State::DefaultRotationScale;
if (ImGui::SliderFloat(_(L("Rotation##1")), &rotation_scale, 0.5f, 2.0f, "%.1f"))
m_state.set_rotation_scale(State::DefaultRotationScale * rotation_scale);
ImGui::Separator();
ImGui::PushStyleColor(ImGuiCol_Text, color);
imgui.text(_(L("Deadzone:")));
ImGui::PopStyleColor();
float translation_deadzone = (float)m_state.get_translation_deadzone();
if (ImGui::SliderFloat(_(L("Translation##2")), &translation_deadzone, 0.0f, (float)State::MaxTranslationDeadzone, "%.2f"))
m_state.set_translation_deadzone((double)translation_deadzone);
float rotation_deadzone = m_state.get_rotation_deadzone();
if (ImGui::SliderFloat(_(L("Rotation##2")), &rotation_deadzone, 0.0f, State::MaxRotationDeadzone, "%.2f"))
m_state.set_rotation_deadzone(rotation_deadzone);
imgui.end();
@ -308,13 +325,19 @@ bool Mouse3DController::connect_device()
BOOST_LOG_TRIVIAL(info) << "Connected device: " << m_device_str;
// get device parameters from the config, if present
double translation = 1.0;
float rotation = 1.0;
wxGetApp().app_config->get_mouse_device_translation_speed(m_device_str, translation);
wxGetApp().app_config->get_mouse_device_rotation_speed(m_device_str, rotation);
double translation_speed = 1.0;
float rotation_speed = 1.0;
double translation_deadzone = State::DefaultTranslationDeadzone;
float rotation_deadzone = State::DefaultRotationDeadzone;
wxGetApp().app_config->get_mouse_device_translation_speed(m_device_str, translation_speed);
wxGetApp().app_config->get_mouse_device_translation_deadzone(m_device_str, translation_deadzone);
wxGetApp().app_config->get_mouse_device_rotation_speed(m_device_str, rotation_speed);
wxGetApp().app_config->get_mouse_device_rotation_deadzone(m_device_str, rotation_deadzone);
// clamp to valid values
m_state.set_translation_scale(State::DefaultTranslationScale * std::max(0.5, std::min(2.0, translation)));
m_state.set_rotation_scale(State::DefaultRotationScale * std::max(0.5f, std::min(2.0f, rotation)));
m_state.set_translation_scale(State::DefaultTranslationScale* std::max(0.5, std::min(2.0, translation_speed)));
m_state.set_translation_deadzone(std::max(0.0, std::min(State::MaxTranslationDeadzone, translation_deadzone)));
m_state.set_rotation_scale(State::DefaultRotationScale* std::max(0.5f, std::min(2.0f, rotation_speed)));
m_state.set_rotation_deadzone(std::max(0.0f, std::min(State::MaxRotationDeadzone, rotation_deadzone)));
}
return (m_device != nullptr);
@ -330,7 +353,8 @@ void Mouse3DController::disconnect_device()
m_thread.join();
// Store current device parameters into the config
wxGetApp().app_config->set_mouse_device(m_device_str, m_state.get_translation_scale() / State::DefaultTranslationScale, m_state.get_rotation_scale() / State::DefaultRotationScale);
wxGetApp().app_config->set_mouse_device(m_device_str, m_state.get_translation_scale() / State::DefaultTranslationScale, m_state.get_translation_deadzone(),
m_state.get_rotation_scale() / State::DefaultRotationScale, m_state.get_rotation_deadzone());
wxGetApp().app_config->save();
// Close the 3Dconnexion device
@ -474,7 +498,9 @@ bool Mouse3DController::handle_packet_translation(const DataPacket& packet)
Vec3d translation(-convert_input(packet[1], packet[2]),
convert_input(packet[3], packet[4]),
convert_input(packet[5], packet[6]));
if (!translation.isApprox(Vec3d::Zero()))
double deadzone = m_state.get_translation_deadzone();
if ((std::abs(translation(0)) > deadzone) || (std::abs(translation(1)) > deadzone) || (std::abs(translation(2)) > deadzone))
{
m_state.append_translation(translation);
return true;
@ -488,7 +514,9 @@ bool Mouse3DController::handle_packet_rotation(const DataPacket& packet, unsigne
Vec3f rotation(-(float)convert_input(packet[first_byte + 0], packet[first_byte + 1]),
(float)convert_input(packet[first_byte + 2], packet[first_byte + 3]),
-(float)convert_input(packet[first_byte + 4], packet[first_byte + 5]));
if (!rotation.isApprox(Vec3f::Zero()))
float deadzone = m_state.get_rotation_deadzone();
if ((std::abs(rotation(0)) > deadzone) || (std::abs(rotation(1)) > deadzone) || (std::abs(rotation(2)) > deadzone))
{
m_state.append_rotation(rotation);
return true;

View file

@ -22,15 +22,28 @@ class Mouse3DController
{
public:
static const double DefaultTranslationScale;
static const double MaxTranslationDeadzone;
static const double DefaultTranslationDeadzone;
static const float DefaultRotationScale;
static const float MaxRotationDeadzone;
static const float DefaultRotationDeadzone;
private:
template <typename Number>
struct CustomParameters
{
Number scale;
Number deadzone;
CustomParameters(Number scale, Number deadzone) : scale(scale), deadzone(deadzone) {}
};
std::queue<Vec3d> m_translation;
std::queue<Vec3f> m_rotation;
std::queue<unsigned int> m_buttons;
double m_translation_scale;
float m_rotation_scale;
CustomParameters<double> m_translation_params;
CustomParameters<float> m_rotation_params;
// When the 3Dconnexion driver is running the system gets, by default, mouse wheel events when rotations around the X axis are detected.
// We want to filter these out because we are getting the data directly from the device, bypassing the driver, and those mouse wheel events interfere
@ -59,11 +72,17 @@ class Mouse3DController
bool process_mouse_wheel();
double get_translation_scale() const { return m_translation_scale; }
void set_translation_scale(double scale) { m_translation_scale = scale; }
double get_translation_scale() const { return m_translation_params.scale; }
void set_translation_scale(double scale) { m_translation_params.scale = scale; }
float get_rotation_scale() const { return m_rotation_scale; }
void set_rotation_scale(float scale) { m_rotation_scale = scale; }
float get_rotation_scale() const { return m_rotation_params.scale; }
void set_rotation_scale(float scale) { m_rotation_params.scale = scale; }
double get_translation_deadzone() const { return m_translation_params.deadzone; }
void set_translation_deadzone(double deadzone) { m_translation_params.deadzone = deadzone; }
float get_rotation_deadzone() const { return m_rotation_params.deadzone; }
void set_rotation_deadzone(float deadzone) { m_rotation_params.deadzone = deadzone; }
// return true if any change to the camera took place
bool apply(Camera& camera);