diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 972372781..bcc00516e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -110,7 +110,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: test - args: --doc --all-features + args: --doc - name: Get package names id: get-package-names run: |- @@ -135,7 +135,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: doc - args: --no-deps ${{ steps.get-package-names.outputs.PACKAGE_NAMES }} --all-features ${{ steps.get-features-for-docs.outputs.FEATURES_FOR_DOCS }} + args: --no-deps ${{ steps.get-package-names.outputs.PACKAGE_NAMES }} docs-and-demos-ghpages: name: Update Docs and Demos in GitHub Pages runs-on: ubuntu-latest @@ -176,7 +176,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: |- set -ex - cargo doc --verbose ${{ steps.get-package-names.outputs.PACKAGE_NAMES }} --all-features ${{ steps.get-features-for-docs.outputs.FEATURES_FOR_DOCS }} + cargo doc --verbose ${{ steps.get-package-names.outputs.PACKAGE_NAMES }} echo "" > target/doc/index.html for physics_backend in rapier xpbd; do cargo build \ diff --git a/Cargo.toml b/Cargo.toml index 9463045c1..2f7432a9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,8 +53,11 @@ bevy = { version = "^0.13", default-features = false, features = [ "x11", # "filesystem_watcher", ] } -bevy_xpbd_3d = { version = "^0.4" } +bevy_xpbd_3d = { version = "^0.4", features = ["3d","debug-plugin", "parallel", "async-collider", "parry-f32"] } bevy-tnua-xpbd3d = { path = "xpbd3d" } [package.metadata.docs.rs] all-features = true + +[features] +f64 = ["bevy-tnua-physics-integration-layer/f64"] \ No newline at end of file diff --git a/demos/Cargo.toml b/demos/Cargo.toml index 95c6e172b..1a3257484 100644 --- a/demos/Cargo.toml +++ b/demos/Cargo.toml @@ -11,11 +11,14 @@ exclude = [ default = [ # Comment this out when Bevy gets upgraded and bevy_egui lags behind "egui", + "bevy_xpbd_3d?/parry-f32", + "bevy_xpbd_2d?/parry-f32", ] egui = ["dep:bevy_egui", "dep:egui_plot"] rapier = [] rapier2d = ["rapier", "dep:bevy_rapier2d", "dep:bevy-tnua-rapier2d"] rapier3d = ["rapier", "dep:bevy_rapier3d", "dep:bevy-tnua-rapier3d"] +f64 = ["bevy_xpbd_3d?/parry-f64", "bevy_xpbd_2d?/parry-f64", "bevy-tnua-physics-integration-layer/f64", "bevy-tnua/f64"] xpbd = [] xpbd2d = ["xpbd", "dep:bevy_xpbd_2d", "dep:bevy-tnua-xpbd2d"] @@ -50,11 +53,13 @@ bevy-tnua-rapier2d = { path = "../rapier2d", optional = true } bevy_rapier3d = { version = "^0.25", features = ["debug-render-3d"], optional = true } bevy-tnua-rapier3d = { path = "../rapier3d", optional = true } -bevy_xpbd_2d = { version = "^0.4", optional = true } -bevy-tnua-xpbd2d = { path = "../xpbd2d", optional = true } +bevy_xpbd_2d = {version = "^0.4", default-features = false, features = ["2d","debug-plugin", "parallel"], optional = true} +bevy-tnua-xpbd2d = { path = "../xpbd2d", default-features = false, optional = true } -bevy_xpbd_3d = { version = "^0.4", optional = true } -bevy-tnua-xpbd3d = { path = "../xpbd3d", optional = true } +bevy_xpbd_3d = {version = "^0.4", default-features = false, features = ["3d","debug-plugin", "parallel", "async-collider"], optional = true } +bevy-tnua-xpbd3d = { path = "../xpbd3d", default-features = false, optional = true } bevy_egui = { version = "0.25", optional = true } egui_plot = { version = "0.26", optional = true } + + diff --git a/demos/build.rs b/demos/build.rs new file mode 100644 index 000000000..e85add04d --- /dev/null +++ b/demos/build.rs @@ -0,0 +1,6 @@ +fn main() { + #[cfg(all(feature = "bevy_xpbd_2d/parry-f32", feature = "f64"))] + compile_error!( + "Default Feature (f32) and f64 are mutually exclusive and cannot be enabled together" + ); +} diff --git a/demos/src/bin/platformer_2d.rs b/demos/src/bin/platformer_2d.rs index b31db5be7..02f165e62 100644 --- a/demos/src/bin/platformer_2d.rs +++ b/demos/src/bin/platformer_2d.rs @@ -6,6 +6,7 @@ use bevy_tnua::control_helpers::{ TnuaCrouchEnforcer, TnuaCrouchEnforcerPlugin, TnuaSimpleAirActionsCounter, TnuaSimpleFallThroughPlatformsHelper, }; +use bevy_tnua::math::{AsF32, Vector3}; use bevy_tnua::prelude::*; use bevy_tnua::{TnuaGhostSensor, TnuaToggle}; #[cfg(feature = "rapier2d")] @@ -264,7 +265,7 @@ fn setup_player(mut commands: Commands) { }); // `TnuaCrouchEnforcer` can be used to prevent the character from standing up when obstructed. - cmd.insert(TnuaCrouchEnforcer::new(0.5 * Vec3::Y, |cmd| { + cmd.insert(TnuaCrouchEnforcer::new(0.5 * Vector3::Y, |cmd| { // It needs a sensor shape because it needs to do a shapecast upwards. Without a sensor shape // it'd do a raycast. #[cfg(feature = "rapier2d")] diff --git a/demos/src/bin/platformer_3d.rs b/demos/src/bin/platformer_3d.rs index f1d1bcaa4..0d6027a22 100644 --- a/demos/src/bin/platformer_3d.rs +++ b/demos/src/bin/platformer_3d.rs @@ -6,6 +6,7 @@ use bevy_tnua::control_helpers::{ TnuaCrouchEnforcer, TnuaCrouchEnforcerPlugin, TnuaSimpleAirActionsCounter, TnuaSimpleFallThroughPlatformsHelper, }; +use bevy_tnua::math::{AsF32, Vector3}; use bevy_tnua::prelude::*; use bevy_tnua::{TnuaAnimatingState, TnuaGhostSensor, TnuaToggle}; #[cfg(feature = "rapier3d")] @@ -290,7 +291,7 @@ fn setup_player(mut commands: Commands, asset_server: Res) { }); // `TnuaCrouchEnforcer` can be used to prevent the character from standing up when obstructed. - cmd.insert(TnuaCrouchEnforcer::new(0.5 * Vec3::Y, |cmd| { + cmd.insert(TnuaCrouchEnforcer::new(0.5 * Vector3::Y, |cmd| { #[cfg(feature = "rapier3d")] cmd.insert(TnuaRapier3dSensorShape(rapier::Collider::cylinder( 0.0, 0.5, diff --git a/demos/src/bin/shooter_like.rs b/demos/src/bin/shooter_like.rs index 48d8ba332..737bbd570 100644 --- a/demos/src/bin/shooter_like.rs +++ b/demos/src/bin/shooter_like.rs @@ -8,6 +8,7 @@ use bevy_tnua::control_helpers::{ TnuaCrouchEnforcer, TnuaCrouchEnforcerPlugin, TnuaSimpleAirActionsCounter, TnuaSimpleFallThroughPlatformsHelper, }; +use bevy_tnua::math::{AdjustPrecision, AsF32, Float, Quaternion, Vector3}; use bevy_tnua::prelude::*; use bevy_tnua::{TnuaAnimatingState, TnuaGhostSensor, TnuaToggle}; #[cfg(feature = "rapier3d")] @@ -144,7 +145,7 @@ fn setup_player(mut commands: Commands, asset_server: Res) { speed: 20.0, walk: TnuaBuiltinWalk { float_height: 2.0, - turning_angvel: f32::INFINITY, + turning_angvel: Float::INFINITY, ..Default::default() }, actions_in_air: 1, @@ -297,7 +298,7 @@ fn setup_player(mut commands: Commands, asset_server: Res) { }); // `TnuaCrouchEnforcer` can be used to prevent the character from standing up when obstructed. - cmd.insert(TnuaCrouchEnforcer::new(0.5 * Vec3::Y, |cmd| { + cmd.insert(TnuaCrouchEnforcer::new(0.5 * Vector3::Y, |cmd| { #[cfg(feature = "rapier3d")] cmd.insert(TnuaRapier3dSensorShape(rapier::Collider::cylinder( 0.0, 0.5, @@ -365,7 +366,7 @@ fn apply_camera_controls( mouse_motion.clear(); Vec2::ZERO }; - let turning = Quat::from_rotation_y(-0.01 * total_delta.x); + let turning = Quaternion::from_rotation_y(-0.01 * total_delta.x.adjust_precision()); let Ok((player_transform, mut forward_from_camera)) = player_character_query.get_single_mut() else { return; @@ -373,8 +374,9 @@ fn apply_camera_controls( forward_from_camera.forward = turning.mul_vec3(forward_from_camera.forward); for mut camera in camera_query.iter_mut() { - camera.translation = - player_transform.translation() + -5.0 * forward_from_camera.forward + 1.0 * Vec3::Y; - camera.look_to(forward_from_camera.forward, Vec3::Y); + camera.translation = player_transform.translation() + + -5.0 * forward_from_camera.forward.f32() + + 1.0 * Vec3::Y; + camera.look_to(forward_from_camera.forward.f32(), Vec3::Y); } } diff --git a/demos/src/character_animating_systems/platformer_animating_systems.rs b/demos/src/character_animating_systems/platformer_animating_systems.rs index d81ed09e6..43b139726 100644 --- a/demos/src/character_animating_systems/platformer_animating_systems.rs +++ b/demos/src/character_animating_systems/platformer_animating_systems.rs @@ -1,5 +1,6 @@ use bevy::prelude::*; use bevy_tnua::builtins::{TnuaBuiltinCrouch, TnuaBuiltinDash, TnuaBuiltinJumpState}; +use bevy_tnua::math::Float; use bevy_tnua::prelude::*; use bevy_tnua::{TnuaAnimatingState, TnuaAnimatingStateDirective}; @@ -8,14 +9,15 @@ use crate::util::animating::AnimationsHandler; #[derive(Debug)] pub enum AnimationState { Standing, - Running(f32), + Running(Float), Jumping, Falling, Crouching, - Crawling(f32), + Crawling(Float), Dashing, } +#[allow(clippy::unnecessary_cast)] pub fn animate_platformer_character( mut animations_handlers_query: Query<( // `TnuaAnimatingState` is a helper for controlling the animations. The user system is @@ -112,7 +114,7 @@ pub fn animate_platformer_character( // animation (without necessarily replacing it). In this case - control the speed // of the animation based on the speed of the movement. AnimationState::Running(speed) | AnimationState::Crawling(speed) => { - player.set_speed(*speed); + player.set_speed(*speed as f32); } // Jumping and dashing can be chained, we want to start a new jump/dash animation // when one jump/dash is chained to another. @@ -142,7 +144,7 @@ pub fn animate_platformer_character( AnimationState::Running(speed) => { player .start(handler.animations["Running"].clone_weak()) - .set_speed(*speed) + .set_speed(*speed as f32) .repeat(); } AnimationState::Jumping => { @@ -164,7 +166,7 @@ pub fn animate_platformer_character( AnimationState::Crawling(speed) => { player .start(handler.animations["Crawling"].clone_weak()) - .set_speed(*speed) + .set_speed(*speed as f32) .repeat(); } AnimationState::Dashing => { diff --git a/demos/src/character_control_systems/platformer_control_systems.rs b/demos/src/character_control_systems/platformer_control_systems.rs index 17655f88b..0f5b7c571 100644 --- a/demos/src/character_control_systems/platformer_control_systems.rs +++ b/demos/src/character_control_systems/platformer_control_systems.rs @@ -5,6 +5,7 @@ use bevy_tnua::builtins::{TnuaBuiltinCrouch, TnuaBuiltinCrouchState, TnuaBuiltin use bevy_tnua::control_helpers::{ TnuaCrouchEnforcer, TnuaSimpleAirActionsCounter, TnuaSimpleFallThroughPlatformsHelper, }; +use bevy_tnua::math::{AdjustPrecision, AsF32, Float, Vector3}; use bevy_tnua::prelude::*; use bevy_tnua::{TnuaGhostSensor, TnuaProximitySensor}; @@ -13,6 +14,7 @@ use crate::ui::tuning::UiTunable; use super::Dimensionality; #[allow(clippy::type_complexity)] +#[allow(clippy::useless_conversion)] pub fn apply_platformer_controls( #[cfg(feature = "egui")] mut egui_context: EguiContexts, keyboard: Res>, @@ -72,29 +74,30 @@ pub fn apply_platformer_controls( { // This part is just keyboard input processing. In a real game this would probably be done // with a third party plugin. - let mut direction = Vec3::ZERO; + let mut direction = Vector3::ZERO; if config.dimensionality == Dimensionality::Dim3 { if keyboard.any_pressed([KeyCode::ArrowUp, KeyCode::KeyW]) { - direction -= Vec3::Z; + direction -= Vector3::Z; } if keyboard.any_pressed([KeyCode::ArrowDown, KeyCode::KeyS]) { - direction += Vec3::Z; + direction += Vector3::Z; } } if keyboard.any_pressed([KeyCode::ArrowLeft, KeyCode::KeyA]) { - direction -= Vec3::X; + direction -= Vector3::X; } if keyboard.any_pressed([KeyCode::ArrowRight, KeyCode::KeyD]) { - direction += Vec3::X; + direction += Vector3::X; } direction = direction.clamp_length_max(1.0); if let Some(forward_from_camera) = forward_from_camera { direction = Transform::default() - .looking_to(forward_from_camera.forward, Vec3::Y) - .transform_point(direction); + .looking_to(forward_from_camera.forward.f32(), Vec3::Y) + .transform_point(direction.f32()) + .adjust_precision(); } let jump = match config.dimensionality { @@ -291,7 +294,7 @@ pub fn apply_platformer_controls( // frame's input. controller.basis(TnuaBuiltinWalk { desired_velocity: if turn_in_place { - Vec3::ZERO + Vector3::ZERO } else { direction * speed_factor * config.speed }, @@ -356,7 +359,7 @@ pub fn apply_platformer_controls( } else { // For shooters, we want to allow rotating mid-dash if the player moves the // mouse. - Vec3::ZERO + Vector3::ZERO }, allow_in_air: air_actions_counter.air_count_for(TnuaBuiltinDash::NAME) <= config.actions_in_air, @@ -369,14 +372,14 @@ pub fn apply_platformer_controls( #[derive(Component)] pub struct CharacterMotionConfigForPlatformerDemo { pub dimensionality: Dimensionality, - pub speed: f32, + pub speed: Float, pub walk: TnuaBuiltinWalk, pub actions_in_air: usize, pub jump: TnuaBuiltinJump, pub crouch: TnuaBuiltinCrouch, - pub dash_distance: f32, + pub dash_distance: Float, pub dash: TnuaBuiltinDash, - pub one_way_platforms_min_proximity: f32, + pub one_way_platforms_min_proximity: Float, pub falling_through: FallingThroughControlScheme, } @@ -442,13 +445,13 @@ impl UiTunable for FallingThroughControlScheme { #[derive(Component)] pub struct ForwardFromCamera { - pub forward: Vec3, + pub forward: Vector3, } impl Default for ForwardFromCamera { fn default() -> Self { Self { - forward: Vec3::NEG_Z, + forward: Vector3::NEG_Z, } } } diff --git a/demos/src/levels_setup/for_2d_platformer.rs b/demos/src/levels_setup/for_2d_platformer.rs index 52b958886..03d3cf029 100644 --- a/demos/src/levels_setup/for_2d_platformer.rs +++ b/demos/src/levels_setup/for_2d_platformer.rs @@ -2,7 +2,10 @@ use bevy::prelude::*; #[cfg(feature = "rapier2d")] use bevy_rapier2d::{prelude as rapier, prelude::*}; -use bevy_tnua::TnuaGhostPlatform; +use bevy_tnua::{ + math::{AdjustPrecision, Vector2, Vector3}, + TnuaGhostPlatform, +}; #[cfg(feature = "xpbd2d")] use bevy_xpbd_2d::{prelude as xpbd, prelude::*}; @@ -31,7 +34,7 @@ pub fn setup_level(mut commands: Commands, asset_server: Res) { #[cfg(feature = "xpbd2d")] { cmd.insert(xpbd::RigidBody::Static); - cmd.insert(xpbd::Collider::halfspace(Vec2::Y)); + cmd.insert(xpbd::Collider::halfspace(Vector2::Y)); } for ([width, height], transform) in [ @@ -58,7 +61,10 @@ pub fn setup_level(mut commands: Commands, asset_server: Res) { #[cfg(feature = "xpbd2d")] { cmd.insert(xpbd::RigidBody::Static); - cmd.insert(xpbd::Collider::rectangle(width, height)); + cmd.insert(xpbd::Collider::rectangle( + width.adjust_precision(), + height.adjust_precision(), + )); } } @@ -201,10 +207,10 @@ pub fn setup_level(mut commands: Commands, asset_server: Res) { cmd.insert(MovingPlatform::new( 4.0, &[ - Vec3::new(-4.0, 6.0, 0.0), - Vec3::new(-8.0, 6.0, 0.0), - Vec3::new(-8.0, 10.0, 0.0), - Vec3::new(-4.0, 10.0, 0.0), + Vector3::new(-4.0, 6.0, 0.0), + Vector3::new(-8.0, 6.0, 0.0), + Vector3::new(-8.0, 10.0, 0.0), + Vector3::new(-4.0, 10.0, 0.0), ], )); } diff --git a/demos/src/levels_setup/for_3d_platformer.rs b/demos/src/levels_setup/for_3d_platformer.rs index a9a596ff1..3445a90fb 100644 --- a/demos/src/levels_setup/for_3d_platformer.rs +++ b/demos/src/levels_setup/for_3d_platformer.rs @@ -2,7 +2,7 @@ use bevy::prelude::*; #[cfg(feature = "rapier3d")] use bevy_rapier3d::{prelude as rapier, prelude::*}; -use bevy_tnua::TnuaGhostPlatform; +use bevy_tnua::{math::Vector3, TnuaGhostPlatform}; #[cfg(feature = "xpbd3d")] use bevy_xpbd_3d::{prelude as xpbd, prelude::*}; @@ -172,12 +172,12 @@ pub fn setup_level( cmd.insert(MovingPlatform::new( 4.0, &[ - Vec3::new(-4.0, 6.0, 0.0), - Vec3::new(-8.0, 6.0, 0.0), - Vec3::new(-8.0, 10.0, 0.0), - Vec3::new(-8.0, 10.0, -4.0), - Vec3::new(-4.0, 10.0, -4.0), - Vec3::new(-4.0, 10.0, 0.0), + Vector3::new(-4.0, 6.0, 0.0), + Vector3::new(-8.0, 6.0, 0.0), + Vector3::new(-8.0, 10.0, 0.0), + Vector3::new(-8.0, 10.0, -4.0), + Vector3::new(-4.0, 10.0, -4.0), + Vector3::new(-4.0, 10.0, 0.0), ], )); } diff --git a/demos/src/moving_platform.rs b/demos/src/moving_platform.rs index 80c64065d..6ba261451 100644 --- a/demos/src/moving_platform.rs +++ b/demos/src/moving_platform.rs @@ -1,4 +1,5 @@ use bevy::prelude::*; +use bevy_tnua::math::{AdjustPrecision, Float, Vector3}; pub struct MovingPlatformPlugin; @@ -8,7 +9,7 @@ impl Plugin for MovingPlatformPlugin { app.add_systems( Update, MovingPlatform::make_system( - |velocity: &mut bevy_rapier2d::prelude::Velocity, linvel: Vec3| { + |velocity: &mut bevy_rapier2d::prelude::Velocity, linvel: Vector3| { velocity.linvel = linvel.truncate(); }, ), @@ -17,7 +18,7 @@ impl Plugin for MovingPlatformPlugin { app.add_systems( Update, MovingPlatform::make_system( - |velocity: &mut bevy_rapier3d::prelude::Velocity, linvel: Vec3| { + |velocity: &mut bevy_rapier3d::prelude::Velocity, linvel: Vector3| { velocity.linvel = linvel; }, ), @@ -26,7 +27,7 @@ impl Plugin for MovingPlatformPlugin { app.add_systems( Update, MovingPlatform::make_system( - |velocity: &mut bevy_xpbd_2d::prelude::LinearVelocity, linvel: Vec3| { + |velocity: &mut bevy_xpbd_2d::prelude::LinearVelocity, linvel: Vector3| { velocity.0 = linvel.truncate(); }, ), @@ -35,7 +36,7 @@ impl Plugin for MovingPlatformPlugin { app.add_systems( Update, MovingPlatform::make_system( - |velocity: &mut bevy_xpbd_3d::prelude::LinearVelocity, linvel: Vec3| { + |velocity: &mut bevy_xpbd_3d::prelude::LinearVelocity, linvel: Vector3| { velocity.0 = linvel; }, ), @@ -46,12 +47,12 @@ impl Plugin for MovingPlatformPlugin { #[derive(Component)] pub struct MovingPlatform { pub current_leg: usize, - pub speed: f32, - pub locations: Vec, + pub speed: Float, + pub locations: Vec, } impl MovingPlatform { - pub fn new(speed: f32, locations: &[Vec3]) -> Self { + pub fn new(speed: Float, locations: &[Vector3]) -> Self { Self { current_leg: 0, speed, @@ -60,19 +61,21 @@ impl MovingPlatform { } fn make_system( - mut updater: impl 'static + Send + Sync + FnMut(&mut V, Vec3), + mut updater: impl 'static + Send + Sync + FnMut(&mut V, Vector3), ) -> bevy::ecs::schedule::SystemConfigs { (move |time: Res