From 8fbbcc37080a60f99a888715f06aa9ce81f992dc Mon Sep 17 00:00:00 2001 From: hut Date: Mon, 1 Apr 2024 16:29:14 +0200 Subject: [PATCH] switch bevy_xpbd physics engine to 64bit precision in preparation for enlargement of coordinate system to match real scale --- Cargo.toml | 2 +- src/camera.rs | 26 +++++++++++++++----------- src/commands.rs | 21 +++++++++++---------- src/world.rs | 11 ++++++----- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dc2d608..3f39ec8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.76.0" [dependencies] regex = "1" bevy = { version = "0.13.1", default-features = false, features = ["jpeg", "bevy_asset", "bevy_audio", "bevy_scene", "bevy_winit", "bevy_core_pipeline", "bevy_pbr", "bevy_gltf", "bevy_render", "bevy_text", "bevy_ui", "file_watcher", "multi-threaded", "png", "vorbis", "x11", "tonemapping_luts"]} -bevy_xpbd_3d = { version = "0.4", default-features = false, features = ["3d", "f32", "parry-f32", "parallel", "async-collider"] } +bevy_xpbd_3d = { version = "0.4", default-features = false, features = ["3d", "f64", "parry-f64", "parallel", "async-collider"] } bevy_embedded_assets = "0.10.2" [features] diff --git a/src/camera.rs b/src/camera.rs index c8100a8..31fed12 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -4,6 +4,7 @@ use bevy::window::PrimaryWindow; use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings}; use bevy::core_pipeline::tonemapping::Tonemapping; use bevy::transform::TransformSystem; +use bevy::math::DVec3; use bevy_xpbd_3d::prelude::*; use crate::{settings, audio, actor}; @@ -136,6 +137,7 @@ fn apply_input_to_player( ) { let dt = time.delta_seconds(); let mut play_thruster_sound = false; + let mut axis_input: DVec3 = DVec3::ZERO; let window_result = windows.get_single_mut(); let mut focused = true; @@ -145,7 +147,6 @@ fn apply_input_to_player( if let Ok((player_transform, mut engine, mut angularvelocity, mut v, mut torque)) = q_playercam.get_single_mut() { // Handle key input - let mut axis_input = Vec3::ZERO; if focused { if key_input.pressed(settings.key_forward) { axis_input.z += 1.2; @@ -168,7 +169,7 @@ fn apply_input_to_player( if key_input.pressed(settings.key_stop) { let stop_direction = -v.normalize(); if stop_direction.length_squared() > 0.3 { - axis_input += 1.0 * (player_transform.rotation.inverse() * stop_direction); + axis_input += 1.0 * DVec3::from(player_transform.rotation.inverse() * stop_direction.as_vec3()); } } } @@ -177,7 +178,7 @@ fn apply_input_to_player( // absolute maximum of 1, since every thruster can be used separately. If the forward // thrusters and the leftward thrusters are active at the same time, then of course the // total diagonal acceleration is faster than the forward acceleration alone. - axis_input = axis_input.clamp(Vec3::splat(-1.0), Vec3::splat(1.0)); + axis_input = axis_input.clamp(DVec3::splat(-1.0), DVec3::splat(1.0)); // Apply movement update let forward_factor = engine.current_warmup * (if axis_input.z > 0.0 { @@ -187,11 +188,11 @@ fn apply_input_to_player( }); let right_factor = engine.thrust_sideways * engine.current_warmup; let up_factor = engine.thrust_sideways * engine.current_warmup; - let factor = Vec3::new(right_factor, up_factor, forward_factor); + let factor = DVec3::new(right_factor as f64, up_factor as f64, forward_factor as f64); if axis_input.length_squared() > 0.003 { - let acceleration_global = player_transform.rotation * (axis_input * factor); - let mut acceleration_total = actor::ENGINE_SPEED_FACTOR * dt * acceleration_global; + let acceleration_global: DVec3 = DVec3::from(player_transform.rotation * (axis_input * factor).as_vec3()); + let mut acceleration_total: DVec3 = (actor::ENGINE_SPEED_FACTOR * dt) as f64 * acceleration_global; let threshold = 1e-5; if key_input.pressed(settings.key_stop) { // Decelerate @@ -248,20 +249,23 @@ fn apply_input_to_player( } } - let angular_slowdown = 2.0 - engine.reaction_wheels.powf(0.01).clamp(1.001, 1.1); + let angular_slowdown: f64 = (2.0 - engine.reaction_wheels.powf(0.01).clamp(1.001, 1.1)) as f64; if pitch_yaw_rot.length_squared() > 0.0001 { play_reactionwheel_sound = true; pitch_yaw_rot *= settings.mouse_sensitivity * engine.reaction_wheels; - torque.apply_torque(player_transform.rotation * Vec3::new( - 2.0*pitch_yaw_rot[0], pitch_yaw_rot[1], pitch_yaw_rot[2])); - angularvelocity.0 *= angular_slowdown.clamp(0.97, 1.0); + torque.apply_torque(DVec3::from( + player_transform.rotation * Vec3::new( + pitch_yaw_rot[0] * 2.0, + pitch_yaw_rot[1], + pitch_yaw_rot[2]))); + angularvelocity.0 *= angular_slowdown.clamp(0.97, 1.0) as f64; } else { if angularvelocity.length_squared() > 0.001 { angularvelocity.0 *= angular_slowdown; } else { - angularvelocity.0 = Vec3::splat(0.0); + angularvelocity.0 = DVec3::splat(0.0); } } diff --git a/src/commands.rs b/src/commands.rs index 97e4a11..f13b465 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -2,6 +2,7 @@ extern crate regex; use bevy::prelude::*; use bevy_xpbd_3d::prelude::*; +use bevy::math::DVec3; use crate::{actor, nature, world}; use regex::Regex; use std::f32::consts::PI; @@ -37,7 +38,7 @@ struct ParserState { model: String, model_scale: f32, rotation: Quat, - angular_momentum: Vec3, + angular_momentum: DVec3, pronoun: String, is_sphere: bool, is_player: bool, @@ -54,7 +55,7 @@ struct ParserState { warmup_seconds: f32, engine_type: actor::EngineType, oxygen: f32, - mass: f32, + mass: f64, collider: Collider, camdistance: f32, suit_integrity: f32, @@ -87,7 +88,7 @@ impl Default for ParserState { model: "".to_string(), model_scale: 1.0, rotation: Quat::IDENTITY, - angular_momentum: Vec3::new(0.03, 0.3, 0.09), + angular_momentum: DVec3::new(0.03, 0.3, 0.09), pronoun: "they/them".to_string(), is_sphere: false, is_player: false, @@ -285,8 +286,8 @@ pub fn load_defs( } ["angularmomentum", x, y, z] => { if let (Ok(x_float), Ok(y_float), Ok(z_float)) = - (x.parse::(), y.parse::(), z.parse::()) { - state.angular_momentum = Vec3::new(x_float, y_float, z_float); + (x.parse::(), y.parse::(), z.parse::()) { + state.angular_momentum = DVec3::new(x_float, y_float, z_float); } else { error!("Can't parse float: {line}"); @@ -321,7 +322,7 @@ pub fn load_defs( } } ["mass", value] => { - if let Ok(value_float) = value.parse::() { + if let Ok(value_float) = value.parse::() { state.mass = value_float; } else { @@ -333,7 +334,7 @@ pub fn load_defs( state.has_physics = false; } ["collider", "sphere", radius] => { - if let Ok(radius_float) = radius.parse::() { + if let Ok(radius_float) = radius.parse::() { state.collider = Collider::sphere(radius_float); } else { @@ -342,7 +343,7 @@ pub fn load_defs( } } ["collider", "capsule", height, radius] => { - if let (Ok(height_float), Ok(radius_float)) = (height.parse::(), radius.parse::()) { + if let (Ok(height_float), Ok(radius_float)) = (height.parse::(), radius.parse::()) { state.collider = Collider::capsule(height_float, radius_float); } else { @@ -538,10 +539,10 @@ fn spawn_entities( // Physics Parameters if state.has_physics { - let fix_scale = 1.0 / state.model_scale.powf(3.0); + let fix_scale: f64 = 1.0 / (state.model_scale as f64).powf(3.0); actor.insert(RigidBody::Dynamic); actor.insert(AngularVelocity(state.angular_momentum)); - actor.insert(ColliderDensity(state.mass * fix_scale)); + actor.insert(ColliderDensity((state.mass * fix_scale) as f64)); if state.collider_is_mesh { actor.insert(AsyncSceneCollider::new(Some( ComputedCollider::TriMesh diff --git a/src/world.rs b/src/world.rs index d981f60..edd41ff 100644 --- a/src/world.rs +++ b/src/world.rs @@ -2,6 +2,7 @@ use crate::{actor, nature, settings}; use bevy::prelude::*; use bevy::pbr::CascadeShadowConfigBuilder; use bevy::render::render_resource::{AsBindGroup, ShaderRef}; +use bevy::math::DVec3; use bevy_xpbd_3d::prelude::*; use std::f32::consts::PI; @@ -33,7 +34,7 @@ impl Plugin for WorldPlugin { app.add_plugins(PhysicsPlugins::default()); app.add_plugins(MaterialPlugin::::default()); //app.add_plugins(PhysicsDebugPlugin::default()); - app.insert_resource(Gravity(Vec3::splat(0.0))); + app.insert_resource(Gravity(DVec3::splat(0.0))); } } @@ -81,8 +82,8 @@ pub fn setup( commands.spawn(( actor::Actor::default(), RigidBody::Dynamic, - AngularVelocity(Vec3::new(0.1, 0.1, 0.03)), - LinearVelocity(Vec3::new(0.0, 0.0, 0.35)), + AngularVelocity(DVec3::new(0.1, 0.1, 0.03)), + LinearVelocity(DVec3::new(0.0, 0.0, 0.35)), Collider::sphere(1.0), SceneBundle { transform: Transform { @@ -203,10 +204,10 @@ fn handle_cheats( trans.translation = Vec3::new(800000.0, 400000.0, 0.0); } if key_input.just_pressed(settings.key_cheat_stop) { - v.0 = Vec3::ZERO; + v.0 = DVec3::ZERO; } if key_input.pressed(settings.key_cheat_speed) { - v.0 += trans.rotation * Vec3::new(0.0, 0.0, 1000.0); + v.0 += DVec3::from(trans.rotation * Vec3::new(0.0, 0.0, 1000.0)); } if key_input.pressed(settings.key_cheat_adrenaline_zero) { lifeform.adrenaline = 0.0;