diff --git a/Cargo.lock b/Cargo.lock index 847a98bf..89da8af5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3176,7 +3176,7 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libmonado" version = "1.6.0" -source = "git+https://github.com/oo8dev/libmonado-rs.git?rev=fc39940a64dea2df080a0d2c974c7d651006241f#fc39940a64dea2df080a0d2c974c7d651006241f" +source = "git+https://github.com/wayvr-org/libmonado-rs.git?rev=6f66b26930c24a8a2fc57ddcd85704784894c750#6f66b26930c24a8a2fc57ddcd85704784894c750" dependencies = [ "dlopen2", "flagset", diff --git a/wayvr/Cargo.toml b/wayvr/Cargo.toml index eb7e052a..c7ff289e 100644 --- a/wayvr/Cargo.toml +++ b/wayvr/Cargo.toml @@ -57,7 +57,7 @@ interprocess = { version = "2.2.3" } json = { version = "0.12.4", optional = true } json5 = "1.3.0" libc = "0.2.178" -libmonado = { git = "https://github.com/oo8dev/libmonado-rs.git", rev = "fc39940a64dea2df080a0d2c974c7d651006241f", optional = true } +libmonado = { git = "https://github.com/wayvr-org/libmonado-rs.git", rev = "6f66b26930c24a8a2fc57ddcd85704784894c750", optional = true } log-panics = { version = "2.1.0", features = ["with-backtrace"] } mint = "0.5.9" openxr = { version = "0.21.0", features = ["linked", "mint"], optional = true } diff --git a/wayvr/src/backend/openxr/helpers.rs b/wayvr/src/backend/openxr/helpers.rs index 936ab5a3..56ed80ca 100644 --- a/wayvr/src/backend/openxr/helpers.rs +++ b/wayvr/src/backend/openxr/helpers.rs @@ -15,6 +15,8 @@ macro_rules! next_chain_insert { } pub(crate) use next_chain_insert; +use crate::state::AppState; + pub(super) fn init_xr() -> Result<(xr::Instance, xr::SystemId), anyhow::Error> { let entry = xr::Entry::linked(); @@ -209,3 +211,21 @@ pub(super) fn posef_to_transform(pose: &xr::Posef) -> Affine3A { let translation = Vec3M::from(pose.position).into(); Affine3A::from_rotation_translation(rotation, translation) } + +pub(super) fn reconfigure_chroma_key(app: &AppState) { + let Some(monado) = app.monado_state.as_ref() else { + return; + }; + + let params = &app.session.config.chroma_key_params; + + if let Err(e) = monado.ipc.set_chroma_key_params( + params.hsv_min[0]..params.hsv_max[0], + params.hsv_min[1]..params.hsv_max[1], + params.hsv_min[2]..params.hsv_max[2], + params.curve, + params.despill, + ) { + log::warn!("Could not set Chroma Key: {e:?}") + } +} diff --git a/wayvr/src/backend/openxr/mod.rs b/wayvr/src/backend/openxr/mod.rs index 8e7938f7..57a6506b 100644 --- a/wayvr/src/backend/openxr/mod.rs +++ b/wayvr/src/backend/openxr/mod.rs @@ -17,7 +17,7 @@ use crate::{ backend::{ BackendError, XrBackend, input::interact, - openxr::{lines::LinePool, overlay::OpenXrOverlayData}, + openxr::{helpers::reconfigure_chroma_key, lines::LinePool, overlay::OpenXrOverlayData}, task::{OpenXrTask, OverlayTask, TaskType}, }, config::{save_settings, save_state}, @@ -94,6 +94,8 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr .ok() }); + reconfigure_chroma_key(&app); + let mut blocker = app .monado_state .as_ref() @@ -489,6 +491,7 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr &mut environment_blend_mode, main_session_visible, ); + reconfigure_chroma_key(&app); } } #[cfg(feature = "openvr")] diff --git a/wgui/src/drawing.rs b/wgui/src/drawing.rs index 71a66e43..2f1aca81 100644 --- a/wgui/src/drawing.rs +++ b/wgui/src/drawing.rs @@ -192,6 +192,42 @@ impl Default for Color { } } +pub struct HsvColor { + pub h: f32, + pub s: f32, + pub v: f32, + pub a: f32, +} + +impl HsvColor { + pub const fn new(h: f32, s: f32, v: f32, a: f32) -> Self { + Self { h, s, v, a } + } +} + +impl From for HsvColor { + fn from(value: Color) -> Self { + let max = value.r.max(value.g).max(value.b); + let min = value.r.min(value.g).min(value.b); + let delta = max - min; + + let h = if delta == 0.0 { + 0.0 + } else if max == value.r { + (((value.g - value.b) / delta) / 6.0 + 1.0) % 1.0 + } else if max == value.g { + ((value.b - value.r) / delta + 2.0) / 6.0 + } else { + ((value.r - value.g) / delta + 4.0) / 6.0 + }; + + let s = if max == 0.0 { 0.0 } else { delta / max }; + let v = max; + + Self::new(h, s, v, value.a) + } +} + #[repr(u8)] #[derive(Debug, Default, Clone, Copy)] pub enum GradientMode { diff --git a/wlx-common/src/config.rs b/wlx-common/src/config.rs index 7fc43dcb..8d5a0e20 100644 --- a/wlx-common/src/config.rs +++ b/wlx-common/src/config.rs @@ -66,6 +66,14 @@ pub enum HandsfreePointer { EyeTrackingOnly, } +#[derive(Clone, Serialize, Deserialize, Default)] +pub struct ChromaKeyParams { + pub hsv_min: [f32; 3], + pub hsv_max: [f32; 3], + pub curve: f32, + pub despill: f32, +} + #[derive(Clone, Serialize, Deserialize)] pub struct SerializedWindowSet { pub name: Arc, @@ -331,4 +339,7 @@ pub struct GeneralConfig { #[serde(default = "def_false")] pub keyboard_swipe_to_type_enabled: bool, + + #[serde(default)] + pub chroma_key_params: ChromaKeyParams, }