diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b09ea3bf..a11a1ec3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,52 +1,52 @@ -# Contributing - -Thanks for being interested in contributing to this project! This document describes -what you need to know to get started with the code. - - -## Installing the dependencies - -First, install the `Rust` programming language by following the instructions at -[rustup.rs](https://rustup.rs). - -Next, install `libclang`, which is used by the -[`ovr_overlay`](https://crates.io/crates/ovr_overlay) bindings for OpenVR. For windows, -use [this] link. For Linux, simply `sudo apt-get install -y libclang-dev`. - -[this]: https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.5/LLVM-14.0.5-win64.exe - -You will also need SteamVR installed. - -### Steam Deck - -If you are building on the steam deck, be sure that you have all the necessary libraries -for native development installed. To get them, follow [these] instructions. - -[these]: https://www.reddit.com/r/SteamDeck/comments/t92ozw/for_compiling_c_code/ - - -## Building - -`cargo` is the build tool for rust. You can `cargo run` to run the code, `cargo check` -to check if your code compiles, and `cargo test` to run tests. You can also do -`--release` to generate an optimized release mode version. This will take longer to -compile but will run significantly faster. - - -## Documentation - -Documentation is autogenerated by cargo and can be viewed in a web browser with -`cargo doc --all --open --no-deps --document-private-items`. You can run -`cargo doc --help` to learn more about what those flags do. The documentation is also -automatically published to github pages for every commit on the `main` branch [here]. - -[here]: https://slimevr.github.io/SlimeVR-Overlay/skeletal_model - - -## Code Style - -All code is autoformatted by `cargo fmt`. We suggest turning on autoformatting on save -in your IDE, otherwise you can just run `cargo fmt` on the command line. Also, all files -should end in a newline and have extra whitespace trimmed. - -Its also a good idea to run `cargo clippy` to fix the style lints it generates. +# Contributing + +Thanks for being interested in contributing to this project! This document describes +what you need to know to get started with the code. + + +## Installing the dependencies + +First, install the `Rust` programming language by following the instructions at +[rustup.rs](https://rustup.rs). + +Next, install `libclang`, which is used by the +[`ovr_overlay`](https://crates.io/crates/ovr_overlay) bindings for OpenVR. For windows, +use [this] link. For Linux, simply `sudo apt-get install -y libclang-dev`. + +[this]: https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.5/LLVM-14.0.5-win64.exe + +You will also need SteamVR installed. + +### Steam Deck + +If you are building on the steam deck, be sure that you have all the necessary libraries +for native development installed. To get them, follow [these] instructions. + +[these]: https://www.reddit.com/r/SteamDeck/comments/t92ozw/for_compiling_c_code/ + + +## Building + +`cargo` is the build tool for rust. You can `cargo run` to run the code, `cargo check` +to check if your code compiles, and `cargo test` to run tests. You can also do +`--release` to generate an optimized release mode version. This will take longer to +compile but will run significantly faster. + + +## Documentation + +Documentation is autogenerated by cargo and can be viewed in a web browser with +`cargo doc --all --open --no-deps --document-private-items`. You can run +`cargo doc --help` to learn more about what those flags do. The documentation is also +automatically published to github pages for every commit on the `main` branch [here]. + +[here]: https://slimevr.github.io/SlimeVR-Overlay/skeletal_model + + +## Code Style + +All code is autoformatted by `cargo fmt`. We suggest turning on autoformatting on save +in your IDE, otherwise you can just run `cargo fmt` on the command line. Also, all files +should end in a newline and have extra whitespace trimmed. + +Its also a good idea to run `cargo clippy` to fix the style lints it generates. diff --git a/autoupdater/README.md b/autoupdater/README.md index 58550403..002c6f3a 100644 --- a/autoupdater/README.md +++ b/autoupdater/README.md @@ -1,16 +1,16 @@ -# Autoupdater - -The SlimeVR autoupdater manages updating all the software for SlimeVR on a user's -computer. It does not handle updates of firmware. - -It reads a `version.yaml` file from a github release to determine the versions of the -software to download, then fetches them and installs them. - -Long term, we may use this to replace most or all of the business logic of the current -[SlimeVR Web Installer](https://github.com/SlimeVR/SlimeVR-Installer). - -## Project Status -This is abandoned due to lack of interested developers. - -When being actively developed, the Yaml description and serialization was complete -already. +# Autoupdater + +The SlimeVR autoupdater manages updating all the software for SlimeVR on a user's +computer. It does not handle updates of firmware. + +It reads a `version.yaml` file from a github release to determine the versions of the +software to download, then fetches them and installs them. + +Long term, we may use this to replace most or all of the business logic of the current +[SlimeVR Web Installer](https://github.com/SlimeVR/SlimeVR-Installer). + +## Project Status +This is abandoned due to lack of interested developers. + +When being actively developed, the Yaml description and serialization was complete +already. diff --git a/overlay/src/main.rs b/overlay/src/main.rs index 7dfc2c71..5874f64a 100644 --- a/overlay/src/main.rs +++ b/overlay/src/main.rs @@ -151,20 +151,30 @@ async fn overlay( .build(mngr) .wrap_err("Could not create skeleton")?; + let mut skeleton_mirrored = SkeletonBuilder { + key: String::from("slimevr_mirrored"), + ..SkeletonBuilder::default() + } + .build(mngr) + .wrap_err("Could not create mirrored skeleton")?; + log::info!("Overlay Loop"); let loop_ = async { let mut hidden_bones: HashSet = HashSet::new(); + let mut hidden_bones_mirrored: HashSet = HashSet::new(); loop { recv.changed() .await .wrap_err("Error while attempting to watch for feed update")?; let is_skeleton_visible = display_settings.borrow().is_visible; + let is_skeleton_mirrored = display_settings.borrow().is_mirrored; log::trace!("Got a feed update"); // Mark all bones as "need to hide" hidden_bones.extend(BoneKind::iter()); + hidden_bones_mirrored.extend(BoneKind::iter()); #[derive(Debug)] struct BoneInfo { @@ -229,6 +239,74 @@ async fn overlay( .collect() }; + let bones_mirrored: Vec = { + let guard = recv.borrow_and_update(); + let table = guard.as_ref().unwrap().0.table(); + log::trace!("update: {:#?}", table); + + let m = unwrap_or_continue!(table.data_feed_msgs()); + + // TODO: handle multiple updates? + let m = m.get(0); + let m = unwrap_or_continue!(m.message_as_data_feed_update()); + let bones_mirrored = unwrap_or_continue!(m.bones()); + log::debug!("Got {} bones before filtering", bones_mirrored.len()); + + bones_mirrored + .iter() + .filter_map(|b| { + let part = b.body_part(); + log::trace!("body_part: {part:?}"); + + let bone_kind = BoneKind::try_from(part) + .map_err(|e| { + log::trace!("Filtering out {e:?}"); + e + }) + .ok()?; + + let pos = if let Some(p) = b.head_position_g() { + p + } else { + log::warn!("No position"); + return None; + }; + let rot = if let Some(r) = b.rotation_g() { + r + } else { + log::warn!("No rotation"); + return None; + }; + let length = b.bone_length(); + + let pos = Translation3::new(pos.x(), pos.y(), -1.0 - pos.z()); + + let mut rot = UnitQuaternion::from_quaternion( + [rot.x(), rot.y(), rot.z(), rot.w()].into(), + ); + + // This is BAD, someone please fix this to use quaternions instead of converting to euler XD + let mut euler_angles = rot.euler_angles(); + euler_angles = (euler_angles.0, euler_angles.1, euler_angles.2); + rot = UnitQuaternion::from_euler_angles( + euler_angles.0, + -euler_angles.1 + std::f32::consts::PI, + euler_angles.2, + ); + + if is_skeleton_mirrored { + hidden_bones_mirrored.remove(&bone_kind); + } + Some(BoneInfo { + kind: bone_kind, + pos, + rot, + length, + }) + }) + .collect() + }; + log::debug!( "Bones after filtering: {:?}", bones.iter().map(|t| t.kind).collect::>() @@ -251,12 +329,33 @@ async fn overlay( skeleton.set_length(kind, length); } + for BoneInfo { + kind, + pos, + rot, + length, + } in bones_mirrored + { + let iso_mirrored = Isometry { + rotation: rot, + translation: pos, + }; + + skeleton_mirrored.set_isometry(kind, iso_mirrored); + skeleton_mirrored.set_length(kind, length); + } + // Update rendering state for kind in BoneKind::iter() { skeleton.set_visibility(kind, !hidden_bones.contains(&kind)); + skeleton_mirrored + .set_visibility(kind, !hidden_bones_mirrored.contains(&kind)); if let Err(e) = skeleton.update_render(kind, mngr) { log::error!("Error updating render for bone {kind:?}: {:?}", e); } + if let Err(e) = skeleton_mirrored.update_render(kind, mngr) { + log::error!("Error updating render for bone {kind:?}: {:?}", e); + } } } }; diff --git a/overlay/src/model/skeleton.rs b/overlay/src/model/skeleton.rs index 952b0e9a..5f5ef95c 100644 --- a/overlay/src/model/skeleton.rs +++ b/overlay/src/model/skeleton.rs @@ -46,10 +46,10 @@ const BONE_RADIUS: f32 = 0.002; /// Builder for the [`Skeleton`]. pub struct SkeletonBuilder { - colors: Option>>, - key: String, - bone_radius: f32, - bone_lengths: Option>, + pub colors: Option>>, + pub key: String, + pub bone_radius: f32, + pub bone_lengths: Option>, } impl SkeletonBuilder { #[allow(dead_code)]