A multiplayer VR framework w/voice chat

add openxr support

phaz.uk 52998727 ea5e764f

verified
Changed files
+131 -9
audio
src
client
+100 -4
Cargo.lock
··· 135 "bitflags 2.10.0", 136 "cc", 137 "cesu8", 138 - "jni", 139 "jni-sys", 140 "libc", 141 "log", ··· 987 checksum = "7ef8e4b7e61dfe7719bb03c884dc270cd46a82efb40f93e9933b990c5c190c59" 988 989 [[package]] 990 name = "bevy_pbr" 991 version = "0.17.3" 992 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1976 "core-foundation-sys", 1977 "coreaudio-rs 0.11.3", 1978 "dasp_sample", 1979 - "jni", 1980 "js-sys", 1981 "libc", 1982 "mach2", ··· 1998 "alsa", 1999 "coreaudio-rs 0.13.0", 2000 "dasp_sample", 2001 - "jni", 2002 "js-sys", 2003 "libc", 2004 "mach2", ··· 2322 dependencies = [ 2323 "anyhow", 2324 "bevy", 2325 "cpal 0.16.0", 2326 "dotenvy", 2327 "felix-audio", 2328 "felix-net", 2329 "tokio", 2330 ] 2331 ··· 2879 version = "1.0.15" 2880 source = "registry+https://github.com/rust-lang/crates.io-index" 2881 checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 2882 2883 [[package]] 2884 name = "jni" ··· 3657 source = "registry+https://github.com/rust-lang/crates.io-index" 3658 checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" 3659 dependencies = [ 3660 - "jni", 3661 "ndk 0.8.0", 3662 "ndk-context", 3663 "num-derive", ··· 3698 version = "1.21.3" 3699 source = "registry+https://github.com/rust-lang/crates.io-index" 3700 checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 3701 3702 [[package]] 3703 name = "opus" ··· 5294 "js-sys", 5295 "log", 5296 "naga", 5297 "portable-atomic", 5298 "profiling", 5299 "raw-window-handle", 5300 "smallvec", 5301 "static_assertions", 5302 "wasm-bindgen", 5303 "web-sys", 5304 "wgpu-core", 5305 "wgpu-hal", ··· 5331 "smallvec", 5332 "thiserror 2.0.17", 5333 "wgpu-core-deps-apple", 5334 "wgpu-core-deps-wasm", 5335 "wgpu-core-deps-windows-linux-android", 5336 "wgpu-hal", ··· 5342 version = "26.0.0" 5343 source = "registry+https://github.com/rust-lang/crates.io-index" 5344 checksum = "18ae5fbde6a4cbebae38358aa73fcd6e0f15c6144b67ef5dc91ded0db125dbdf" 5345 dependencies = [ 5346 "wgpu-hal", 5347 ]
··· 135 "bitflags 2.10.0", 136 "cc", 137 "cesu8", 138 + "jni 0.21.1", 139 "jni-sys", 140 "libc", 141 "log", ··· 987 checksum = "7ef8e4b7e61dfe7719bb03c884dc270cd46a82efb40f93e9933b990c5c190c59" 988 989 [[package]] 990 + name = "bevy_mod_openxr" 991 + version = "0.4.0" 992 + source = "registry+https://github.com/rust-lang/crates.io-index" 993 + checksum = "1ead3d12dc1c364bc8f5d063c8cd82df23a3d6261807abecfbbca70ca3cb2c15" 994 + dependencies = [ 995 + "android_system_properties", 996 + "ash", 997 + "bevy_app", 998 + "bevy_camera", 999 + "bevy_derive", 1000 + "bevy_ecs", 1001 + "bevy_log", 1002 + "bevy_math", 1003 + "bevy_mod_xr", 1004 + "bevy_platform", 1005 + "bevy_render", 1006 + "bevy_transform", 1007 + "jni 0.20.0", 1008 + "ndk-context", 1009 + "openxr", 1010 + "thiserror 2.0.17", 1011 + "wgpu", 1012 + "wgpu-hal", 1013 + ] 1014 + 1015 + [[package]] 1016 + name = "bevy_mod_xr" 1017 + version = "0.4.0" 1018 + source = "registry+https://github.com/rust-lang/crates.io-index" 1019 + checksum = "4107b79e3e3b38bc57a7c3fceb465300070b4bc3d2ebd839a9e04468b06cc11c" 1020 + dependencies = [ 1021 + "bevy_app", 1022 + "bevy_camera", 1023 + "bevy_color", 1024 + "bevy_derive", 1025 + "bevy_ecs", 1026 + "bevy_gizmos", 1027 + "bevy_log", 1028 + "bevy_math", 1029 + "bevy_render", 1030 + "bevy_transform", 1031 + ] 1032 + 1033 + [[package]] 1034 name = "bevy_pbr" 1035 version = "0.17.3" 1036 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2020 "core-foundation-sys", 2021 "coreaudio-rs 0.11.3", 2022 "dasp_sample", 2023 + "jni 0.21.1", 2024 "js-sys", 2025 "libc", 2026 "mach2", ··· 2042 "alsa", 2043 "coreaudio-rs 0.13.0", 2044 "dasp_sample", 2045 + "jni 0.21.1", 2046 "js-sys", 2047 "libc", 2048 "mach2", ··· 2366 dependencies = [ 2367 "anyhow", 2368 "bevy", 2369 + "bevy_mod_openxr", 2370 + "bevy_mod_xr", 2371 "cpal 0.16.0", 2372 "dotenvy", 2373 "felix-audio", 2374 "felix-net", 2375 + "openxr", 2376 "tokio", 2377 ] 2378 ··· 2926 version = "1.0.15" 2927 source = "registry+https://github.com/rust-lang/crates.io-index" 2928 checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 2929 + 2930 + [[package]] 2931 + name = "jni" 2932 + version = "0.20.0" 2933 + source = "registry+https://github.com/rust-lang/crates.io-index" 2934 + checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" 2935 + dependencies = [ 2936 + "cesu8", 2937 + "combine", 2938 + "jni-sys", 2939 + "log", 2940 + "thiserror 1.0.69", 2941 + "walkdir", 2942 + ] 2943 2944 [[package]] 2945 name = "jni" ··· 3718 source = "registry+https://github.com/rust-lang/crates.io-index" 3719 checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" 3720 dependencies = [ 3721 + "jni 0.21.1", 3722 "ndk 0.8.0", 3723 "ndk-context", 3724 "num-derive", ··· 3759 version = "1.21.3" 3760 source = "registry+https://github.com/rust-lang/crates.io-index" 3761 checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 3762 + 3763 + [[package]] 3764 + name = "openxr" 3765 + version = "0.19.0" 3766 + source = "registry+https://github.com/rust-lang/crates.io-index" 3767 + checksum = "2a2d6934d2508f94fd4cbda6c2a326f111f60ce59fd9136df6d478564397dd40" 3768 + dependencies = [ 3769 + "libc", 3770 + "libloading", 3771 + "ndk-context", 3772 + "openxr-sys", 3773 + ] 3774 + 3775 + [[package]] 3776 + name = "openxr-sys" 3777 + version = "0.11.0" 3778 + source = "registry+https://github.com/rust-lang/crates.io-index" 3779 + checksum = "f10e7e38c47f2175fc39363713b656db899fa0b4a14341029702cbdfa6f44d05" 3780 + dependencies = [ 3781 + "cmake", 3782 + "libc", 3783 + "mint", 3784 + ] 3785 3786 [[package]] 3787 name = "opus" ··· 5378 "js-sys", 5379 "log", 5380 "naga", 5381 + "parking_lot", 5382 "portable-atomic", 5383 "profiling", 5384 "raw-window-handle", 5385 "smallvec", 5386 "static_assertions", 5387 "wasm-bindgen", 5388 + "wasm-bindgen-futures", 5389 "web-sys", 5390 "wgpu-core", 5391 "wgpu-hal", ··· 5417 "smallvec", 5418 "thiserror 2.0.17", 5419 "wgpu-core-deps-apple", 5420 + "wgpu-core-deps-emscripten", 5421 "wgpu-core-deps-wasm", 5422 "wgpu-core-deps-windows-linux-android", 5423 "wgpu-hal", ··· 5429 version = "26.0.0" 5430 source = "registry+https://github.com/rust-lang/crates.io-index" 5431 checksum = "18ae5fbde6a4cbebae38358aa73fcd6e0f15c6144b67ef5dc91ded0db125dbdf" 5432 + dependencies = [ 5433 + "wgpu-hal", 5434 + ] 5435 + 5436 + [[package]] 5437 + name = "wgpu-core-deps-emscripten" 5438 + version = "26.0.0" 5439 + source = "registry+https://github.com/rust-lang/crates.io-index" 5440 + checksum = "d7670e390f416006f746b4600fdd9136455e3627f5bd763abf9a65daa216dd2d" 5441 dependencies = [ 5442 "wgpu-hal", 5443 ]
+3 -1
audio/src/voice/microphone.rs
··· 70 71 let stream = mic.build_input_stream( 72 &StreamConfig { 73 - channels: 1, 74 buffer_size: BufferSize::Fixed(BUFFER_SIZE as u32), 75 sample_rate: SampleRate(SAMPLE_RATE as u32) 76 }, ··· 81 buffer_indx = 0; 82 } else{ 83 for i in 0..data.len(){ 84 buffer[buffer_indx] = data[i]; 85 buffer_indx += 1; 86
··· 70 71 let stream = mic.build_input_stream( 72 &StreamConfig { 73 + channels: 2, 74 buffer_size: BufferSize::Fixed(BUFFER_SIZE as u32), 75 sample_rate: SampleRate(SAMPLE_RATE as u32) 76 }, ··· 81 buffer_indx = 0; 82 } else{ 83 for i in 0..data.len(){ 84 + if i % 2 == 0{ continue; } 85 + 86 buffer[buffer_indx] = data[i]; 87 buffer_indx += 1; 88
+3
client/Cargo.toml
··· 11 felix-net = { path = '../net' } 12 felix-audio = { path = '../audio' } 13 tokio = { version = "1.48.0", features = ["full"] }
··· 11 felix-net = { path = '../net' } 12 felix-audio = { path = '../audio' } 13 tokio = { version = "1.48.0", features = ["full"] } 14 + bevy_mod_openxr = "0.4.0" 15 + openxr = "0.19.0" 16 + bevy_mod_xr = "0.4.0"
+7 -2
client/src/components/debug_camera.rs
··· 1 use std::f32::consts::PI; 2 3 use bevy::{ input::mouse::MouseMotion, prelude::* }; 4 use felix_audio::voice::microphone::VoiceChatMicrophone; 5 6 use crate::net::connection::Connection; ··· 33 mut debug_text: Query<(&mut Text, &DebugText)>, 34 voice: Query<&VoiceChatMicrophone>, 35 networking: Query<&Connection>, 36 ){ 37 let net_manager = networking.single().unwrap(); 38 ··· 89 text.0 = format!( 90 "Microphone RMS: {:.4} 91 {}Position: {:.2} {:.2} {:.2} 92 - Rotation: {:.2} {:.2} {:.2} {:.2}", 93 rms, 94 95 remote_rms, ··· 101 transform.rotation.x, 102 transform.rotation.y, 103 transform.rotation.z, 104 - transform.rotation.w 105 ); 106 } 107
··· 1 use std::f32::consts::PI; 2 3 use bevy::{ input::mouse::MouseMotion, prelude::* }; 4 + use bevy_mod_xr::session::XrState; 5 use felix_audio::voice::microphone::VoiceChatMicrophone; 6 7 use crate::net::connection::Connection; ··· 34 mut debug_text: Query<(&mut Text, &DebugText)>, 35 voice: Query<&VoiceChatMicrophone>, 36 networking: Query<&Connection>, 37 + xr_state: Res<XrState> 38 ){ 39 let net_manager = networking.single().unwrap(); 40 ··· 91 text.0 = format!( 92 "Microphone RMS: {:.4} 93 {}Position: {:.2} {:.2} {:.2} 94 + Rotation: {:.2} {:.2} {:.2} {:.2} 95 + XR State: {:#?}", 96 rms, 97 98 remote_rms, ··· 104 transform.rotation.x, 105 transform.rotation.y, 106 transform.rotation.z, 107 + transform.rotation.w, 108 + 109 + xr_state.into_inner() 110 ); 111 } 112
+18 -2
client/src/main.rs
··· 1 - use bevy::{DefaultPlugins, app::{App, FixedUpdate, Startup, Update}, ecs::system::Commands}; 2 use felix_audio::{FelixAudio, voice}; 3 4 use crate::{components::{debug_camera, network_interface, remote_player}, setup::setup}; 5 ··· 12 13 App::new() 14 .add_plugins(( 15 - DefaultPlugins, 16 FelixAudio 17 )) 18 .add_systems(Startup, setup) 19 .add_systems(Startup, move | mut commands: Commands |{ 20 let ( comp, voice ) = net::handle_net().expect("Network Module Failed");
··· 1 + use bevy::{app::{App, FixedUpdate, Startup, Update}, ecs::system::Commands, prelude::*, render::pipelined_rendering::PipelinedRenderingPlugin}; 2 + use bevy_mod_openxr::{add_xr_plugins, resources::OxrSessionConfig}; 3 + use bevy_mod_xr::session::{XrSessionCreated, XrSessionPlugin}; 4 use felix_audio::{FelixAudio, voice}; 5 + use openxr::EnvironmentBlendMode; 6 7 use crate::{components::{debug_camera, network_interface, remote_player}, setup::setup}; 8 ··· 15 16 App::new() 17 .add_plugins(( 18 + add_xr_plugins( 19 + DefaultPlugins 20 + .build() 21 + .disable::<PipelinedRenderingPlugin>(), 22 + ).set(XrSessionPlugin { auto_handle: true }), 23 FelixAudio 24 )) 25 + .insert_resource(OxrSessionConfig { 26 + blend_mode_preference: vec![ 27 + EnvironmentBlendMode::ALPHA_BLEND, 28 + EnvironmentBlendMode::ADDITIVE, 29 + EnvironmentBlendMode::OPAQUE 30 + ], 31 + ..Default::default() 32 + }) 33 + .add_systems(XrSessionCreated, || { println!("[INFO] Started VR") }) 34 .add_systems(Startup, setup) 35 .add_systems(Startup, move | mut commands: Commands |{ 36 let ( comp, voice ) = net::handle_net().expect("Network Module Failed");