diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..7817496 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,3 @@ +[target.wasm32-unknown-unknown] +runner = "wasm-server-runner" +rustflags = ["--cfg","web_sys_unstable_apis",] \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index d522457..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Build -on: - push: - branches: - - "main" - paths-ignore: - - "/docs" - - "README.md" - pull_request: - paths-ignore: - - "/docs" - - "README.md" -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: "Checkout" - uses: actions/checkout@v3 - - name: "Cache" - uses: Swatinem/rust-cache@v2 - - name: "External dependencies" - run: sudo apt-get install -y libasound2-dev portaudio19-dev build-essential libpulse-dev libdbus-1-dev libudev-dev libopenxr-loader1 libopenxr-dev - - name: "Checks" - run: | - cargo update - #cargo fmt --check - #cargo clippy --no-deps --tests -- -D warnings - #cargo rustdoc -- -D warnings - - name: "Build" - run: | - cargo build - cargo build --examples - - name: "Test" - run: | - cargo test --verbose diff --git a/.gitignore b/.gitignore index 77a7bd1..59322f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ **/target **/Cargo.lock **/runtime_libs/arm64-v8a/* +.vscode \.DS_Store diff --git a/Cargo.toml b/Cargo.toml index 57a7a2a..b080fbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,38 +6,78 @@ description = "Community crate for OpenXR in Bevy" repository = "https://github.com/awtterpip/bevy_oxr" license = "MIT/Apache-2.0" - [features] -default = ["linked"] +default = ["linked", "vulkan"] linked = ["openxr/linked"] - -[workspace] -members = ["examples/android", "examples/demo"] +vulkan = ["dep:ash"] [dependencies] -anyhow = "1.0.75" -ash = "0.37.3" -bevy = "0.12" -futures-lite = "2.0.1" -mint = "0.5.9" +bevy = "0.12.1" +paste = "1.0.14" wgpu = "0.17.1" -wgpu-core = { version = "0.17.1", features = ["vulkan"] } wgpu-hal = "0.17.1" -[target.'cfg( target_family = "unix" )'.dependencies] +[target.'cfg(target_family = "unix")'.dependencies] openxr = { version = "0.17.1", features = ["mint"] } -[target.'cfg(not(target_family = "unix"))'.dependencies] +[target.'cfg(target_family = "windows")'.dependencies] openxr = { version = "0.17.1", features = ["mint", "static"] } -[dev-dependencies] -bevy = "0.12" -color-eyre = "0.6.2" -bevy_rapier3d = { git = "https://github.com/devil-ira/bevy_rapier", branch = "bevy-0.12" } +[target.'cfg(not(target_family = "wasm"))'.dependencies] +ash = { version = "0.37.3", optional = true } -[[example]] -name = "xr" -path = "examples/xr.rs" - -[profile.release] -debug = true +[target.'cfg(target_family = "wasm")'.dependencies] +wasm-bindgen = "0.2.87" +web-sys = { version = "0.3.61", features = [ + # STANDARD + 'console', + 'Document', + 'Element', + 'Headers', + 'Navigator', + 'Window', + # IO + # 'Url', + # WEBGL + 'Gpu', + 'HtmlCanvasElement', + 'WebGl2RenderingContext', + 'WebGlFramebuffer', + ## XR + 'DomPointReadOnly', + 'XrWebGlLayer', + 'XrBoundedReferenceSpace', + 'XrEye', + 'XrFrame', + 'XrHandedness', + 'XrInputSource', + 'XrInputSourceArray', + 'XrInputSourceEvent', + 'XrInputSourceEventInit', + 'XrInputSourcesChangeEvent', + 'XrJointPose', + 'XrJointSpace', + 'XrPose', + 'XrReferenceSpace', + 'XrReferenceSpaceEvent', + 'XrReferenceSpaceEventInit', + 'XrReferenceSpaceType', + 'XrRenderState', + 'XrRenderStateInit', + 'XrRigidTransform', + 'XrSession', + 'XrSessionEvent', + 'XrSessionEventInit', + 'XrSessionInit', + 'XrSessionMode', + 'XrSpace', + 'XrTargetRayMode', + 'XrView', + 'XrViewerPose', + 'XrViewport', + 'XrVisibilityState', + 'XrWebGlLayer', + 'XrWebGlLayerInit', + 'XrSystem', +] } +wasm-bindgen-futures = "0.4" diff --git a/examples/android/.gitignore b/examples/android/.gitignore deleted file mode 100644 index d74eb91..0000000 --- a/examples/android/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target -/Cargo.lock -/runtime_libs diff --git a/examples/android/Cargo.toml b/examples/android/Cargo.toml deleted file mode 100644 index 2a52a8a..0000000 --- a/examples/android/Cargo.toml +++ /dev/null @@ -1,73 +0,0 @@ -[package] -name = "bevy_openxr_android" -version = "0.1.0" -edition = "2021" -description = "Example for building an Android OpenXR app with Bevy" -publish = false -license = "MIT OR Apache-2.0" - -[lib] -name = "bevy_openxr_android" -crate-type = ["rlib", "cdylib"] - -[target.'cfg(not(target_os="android"))'.dependencies.bevy_oxr] -path = "../../" -default-features = true - - -[dependencies] -bevy_oxr = { path = "../..", default-features = false } -bevy = "0.12" -openxr = { git = "https://github.com/Ralith/openxrs", features = ["mint"] } - -[profile.release] -lto = "fat" -codegen-units = 1 -panic = "abort" - -# This metadata is used by `cargo-apk` - `xbuild` uses the `manifest.yaml` instead. -[package.metadata.android] -package = "org.bevyengine.example_openxr_android" -build_targets = ["aarch64-linux-android"] -runtime_libs = "runtime_libs" -apk_name = "bevyopenxr" -# assets = "assets" -# res = "assets/android-res" -icon = "@mipmap/ic_launcher" -label = "Bevy Openxr Android" -strip = "strip" - -# [package.metadata.android.application] -# icon = "@mipmap/ic_launcher" -# label = "Bevy Example" - -[package.metadata.android.sdk] -target_sdk_version = 32 - -[package.metadata.android.application.activity] -theme = "@android:style/Theme.Black.NoTitleBar.Fullscreen" -config_changes = "density|keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|uiMode" -launch_mode = "singleTask" -orientation = "landscape" -resizeable_activity = false - -[[package.metadata.android.application.activity.intent_filter]] -actions = ["android.intent.action.MAIN"] -categories = [ - "com.oculus.intent.category.VR", - "android.intent.category.LAUNCHER", -] - -# !! IMPORTANT !! -# -# When creating your own apps, make sure to generate your own keystore, rather than using our example one! -# You can use `keytool` like so: -# keytool -genkey -v -keystore my-release-key.keystore -keyalg RSA -keysize 2048 -validity 10000 -# -# For more information on key signing and why it's so important, check out this article: -# https://developer.android.com/studio/publish/app-signing -# -# !! IMPORTANT !! -[package.metadata.android.signing.release] -path = "./hotham_examples.keystore" -keystore_password = "chomsky-vigilant-spa" diff --git a/examples/android/README.md b/examples/android/README.md deleted file mode 100644 index d8a7890..0000000 --- a/examples/android/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Bevy OpenXR Android example - -## Setup -Get libopenxr_loader.so from the Oculus OpenXR Mobile SDK and add it to `examples/android/runtime_libs/arm64-v8a` -https://developer.oculus.com/downloads/package/oculus-openxr-mobile-sdk/ -`examples/android/runtime_libs/arm64-v8a/libopenxr_loader.so` - -Also, install either `cargo-apk` (marked as deprecated): -```sh -cargo install cargo-apk -``` -or, install `xbuild` as it supersedes `cargo-apk`. Note that the `--git` is -very important here. -```sh -cargo install --git https://github.com/rust-mobile/xbuild -``` - -## Run -Running on Meta Quest can be done with https://github.com/rust-mobile/cargo-apk. -```sh -cargo apk run --release -``` -But cargo-apk is deprecated in favour of xbuild https://github.com/rust-mobile/xbuild. -```sh -# List devices and copy device string "adb:***" -x devices - -# Run on this device -x run --release --device adb:*** -``` -There is [manifest.yaml](./manifest.yaml) example required by xbuild. -Interface for this manifest can be found as AndroidConfig struct in https://github.com/rust-mobile/xbuild/blob/master/xbuild/src/config.rs - -## Notes - -### Relase mode -More optimisations enabled in Cargo.toml for the release mode. -This gives more performance but longer build time. -```toml -[profile.release] -lto = "fat" -codegen-units = 1 -panic = "abort" -``` - -### Cargo apk -If you see error like `Error: String `` is not a PID`, try to install cargo apk with a fix in branch. -```sh -cargo install --git https://github.com/rust-mobile/cargo-apk --branch=adb-logcat-uid -``` - -### Temporary JNIEnv log -This message is logged every frame. It's not yet fixed. -```sh -I JniUtils-inl: Creating temporary JNIEnv. This is a heavy operation and should be infrequent. To optimize, use JNI AttachCurrentThread on calling threa -``` - -### Android keystore -Release mode requires keystore. See Cargo.toml `package.metadata.android.signing.release`. - -When creating your own apps, make sure to generate your own keystore, rather than using our example one! -You can use `keytool` like so: -```sh -keytool -genkey -v -keystore my-release-key.keystore -keyalg RSA -keysize 2048 -validity 10000 -``` -For more information on key signing and why it's so important, check out this article: -https://developer.android.com/studio/publish/app-signing diff --git a/examples/android/hotham_examples.keystore b/examples/android/hotham_examples.keystore deleted file mode 100644 index 62623c4..0000000 Binary files a/examples/android/hotham_examples.keystore and /dev/null differ diff --git a/examples/android/manifest.yaml b/examples/android/manifest.yaml deleted file mode 100644 index 9a6118c..0000000 --- a/examples/android/manifest.yaml +++ /dev/null @@ -1,27 +0,0 @@ -android: - runtime_libs: - - "runtime_libs" - manifest: - package: "org.bevyengine.example_openxr_android" - application: - label: "Bevy Openxr Android" - theme: "@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen" - meta_data: - - name: "com.oculus.intent.category.VR" - value: "vr_only" - - name: "com.samsung.android.vr.application.mode" - value: "vr_only" - - name: "com.oculus.supportedDevices" - value: "quest|quest2|quest3|questpro" - activities: - - config_changes: "density|keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|uiMode" - launch_mode: "singleTask" - orientation: "landscape" - intent_filters: - - actions: - - "android.intent.action.MAIN" - categories: - - "com.oculus.intent.category.VR" - - "android.intent.category.LAUNCHER" - sdk: - target_sdk_version: 32 diff --git a/examples/android/src/lib.rs b/examples/android/src/lib.rs deleted file mode 100644 index 4f8bdeb..0000000 --- a/examples/android/src/lib.rs +++ /dev/null @@ -1,83 +0,0 @@ -use bevy::diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}; -use bevy::prelude::*; -use bevy::transform::components::Transform; -use bevy_oxr::xr_input::debug_gizmos::OpenXrDebugRenderer; -use bevy_oxr::xr_input::prototype_locomotion::{proto_locomotion, PrototypeLocomotionConfig}; -use bevy_oxr::xr_input::trackers::{ - OpenXRController, OpenXRLeftController, OpenXRRightController, OpenXRTracker, -}; -use bevy_oxr::DefaultXrPlugins; - -#[bevy_main] -fn main() { - App::new() - .add_plugins(DefaultXrPlugins) - .add_plugins(OpenXrDebugRenderer) - .add_plugins(LogDiagnosticsPlugin::default()) - .add_plugins(FrameTimeDiagnosticsPlugin) - .add_systems(Startup, setup) - .add_systems(Update, proto_locomotion) - .add_systems(Startup, spawn_controllers_example) - .insert_resource(PrototypeLocomotionConfig::default()) - .run(); -} - -/// set up a simple 3D scene -fn setup( - mut commands: Commands, - mut meshes: ResMut>, - mut materials: ResMut>, -) { - // plane - commands.spawn(PbrBundle { - mesh: meshes.add(shape::Plane::from_size(5.0).into()), - material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), - ..default() - }); - // cube - commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Cube { size: 0.1 })), - material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), - transform: Transform::from_xyz(0.0, 0.5, 0.0), - ..default() - }); - // cube - commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Cube { size: 0.1 })), - material: materials.add(Color::rgb(0.8, 0.0, 0.0).into()), - transform: Transform::from_xyz(0.0, 0.5, 1.0), - ..default() - }); - // light - commands.spawn(PointLightBundle { - point_light: PointLight { - intensity: 1500.0, - shadows_enabled: true, - ..default() - }, - transform: Transform::from_xyz(4.0, 8.0, 4.0), - ..default() - }); - // camera - // commands.spawn((Camera3dBundle { - // transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), - // ..default() - // },)); -} - -fn spawn_controllers_example(mut commands: Commands) { - //left hand - commands.spawn(( - OpenXRLeftController, - OpenXRController, - OpenXRTracker, - SpatialBundle::default(), - )); - //right hand - commands.spawn(( - OpenXRRightController, - OpenXRController, - OpenXRTracker, - SpatialBundle::default(), - )); -} diff --git a/examples/demo/Cargo.toml b/examples/demo/Cargo.toml deleted file mode 100644 index a6abbf9..0000000 --- a/examples/demo/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "demo" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["rlib", "cdylib"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bevy = "0.12" -bevy_oxr = { path = "../../", default-features = false } -bevy_rapier3d = { git = "https://github.com/devil-ira/bevy_rapier", branch = "bevy-0.12" } -color-eyre = "0.6.2" - - -[target.'cfg(not(target_os="android"))'.dependencies.bevy_oxr] -path = "../../" -# May need to be more specific. needs to be false at least on linux without an active runtime to run in flat -default-features = true diff --git a/examples/demo/Readme.md b/examples/demo/Readme.md deleted file mode 100644 index 6b16a29..0000000 --- a/examples/demo/Readme.md +++ /dev/null @@ -1,11 +0,0 @@ -## setup -install xbuild ```cargo install --git https://github.com/rust-mobile/xbuild``` -run ```x doctor``` and install all required depencencies -download the [openxr loader](https://developer.oculus.com/downloads/package/oculus-openxr-mobile-sdk/) and put it in the runtime_libs/arm64-v8a folder - -## how to run -run ```x devices``` - -and get the device name that looks something like this ```adb:1WD523S``` (probably a bit longer) - -then ```run x run --release``` diff --git a/examples/demo/manifest.yaml b/examples/demo/manifest.yaml deleted file mode 100644 index ab098d6..0000000 --- a/examples/demo/manifest.yaml +++ /dev/null @@ -1,34 +0,0 @@ -android: - runtime_libs: - - "runtime_libs" - manifest: - package: "org.bevyengine.demo_openxr_android" - uses_feature: - - name: "android.hardware.vr.headtracking" - required: true - - name: "oculus.software.handtracking" - required: false - - name: "com.oculus.experimental.enabled" - required: true - uses_permission: - - name: "com.oculus.permission.HAND_TRACKING" - application: - label: "Bevy Openxr Android" - theme: "@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen" - meta_data: - - name: "com.samsung.android.vr.application.mode" - value: "vr_only" - - name: "com.oculus.supportedDevices" - value: "quest|quest2|quest3" - activities: - - config_changes: "density|keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|uiMode" - launch_mode: "singleTask" - orientation: "landscape" - intent_filters: - - actions: - - "android.intent.action.MAIN" - categories: - - "com.oculus.intent.category.VR" - - "android.intent.category.LAUNCHER" - sdk: - target_sdk_version: 32 diff --git a/examples/demo/src/lib.rs b/examples/demo/src/lib.rs deleted file mode 100644 index 9ce5000..0000000 --- a/examples/demo/src/lib.rs +++ /dev/null @@ -1,791 +0,0 @@ -use std::{f32::consts::PI, ops::Mul, time::Duration}; - -use bevy::{ - diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, - ecs::schedule::ScheduleLabel, - input::{keyboard::KeyCode, Input}, - log::info, - prelude::{ - bevy_main, default, shape, App, Assets, Color, Commands, Component, Entity, Event, - EventReader, EventWriter, FixedUpdate, Gizmos, GlobalTransform, IntoSystemConfigs, - IntoSystemSetConfigs, Mesh, PbrBundle, PostUpdate, Quat, Query, Res, ResMut, Resource, - Schedule, SpatialBundle, StandardMaterial, Startup, Transform, Update, Vec3, Vec3Swizzles, - With, Without, World, - }, - time::{Fixed, Time, Timer, TimerMode}, - transform::TransformSystem, -}; -use bevy_oxr::{ - input::XrInput, - xr_init::{XrEnableRequest, XrEnableStatus, xr_only}, - resources::{XrFrameState, XrInstance, XrSession}, - xr_input::{ - actions::XrActionSets, - debug_gizmos::OpenXrDebugRenderer, - hands::common::{HandInputDebugRenderer, HandResource, HandsResource, OpenXrHandInput}, - hands::HandBone, - interactions::{ - draw_interaction_gizmos, draw_socket_gizmos, interactions, socket_interactions, - update_interactable_states, InteractionEvent, Touched, XRDirectInteractor, - XRInteractable, XRInteractableState, XRInteractorState, XRSelection, - }, - oculus_touch::OculusController, - prototype_locomotion::{proto_locomotion, PrototypeLocomotionConfig}, - trackers::{OpenXRController, OpenXRLeftController, OpenXRRightController, OpenXRTracker}, - Hand, - }, - DefaultXrPlugins, -}; - -fn input_stuff( - keys: Res>, - status: Res, - mut request: EventWriter, -) { - if keys.just_pressed(KeyCode::Space) { - match status.into_inner() { - XrEnableStatus::Enabled => request.send(XrEnableRequest::TryDisable), - XrEnableStatus::Disabled => request.send(XrEnableRequest::TryEnable), - XrEnableStatus::Waiting => (), - } - } -} - -mod setup; -use crate::setup::setup_scene; -use bevy_rapier3d::prelude::*; - -#[bevy_main] -pub fn main() { - color_eyre::install().unwrap(); - - info!("Running bevy_openxr demo"); - let mut app = App::new(); - - app.add_systems(Update, input_stuff) - //lets get the usual diagnostic stuff added - .add_plugins(LogDiagnosticsPlugin::default()) - .add_plugins(FrameTimeDiagnosticsPlugin) - //lets get the xr defaults added - .add_plugins(DefaultXrPlugins) - //lets add the debug renderer for the controllers - .add_plugins(OpenXrDebugRenderer) - //rapier goes here - .add_plugins(RapierPhysicsPlugin::::default().with_default_system_setup(false)) - // .add_plugins(RapierDebugRenderPlugin::default()) - //lets setup the starting scene - .add_systems(Startup, setup_scene) - .add_systems(Startup, spawn_controllers_example) //you need to spawn controllers or it crashes TODO:: Fix this - //add locomotion - .add_systems(Update, proto_locomotion.run_if(xr_only())) - .insert_resource(PrototypeLocomotionConfig::default()) - //lets add the interaction systems - .add_event::() - .add_systems(Update, prototype_interaction_input.run_if(xr_only())) - .add_systems(Update, interactions.before(update_interactable_states)) - .add_systems(Update, update_interactable_states) - .add_systems( - Update, - socket_interactions.before(update_interactable_states), - ) - //add the grabbable system - .add_systems(Update, update_grabbables.after(update_interactable_states)) - //draw the interaction gizmos - .add_systems( - Update, - draw_interaction_gizmos.run_if(xr_only()).after(update_interactable_states), - ) - .add_systems(Update, draw_socket_gizmos.after(update_interactable_states)) - //add our cube spawning system - .add_event::() - .insert_resource(SpawnCubeTimer(Timer::from_seconds( - 0.25, - bevy::time::TimerMode::Once, - ))) - .add_systems(Update, request_cube_spawn.run_if(xr_only())) - .add_systems(Update, cube_spawner.after(request_cube_spawn)) - //test capsule - .add_systems(Startup, spawn_capsule) - //physics hands - .add_plugins(OpenXrHandInput) - .add_plugins(HandInputDebugRenderer) - .add_systems(Startup, spawn_physics_hands) - .add_systems( - FixedUpdate, - update_physics_hands.before(PhysicsSet::SyncBackend), - ) - .add_event::() - .add_systems(Update, handle_ghost_hand_events.after(update_grabbables)) - .insert_resource(GhostTimers { - left: Timer::from_seconds(0.25, TimerMode::Once), - right: Timer::from_seconds(0.25, TimerMode::Once), - }) - .add_systems(Update, watch_ghost_timers.before(handle_ghost_hand_events)); - - //configure rapier sets - let mut physics_schedule = Schedule::new(PhysicsSchedule); - - physics_schedule.configure_sets( - ( - PhysicsSet::SyncBackend, - PhysicsSet::StepSimulation, - PhysicsSet::Writeback, - ) - .chain() - .before(TransformSystem::TransformPropagate), - ); - - app.configure_sets( - PostUpdate, - ( - PhysicsSet::SyncBackend, - PhysicsSet::StepSimulation, - PhysicsSet::Writeback, - ) - .chain() - .before(TransformSystem::TransformPropagate), - ); - //add rapier systems - physics_schedule.add_systems(( - RapierPhysicsPlugin::::get_systems(PhysicsSet::SyncBackend) - .in_set(PhysicsSet::SyncBackend), - RapierPhysicsPlugin::::get_systems(PhysicsSet::StepSimulation) - .in_set(PhysicsSet::StepSimulation), - RapierPhysicsPlugin::::get_systems(PhysicsSet::Writeback) - .in_set(PhysicsSet::Writeback), - )); - app.add_schedule(physics_schedule) // configure our fixed timestep schedule to run at the rate we want - .insert_resource(Time::::from_duration(Duration::from_secs_f32( - FIXED_TIMESTEP, - ))) - .add_systems(FixedUpdate, run_physics_schedule) - .add_systems(Startup, configure_physics); - app.run(); -} - -//fixed timesteps? -const FIXED_TIMESTEP: f32 = 1. / 90.; - -// A label for our new Schedule! -#[derive(ScheduleLabel, Debug, Hash, PartialEq, Eq, Clone)] -struct PhysicsSchedule; - -fn run_physics_schedule(world: &mut World) { - world.run_schedule(PhysicsSchedule); -} - -fn configure_physics(mut rapier_config: ResMut) { - rapier_config.timestep_mode = TimestepMode::Fixed { - dt: FIXED_TIMESTEP, - substeps: 1, - } -} - -fn spawn_controllers_example(mut commands: Commands) { - //left hand - commands.spawn(( - OpenXRLeftController, - OpenXRController, - OpenXRTracker, - SpatialBundle::default(), - XRDirectInteractor, - XRInteractorState::default(), - XRSelection::default(), - Hand::Left, - )); - //right hand - commands.spawn(( - OpenXRRightController, - OpenXRController, - OpenXRTracker, - SpatialBundle::default(), - XRDirectInteractor, - XRInteractorState::default(), - XRSelection::default(), - Hand::Right, - )); -} - -fn spawn_capsule( - mut commands: Commands, - mut meshes: ResMut>, - mut materials: ResMut>, -) { - commands.spawn(( - PbrBundle { - mesh: meshes.add(Mesh::from(shape::Capsule { - radius: 0.033, - depth: 0.115, - ..default() - })), - material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), - transform: Transform::from_xyz(0.0, 2.0, 0.0), - ..default() - }, - // Collider::capsule_y(0.0575, 0.034), - Collider::capsule( - Vec3 { - x: 0.0, - y: -0.0575, - z: 0.0, - }, - Vec3 { - x: 0.0, - y: 0.0575, - z: 0.0, - }, - 0.034, - ), - RigidBody::Dynamic, - )); -} - -#[derive(Component, PartialEq, Debug, Clone, Copy)] -pub enum PhysicsHandBone { - Palm, - Wrist, - ThumbMetacarpal, - ThumbProximal, - ThumbDistal, - ThumbTip, - IndexMetacarpal, - IndexProximal, - IndexIntermediate, - IndexDistal, - IndexTip, - MiddleMetacarpal, - MiddleProximal, - MiddleIntermediate, - MiddleDistal, - MiddleTip, - RingMetacarpal, - RingProximal, - RingIntermediate, - RingDistal, - RingTip, - LittleMetacarpal, - LittleProximal, - LittleIntermediate, - LittleDistal, - LittleTip, -} -#[derive(Component, PartialEq)] -pub enum BoneInitState { - True, - False, -} - -fn spawn_physics_hands(mut commands: Commands) { - //here we go - let hands = [Hand::Left, Hand::Right]; - let bones = [ - PhysicsHandBone::Palm, - PhysicsHandBone::Wrist, - PhysicsHandBone::ThumbMetacarpal, - PhysicsHandBone::ThumbProximal, - PhysicsHandBone::ThumbDistal, - PhysicsHandBone::ThumbTip, - PhysicsHandBone::IndexMetacarpal, - PhysicsHandBone::IndexProximal, - PhysicsHandBone::IndexIntermediate, - PhysicsHandBone::IndexDistal, - PhysicsHandBone::IndexTip, - PhysicsHandBone::MiddleMetacarpal, - PhysicsHandBone::MiddleProximal, - PhysicsHandBone::MiddleIntermediate, - PhysicsHandBone::MiddleDistal, - PhysicsHandBone::MiddleTip, - PhysicsHandBone::RingMetacarpal, - PhysicsHandBone::RingProximal, - PhysicsHandBone::RingIntermediate, - PhysicsHandBone::RingDistal, - PhysicsHandBone::RingTip, - PhysicsHandBone::LittleMetacarpal, - PhysicsHandBone::LittleProximal, - PhysicsHandBone::LittleIntermediate, - PhysicsHandBone::LittleDistal, - PhysicsHandBone::LittleTip, - ]; - let radius = 0.010; - let left_hand_membership_group = Group::GROUP_1; - let right_hand_membership_group = Group::GROUP_2; - let floor_membership = Group::GROUP_3; - - for hand in hands.iter() { - let hand_membership = match hand { - Hand::Left => left_hand_membership_group, - Hand::Right => right_hand_membership_group, - }; - let mut hand_filter: Group = Group::ALL; - hand_filter.remove(hand_membership); - hand_filter.remove(floor_membership); - for bone in bones.iter() { - //spawn the thing - commands.spawn(( - SpatialBundle::default(), - Collider::capsule( - Vec3 { - x: 0.0, - y: -0.0575, - z: 0.0, - }, - Vec3 { - x: 0.0, - y: 0.0575, - z: 0.0, - }, - radius, - ), - RigidBody::Dynamic, - Velocity::default(), - CollisionGroups::new(hand_membership, Group::from_bits(0b0001).unwrap()), - // SolverGroups::new(self_group, interaction_group), - bone.clone(), - BoneInitState::False, - hand.clone(), - )); - } - } -} - -pub enum MatchingType { - PositionMatching, - VelocityMatching, -} - -fn update_physics_hands( - hands_res: Option>, - mut bone_query: Query<( - &mut Transform, - &mut Collider, - &PhysicsHandBone, - &mut BoneInitState, - &Hand, - &mut Velocity, - )>, - hand_query: Query<(&Transform, &HandBone, &Hand, Without)>, - time: Res