Add dead-zone controls to UI, v2.6.4
This commit is contained in:
parent
e96ccc4f0b
commit
3fc4dcefd9
|
|
@ -594,18 +594,17 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
|||
this.set_uniform_float(this.get_uniform_location('u_look_ahead_ms'), 1, [0.0]);
|
||||
lookAheadSet = true;
|
||||
}
|
||||
let posePositionPixels = [0.0, 0.0, 0.0];
|
||||
if (this.pose_has_position) {
|
||||
posePositionPixels = this.imu_snapshots.pose_position.map((coord, index) => {
|
||||
return coord * this.fov_details.fullScreenDistancePixels + this.lens_vector[index];
|
||||
});
|
||||
}
|
||||
this.set_uniform_matrix(this.get_uniform_location("u_pose_orientation"), false, 4, this.imu_snapshots.pose_orientation);
|
||||
this.set_uniform_float(this.get_uniform_location("u_pose_position"), 3, posePositionPixels);
|
||||
} else {
|
||||
this.set_uniform_matrix(this.get_uniform_location("u_pose_orientation"), false, 4, this.imu_snapshots.smooth_follow_origin);
|
||||
this.set_uniform_float(this.get_uniform_location("u_pose_position"), 3, [0.0, 0.0, 0.0]);
|
||||
}
|
||||
let posePositionPixels = [0.0, 0.0, 0.0];
|
||||
if (this.pose_has_position) {
|
||||
posePositionPixels = this.imu_snapshots.pose_position.map((coord, index) => {
|
||||
return coord * this.fov_details.fullScreenDistancePixels + this.lens_vector[index];
|
||||
});
|
||||
}
|
||||
this.set_uniform_float(this.get_uniform_location("u_pose_position"), 3, posePositionPixels);
|
||||
if (!lookAheadSet) {
|
||||
this.set_uniform_float(this.get_uniform_location('u_look_ahead_ms'), 1, [lookAheadMS(this.imu_snapshots.timestamp_ms, Globals.data_stream.device_data.lookAheadCfg, this.look_ahead_override)]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -372,6 +372,12 @@ BreezyDesktopEffectConfig::BreezyDesktopEffectConfig(QObject *parent, const KPlu
|
|||
connect(ui.SmoothFollowTrackRoll, &QCheckBox::toggled, this, &BreezyDesktopEffectConfig::updateSmoothFollowTrackRoll);
|
||||
connect(ui.NeckSaverHorizontalMultiplier, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::updateNeckSaverHorizontal);
|
||||
connect(ui.NeckSaverVerticalMultiplier, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::updateNeckSaverVertical);
|
||||
connect(ui.DeadZoneThresholdDeg, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::updateDeadZoneThresholdDeg);
|
||||
|
||||
if (ui.DeadZoneThresholdDeg) {
|
||||
ui.DeadZoneThresholdDeg->setValueUnitsSuffix(QStringLiteral("°"));
|
||||
ui.DeadZoneThresholdDeg->setValueText(0, i18n("Disabled"));
|
||||
}
|
||||
|
||||
if (auto label = widget()->findChild<QLabel*>("labelAppNameVersion")) {
|
||||
label->setText(QStringLiteral("Breezy Desktop - v%1").arg(QLatin1String(BREEZY_DESKTOP_VERSION_STR)));
|
||||
|
|
@ -763,6 +769,12 @@ void BreezyDesktopEffectConfig::pollDriverState()
|
|||
ui.NeckSaverVerticalMultiplier->setValue(vertInt);
|
||||
}
|
||||
|
||||
const double dz = deadZoneThresholdDeg(configJsonOpt);
|
||||
const int dzInt = static_cast<int>(std::round(dz * 10.0));
|
||||
if (ui.DeadZoneThresholdDeg->value() != dzInt) {
|
||||
ui.DeadZoneThresholdDeg->setValue(dzInt);
|
||||
}
|
||||
|
||||
refreshLicenseUi(stateJson);
|
||||
|
||||
m_driverStateInitialized = true;
|
||||
|
|
@ -836,6 +848,16 @@ double BreezyDesktopEffectConfig::neckSaverVerticalMultiplier(std::optional<QJso
|
|||
return v;
|
||||
}
|
||||
|
||||
double BreezyDesktopEffectConfig::deadZoneThresholdDeg(std::optional<QJsonObject> configJsonOpt)
|
||||
{
|
||||
if (!configJsonOpt) return 0.0;
|
||||
const QJsonValue jv = configJsonOpt->value(QStringLiteral("dead_zone_threshold_deg"));
|
||||
const double v = jv.isDouble() ? jv.toDouble() : 0.0;
|
||||
if (v < 0.0) return 0.0;
|
||||
if (v > 5.0) return 5.0;
|
||||
return v;
|
||||
}
|
||||
|
||||
void BreezyDesktopEffectConfig::updateNeckSaverHorizontal()
|
||||
{
|
||||
auto configJsonOpt = XRDriverIPC::instance().retrieveConfig();
|
||||
|
|
@ -858,6 +880,20 @@ void BreezyDesktopEffectConfig::updateNeckSaverVertical()
|
|||
XRDriverIPC::instance().writeConfig(newConfig);
|
||||
}
|
||||
|
||||
void BreezyDesktopEffectConfig::updateDeadZoneThresholdDeg()
|
||||
{
|
||||
auto configJsonOpt = XRDriverIPC::instance().retrieveConfig();
|
||||
double val = ui.DeadZoneThresholdDeg->value() / 10.0;
|
||||
val = std::clamp(val, 0.0, 5.0);
|
||||
|
||||
const double current = deadZoneThresholdDeg(configJsonOpt);
|
||||
if (std::abs(current - val) < 1e-9) return;
|
||||
|
||||
QJsonObject newConfig = configJsonOpt ? configJsonOpt.value() : QJsonObject();
|
||||
newConfig.insert(QStringLiteral("dead_zone_threshold_deg"), val);
|
||||
XRDriverIPC::instance().writeConfig(newConfig);
|
||||
}
|
||||
|
||||
bool BreezyDesktopEffectConfig::multitapEnabled(std::optional<QJsonObject> configJsonOpt)
|
||||
{
|
||||
if (!configJsonOpt) return false;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ private:
|
|||
void updateSmoothFollowTrackRoll();
|
||||
void updateNeckSaverHorizontal();
|
||||
void updateNeckSaverVertical();
|
||||
void updateDeadZoneThresholdDeg();
|
||||
void updateUiFromConfig();
|
||||
void updateUiFromDefaultConfig();
|
||||
void updateConfigFromUi();
|
||||
|
|
@ -51,6 +52,7 @@ private:
|
|||
bool smoothFollowTrackRollEnabled(std::optional<QJsonObject> configJsonOpt);
|
||||
double neckSaverHorizontalMultiplier(std::optional<QJsonObject> configJsonOpt);
|
||||
double neckSaverVerticalMultiplier(std::optional<QJsonObject> configJsonOpt);
|
||||
double deadZoneThresholdDeg(std::optional<QJsonObject> configJsonOpt);
|
||||
void pollDriverState();
|
||||
void refreshLicenseUi(const QJsonObject &rootObj);
|
||||
void checkEffectLoaded();
|
||||
|
|
|
|||
|
|
@ -654,13 +654,48 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QLabel" name="labelDeadZoneThresholdDeg">
|
||||
<property name="text">
|
||||
<string>Dead-zone threshold (deg):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="LabeledSlider" name="DeadZoneThresholdDeg">
|
||||
<property name="decimalShift">
|
||||
<double>1</double>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="tickStartOffset">
|
||||
<double>0</double>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<double>10</double>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<widget class="QLabel" name="labelMeasurementUnits">
|
||||
<property name="text">
|
||||
<string>Measurement units:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<item row="14" column="1">
|
||||
<widget class="QComboBox" name="comboMeasurementUnits"/>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b74587dfc17e85c63ee03fdbdd8f2541400f454f
|
||||
Subproject commit 4267946ef0d0d24a7563455c70b8cee6bcd1f2da
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 44657a5de6532ac0ec1a4ce6d3ccd73e2c87fdc6
|
||||
Subproject commit 6f1844829e11fcc7664398d4c95d8fbdb6341669
|
||||
|
|
@ -10,6 +10,13 @@ class ConfigManager(GObject.GObject):
|
|||
'follow-track-roll': (bool, 'Follow Track Roll', 'Whether to follow on the roll axis', False, GObject.ParamFlags.READWRITE),
|
||||
'follow-track-pitch': (bool, 'Follow Track Pitch', 'Whether to follow on the pitch axis', True, GObject.ParamFlags.READWRITE),
|
||||
'follow-track-yaw': (bool, 'Follow Track Yaw', 'Whether to follow on the yaw axis', True, GObject.ParamFlags.READWRITE),
|
||||
'dead-zone-threshold-deg': (
|
||||
float,
|
||||
'Dead Zone Threshold (deg)',
|
||||
'IMU dead-zone threshold in degrees (0.0 disables)',
|
||||
0.0, 5.0, 0.0,
|
||||
GObject.ParamFlags.READWRITE,
|
||||
),
|
||||
'neck-saver-horizontal-multiplier': (
|
||||
float,
|
||||
'Neck Saver Horizontal Multiplier',
|
||||
|
|
@ -49,6 +56,7 @@ class ConfigManager(GObject.GObject):
|
|||
self.follow_track_roll = None
|
||||
self.follow_track_pitch = None
|
||||
self.follow_track_yaw = None
|
||||
self.dead_zone_threshold_deg = None
|
||||
self.neck_saver_horizontal_multiplier = None
|
||||
self.neck_saver_vertical_multiplier = None
|
||||
self._running = True
|
||||
|
|
@ -74,6 +82,9 @@ class ConfigManager(GObject.GObject):
|
|||
if self.config['smooth_follow_track_yaw'] != self.follow_track_yaw:
|
||||
self.set_property('follow-track-yaw', self.config['smooth_follow_track_yaw'])
|
||||
|
||||
if self.config['dead_zone_threshold_deg'] != self.dead_zone_threshold_deg:
|
||||
self.set_property('dead-zone-threshold-deg', self.config['dead_zone_threshold_deg'])
|
||||
|
||||
if self.config['neck_saver_horizontal_multiplier'] != self.neck_saver_horizontal_multiplier:
|
||||
self.set_property('neck-saver-horizontal-multiplier', self.config['neck_saver_horizontal_multiplier'])
|
||||
|
||||
|
|
@ -120,6 +131,13 @@ class ConfigManager(GObject.GObject):
|
|||
self.ipc.write_config(self.config)
|
||||
self.follow_track_yaw = value
|
||||
|
||||
def _set_dead_zone_threshold_deg(self, value):
|
||||
value = round(min(5.0, max(0.0, float(value))), 2)
|
||||
if self.dead_zone_threshold_deg != value:
|
||||
self.config['dead_zone_threshold_deg'] = value
|
||||
self.ipc.write_config(self.config)
|
||||
self.dead_zone_threshold_deg = value
|
||||
|
||||
def _set_neck_saver_horizontal_multiplier(self, value):
|
||||
value = round(min(2.5, max(1.0, float(value))), 2)
|
||||
if self.neck_saver_horizontal_multiplier != value:
|
||||
|
|
@ -145,6 +163,8 @@ class ConfigManager(GObject.GObject):
|
|||
self._set_follow_track_pitch(value)
|
||||
elif prop.name == 'follow-track-yaw':
|
||||
self._set_follow_track_yaw(value)
|
||||
elif prop.name == 'dead-zone-threshold-deg':
|
||||
self._set_dead_zone_threshold_deg(value)
|
||||
elif prop.name == 'neck-saver-horizontal-multiplier':
|
||||
self._set_neck_saver_horizontal_multiplier(value)
|
||||
elif prop.name == 'neck-saver-vertical-multiplier':
|
||||
|
|
@ -161,6 +181,8 @@ class ConfigManager(GObject.GObject):
|
|||
return self.follow_track_pitch
|
||||
elif prop.name == 'follow-track-yaw':
|
||||
return self.follow_track_yaw
|
||||
elif prop.name == 'dead-zone-threshold-deg':
|
||||
return self.dead_zone_threshold_deg
|
||||
elif prop.name == 'neck-saver-horizontal-multiplier':
|
||||
return self.neck_saver_horizontal_multiplier
|
||||
elif prop.name == 'neck-saver-vertical-multiplier':
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ class ConnectedDevice(Gtk.Box):
|
|||
neck_saver_horizontal_adjustment = Gtk.Template.Child()
|
||||
neck_saver_vertical_scale = Gtk.Template.Child()
|
||||
neck_saver_vertical_adjustment = Gtk.Template.Child()
|
||||
dead_zone_threshold_scale = Gtk.Template.Child()
|
||||
dead_zone_threshold_adjustment = Gtk.Template.Child()
|
||||
enable_multi_tap_switch = Gtk.Template.Child()
|
||||
legacy_follow_mode_switch = Gtk.Template.Child()
|
||||
follow_track_yaw_switch = Gtk.Template.Child()
|
||||
|
|
@ -193,6 +195,7 @@ class ConnectedDevice(Gtk.Box):
|
|||
self._bind_switch_to_config(self.follow_track_roll_switch, 'follow-track-roll')
|
||||
self._bind_switch_to_config(self.follow_track_pitch_switch, 'follow-track-pitch')
|
||||
self._bind_switch_to_config(self.follow_track_yaw_switch, 'follow-track-yaw')
|
||||
self._bind_scale_to_config(self.dead_zone_threshold_adjustment, 'dead-zone-threshold-deg')
|
||||
self._bind_scale_to_config(self.neck_saver_horizontal_adjustment, 'neck-saver-horizontal-multiplier')
|
||||
self._bind_scale_to_config(self.neck_saver_vertical_adjustment, 'neck-saver-vertical-multiplier')
|
||||
|
||||
|
|
|
|||
|
|
@ -762,6 +762,38 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Dead-zone threshold (degrees)</property>
|
||||
<property name="subtitle" translatable="yes">Stabilize movements below this angle.</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="dead_zone_threshold_scale">
|
||||
<property name="valign">3</property>
|
||||
<property name="draw-value">true</property>
|
||||
<property name="value-pos">0</property>
|
||||
<property name="digits">1</property>
|
||||
<property name="width-request">350</property>
|
||||
<property name="has-origin">false</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment" id="dead_zone_threshold_adjustment">
|
||||
<property name="lower">0.0</property>
|
||||
<property name="upper">5.0</property>
|
||||
<property name="step-increment">0.1</property>
|
||||
<property name="value">0.0</property>
|
||||
</object>
|
||||
</property>
|
||||
<marks>
|
||||
<mark value="0.0" position="bottom" translatable="yes">Disabled</mark>
|
||||
<mark value="1.0" position="bottom">1.0</mark>
|
||||
<mark value="2.0" position="bottom">2.0</mark>
|
||||
<mark value="3.0" position="bottom">3.0</mark>
|
||||
<mark value="4.0" position="bottom">4.0</mark>
|
||||
<mark value="5.0" position="bottom">5.0</mark>
|
||||
</marks>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Follow mode movement tracking</property>
|
||||
|
|
|
|||
Loading…
Reference in New Issue