refactor(server): ♻️ Light refactoring for hand gestures code

This commit is contained in:
Riccardo Zaglia 2023-09-12 11:37:33 +08:00
parent ae66ce92c9
commit 096ec85296
3 changed files with 189 additions and 191 deletions

View File

@ -262,8 +262,8 @@ pub fn handshake_loop() {
data_manager
.client_list()
.get(&client_hostname)
.unwrap()
.trusted
.map(|c| c.trusted)
.unwrap_or(false)
};
// do not attempt connection if the client is already connected
@ -272,9 +272,8 @@ pub fn handshake_loop() {
.read()
.client_list()
.get(&client_hostname)
.unwrap()
.connection_state
== ConnectionState::Disconnected
.map(|c| c.connection_state == ConnectionState::Disconnected)
.unwrap_or(false)
{
if let Err(e) =
try_connect([(client_ip, client_hostname.clone())].into_iter().collect())
@ -297,8 +296,9 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
let (disconnect_sender, disconnect_receiver) = mpsc::channel();
*DISCONNECT_CLIENT_NOTIFIER.lock() = Some(disconnect_sender);
// Safety: this never panics because client_ip is picked from client_ips keys
let client_hostname = client_ips.remove(&client_ip).unwrap();
let Some(client_hostname) = client_ips.remove(&client_ip) else {
con_bail!("unreachable");
};
struct DropGuard {
hostname: String,
@ -650,19 +650,12 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
let tracking_manager = Arc::clone(&tracking_manager);
let hand_gesture_manager = Arc::clone(&hand_gesture_manager);
let mut gestures_button_mapping_manager = SERVER_DATA_MANAGER
.read()
.settings()
.headset
.controllers
.as_option()
.and_then(|config| {
config.hand_tracking.use_gestures.as_option().and_then(|_| {
Some(ButtonMappingManager::new_automatic(
&HAND_GESTURE_BUTTON_SET,
&config.button_mapping_config,
))
})
let mut gestures_button_mapping_manager =
settings.headset.controllers.as_option().map(|config| {
ButtonMappingManager::new_automatic(
&HAND_GESTURE_BUTTON_SET,
&config.button_mapping_config,
)
});
move || {
@ -675,11 +668,6 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
FaceTrackingSink::new(config.sink, settings.connection.osc_local_port).ok()
});
let mut track_controllers = 0u32;
if let Switch::Enabled(config) = &settings.headset.controllers {
track_controllers = config.tracked.into();
}
while IS_STREAMING.value() {
let data = match tracking_receiver.recv(STREAMING_RECV_TIMEOUT) {
Ok(tracking) => tracking,
@ -690,6 +678,21 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
return;
};
let controllers_config = {
let data_lock = SERVER_DATA_MANAGER.read();
data_lock
.settings()
.headset
.controllers
.clone()
.into_option()
};
let track_controllers = controllers_config
.as_ref()
.map(|c| c.tracked)
.unwrap_or(false);
let mut tracking_manager_lock = tracking_manager.lock();
let motions;
@ -766,51 +769,50 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
drop(tracking_manager_lock);
// Handle hand gestures
if let (Some(gestures_config), Some(gestures_button_mapping_manager)) = (
controllers_config
.as_ref()
.and_then(|c| c.hand_tracking.gestures.as_option()),
&mut gestures_button_mapping_manager,
) {
let mut hand_gesture_manager_lock = hand_gesture_manager.lock();
if let Some(hand_skeleton) = tracking.hand_skeletons[0] {
trigger_hand_gesture_actions(
gestures_button_mapping_manager,
*LEFT_HAND_ID,
&hand_gesture_manager_lock.get_active_gestures(
hand_skeleton,
gestures_config,
*LEFT_HAND_ID,
),
);
}
if let Some(hand_skeleton) = tracking.hand_skeletons[1] {
trigger_hand_gesture_actions(
gestures_button_mapping_manager,
*RIGHT_HAND_ID,
&hand_gesture_manager_lock.get_active_gestures(
hand_skeleton,
gestures_config,
*RIGHT_HAND_ID,
),
);
}
}
if controllers_config
.map(|c| c.hand_tracking.enable_skeleton)
.unwrap_or(false)
{
ffi_left_hand_skeleton = None;
ffi_right_hand_skeleton = None;
}
if let Some(stats) = &mut *STATISTICS_MANAGER.lock() {
stats.report_tracking_received(tracking.target_timestamp);
// Handle hand gestures
if let Switch::Enabled(controllers_config) = &settings.headset.controllers {
if let Switch::Enabled(gestures_config) =
&controllers_config.hand_tracking.use_gestures
{
let mut hand_gesture_manager_lock = hand_gesture_manager.lock();
if let Some(hand_skeleton) = tracking.hand_skeletons[0] {
trigger_hand_gesture_actions(
gestures_button_mapping_manager.as_mut().unwrap(),
*LEFT_HAND_ID,
&hand_gesture_manager_lock.get_active_gestures(
hand_skeleton,
gestures_config.clone(),
*LEFT_HAND_ID,
),
);
}
if let Some(hand_skeleton) = tracking.hand_skeletons[1] {
trigger_hand_gesture_actions(
gestures_button_mapping_manager.as_mut().unwrap(),
*RIGHT_HAND_ID,
&hand_gesture_manager_lock.get_active_gestures(
hand_skeleton,
gestures_config.clone(),
*RIGHT_HAND_ID,
),
);
}
}
}
let data_manager_lock = SERVER_DATA_MANAGER.read();
let config = &data_manager_lock.settings().headset;
if let Switch::Enabled(controllers) = &config.controllers {
if !controllers.hand_tracking.enable_skeleton {
ffi_left_hand_skeleton = None;
ffi_right_hand_skeleton = None;
}
}
unsafe {
crate::SetTracking(
tracking.target_timestamp.as_nanos() as _,
@ -827,7 +829,7 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
} else {
ptr::null()
},
track_controllers,
track_controllers.into(),
)
};
}

View File

@ -107,7 +107,7 @@ impl HandGestureManager {
pub fn get_active_gestures(
&mut self,
hand_skeleton: [Pose; 26],
config: HandGestureConfig,
config: &HandGestureConfig,
device_id: u64,
) -> Vec<HandGesture> {
// global joints
@ -145,99 +145,102 @@ impl HandGestureManager {
let little_proximal: Pose = gj[22];
let little_tip: Pose = gj[25];
let mut gestures: Vec<HandGesture> = Vec::new();
// Thumb & index pinch
gestures.push(HandGesture {
id: HandGestureId::ThumbIndexPinch,
active: self.is_gesture_active(
HandGestureId::ThumbIndexPinch,
thumb_tip,
thumb_rad,
index_tip,
index_rad,
pinch_max,
config.repeat_delay,
config.activation_delay,
config.deactivation_delay,
device_id,
),
clicked: self.test_gesture_dist(thumb_tip, thumb_rad, index_tip, index_rad, pinch_min),
touching: self.test_gesture_dist(thumb_tip, thumb_rad, index_tip, index_rad, pinch_max),
value: self.get_gesture_hover(
thumb_tip, thumb_rad, index_tip, index_rad, pinch_min, pinch_max,
),
});
// Thumb & middle pinch
gestures.push(HandGesture {
id: HandGestureId::ThumbMiddlePinch,
active: self.is_gesture_active(
HandGestureId::ThumbMiddlePinch,
thumb_tip,
thumb_rad,
middle_tip,
middle_rad,
pinch_max,
config.repeat_delay,
config.activation_delay,
config.deactivation_delay,
device_id,
),
clicked: self
.test_gesture_dist(thumb_tip, thumb_rad, middle_tip, middle_rad, pinch_min),
touching: self
.test_gesture_dist(thumb_tip, thumb_rad, middle_tip, middle_rad, pinch_max),
value: self.get_gesture_hover(
thumb_tip, thumb_rad, middle_tip, middle_rad, pinch_min, pinch_max,
),
});
// Thumb & ring pinch
gestures.push(HandGesture {
id: HandGestureId::ThumbRingPinch,
active: self.is_gesture_active(
HandGestureId::ThumbRingPinch,
thumb_tip,
thumb_rad,
ring_tip,
ring_rad,
pinch_max,
config.repeat_delay,
config.activation_delay,
config.deactivation_delay,
device_id,
),
clicked: self.test_gesture_dist(thumb_tip, thumb_rad, ring_tip, ring_rad, pinch_min),
touching: self.test_gesture_dist(thumb_tip, thumb_rad, ring_tip, ring_rad, pinch_max),
value: self.get_gesture_hover(
thumb_tip, thumb_rad, ring_tip, ring_rad, pinch_min, pinch_max,
),
});
// Thumb & little pinch
gestures.push(HandGesture {
id: HandGestureId::ThumbLittlePinch,
active: self.is_gesture_active(
HandGestureId::ThumbLittlePinch,
thumb_tip,
thumb_rad,
little_tip,
little_rad,
pinch_max,
config.repeat_delay,
config.activation_delay,
config.deactivation_delay,
device_id,
),
clicked: self
.test_gesture_dist(thumb_tip, thumb_rad, little_tip, little_rad, pinch_min),
touching: self
.test_gesture_dist(thumb_tip, thumb_rad, little_tip, little_rad, pinch_max),
value: self.get_gesture_hover(
thumb_tip, thumb_rad, little_tip, little_rad, pinch_min, pinch_max,
),
});
let mut gestures = [
// Thumb & index pinch
HandGesture {
id: HandGestureId::ThumbIndexPinch,
active: self.is_gesture_active(
HandGestureId::ThumbIndexPinch,
thumb_tip,
thumb_rad,
index_tip,
index_rad,
pinch_max,
config.repeat_delay,
config.activation_delay,
config.deactivation_delay,
device_id,
),
clicked: self
.test_gesture_dist(thumb_tip, thumb_rad, index_tip, index_rad, pinch_min),
touching: self
.test_gesture_dist(thumb_tip, thumb_rad, index_tip, index_rad, pinch_max),
value: self.get_gesture_hover(
thumb_tip, thumb_rad, index_tip, index_rad, pinch_min, pinch_max,
),
},
// Thumb & middle pinch
HandGesture {
id: HandGestureId::ThumbMiddlePinch,
active: self.is_gesture_active(
HandGestureId::ThumbMiddlePinch,
thumb_tip,
thumb_rad,
middle_tip,
middle_rad,
pinch_max,
config.repeat_delay,
config.activation_delay,
config.deactivation_delay,
device_id,
),
clicked: self
.test_gesture_dist(thumb_tip, thumb_rad, middle_tip, middle_rad, pinch_min),
touching: self
.test_gesture_dist(thumb_tip, thumb_rad, middle_tip, middle_rad, pinch_max),
value: self.get_gesture_hover(
thumb_tip, thumb_rad, middle_tip, middle_rad, pinch_min, pinch_max,
),
},
// Thumb & ring pinch
HandGesture {
id: HandGestureId::ThumbRingPinch,
active: self.is_gesture_active(
HandGestureId::ThumbRingPinch,
thumb_tip,
thumb_rad,
ring_tip,
ring_rad,
pinch_max,
config.repeat_delay,
config.activation_delay,
config.deactivation_delay,
device_id,
),
clicked: self
.test_gesture_dist(thumb_tip, thumb_rad, ring_tip, ring_rad, pinch_min),
touching: self
.test_gesture_dist(thumb_tip, thumb_rad, ring_tip, ring_rad, pinch_max),
value: self.get_gesture_hover(
thumb_tip, thumb_rad, ring_tip, ring_rad, pinch_min, pinch_max,
),
},
// Thumb & little pinch
HandGesture {
id: HandGestureId::ThumbLittlePinch,
active: self.is_gesture_active(
HandGestureId::ThumbLittlePinch,
thumb_tip,
thumb_rad,
little_tip,
little_rad,
pinch_max,
config.repeat_delay,
config.activation_delay,
config.deactivation_delay,
device_id,
),
clicked: self
.test_gesture_dist(thumb_tip, thumb_rad, little_tip, little_rad, pinch_min),
touching: self
.test_gesture_dist(thumb_tip, thumb_rad, little_tip, little_rad, pinch_max),
value: self.get_gesture_hover(
thumb_tip, thumb_rad, little_tip, little_rad, pinch_min, pinch_max,
),
},
]
.into_iter()
.collect::<Vec<_>>();
// Finger curls
let thumb_curl =
@ -359,6 +362,7 @@ impl HandGestureManager {
gestures
}
#[allow(clippy::too_many_arguments)]
fn is_gesture_active(
&mut self,
gesture_id: HandGestureId,
@ -381,20 +385,15 @@ impl HandGestureManager {
&mut self.gesture_data_right
};
if !gesture_data.contains_key(&gesture_id) {
gesture_data.insert(
gesture_id,
GestureAction {
last_activated: 0,
last_deactivated: 0,
entering: false,
entering_since: 0,
exiting: false,
exiting_since: 0,
active: false,
},
);
}
gesture_data.entry(gesture_id).or_insert(GestureAction {
last_activated: 0,
last_deactivated: 0,
entering: false,
entering_since: 0,
exiting: false,
exiting_since: 0,
active: false,
});
let g: &mut GestureAction = gesture_data.get_mut(&gesture_id).unwrap();
// Disable entering/exiting state if we leave/enter range
@ -477,6 +476,7 @@ impl HandGestureManager {
.clamp(0.0, 1.0)
}
#[allow(clippy::too_many_arguments)]
fn get_joystick_values(
&self,
center: Pose,
@ -566,32 +566,29 @@ fn get_hover_bind_for_gesture(device_id: u64, gesture_id: HandGestureId) -> Opti
pub fn trigger_hand_gesture_actions(
button_mapping_manager: &mut ButtonMappingManager,
device_id: u64,
gestures: &Vec<HandGesture>,
gestures: &[HandGesture],
) {
for gesture in gestures.iter() {
// Click bind
let click_bind = get_click_bind_for_gesture(device_id, gesture.id);
if click_bind.is_some() {
if let Some(click_bind) = get_click_bind_for_gesture(device_id, gesture.id) {
button_mapping_manager.report_button(
click_bind.unwrap(),
click_bind,
ButtonValue::Binary(gesture.active && gesture.clicked),
);
}
// Touch bind
let touch_bind = get_touch_bind_for_gesture(device_id, gesture.id);
if touch_bind.is_some() {
if let Some(touch_bind) = get_touch_bind_for_gesture(device_id, gesture.id) {
button_mapping_manager.report_button(
touch_bind.unwrap(),
touch_bind,
ButtonValue::Binary(gesture.active && gesture.touching),
);
}
// Hover bind
let hover_bind = get_hover_bind_for_gesture(device_id, gesture.id);
if hover_bind.is_some() {
if let Some(hover_bind) = get_hover_bind_for_gesture(device_id, gesture.id) {
button_mapping_manager.report_button(
hover_bind.unwrap(),
hover_bind,
ButtonValue::Scalar(if gesture.active { gesture.value } else { 0.0 }),
);
}

View File

@ -646,9 +646,8 @@ pub struct HapticsConfig {
#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
#[schema(collapsible)]
pub struct ControllersConfig {
#[schema(strings(
help = "Turning this off will make the controllers appear powered off. Reconnect HMD to apply."
))]
#[schema(strings(help = "Turning this off will make the controllers appear powered off."))]
#[schema(flag = "real-time")]
pub tracked: bool,
#[schema(flag = "steamvr-restart")]
@ -709,7 +708,7 @@ pub struct HandTrackingConfig {
#[schema(strings(
help = "Enabling this allows using hand gestures to emulate controller inputs."
))]
pub use_gestures: Switch<HandGestureConfig>,
pub gestures: Switch<HandGestureConfig>,
#[schema(flag = "real-time")]
#[schema(strings(
@ -1323,7 +1322,7 @@ pub fn session_settings_default() -> SettingsDefault {
},
hand_tracking: HandTrackingConfigDefault {
gui_collapsed: true,
use_gestures: SwitchDefault {
gestures: SwitchDefault {
enabled: true,
content: HandGestureConfigDefault {
pinch_touch_distance: 0.0,