From 29508f065f58bb2b2112857a0dd2f3e523f18f55 Mon Sep 17 00:00:00 2001 From: Benjamin Brienen Date: Tue, 17 Sep 2024 01:28:12 +0200 Subject: [PATCH] Fix floating point math (#15239) # Objective - Fixes #15236 ## Solution - Use bevy_math::ops instead of std floating point operations. ## Testing - Did you test these changes? If so, how? Unit tests and `cargo run -p ci -- test` - How can other people (reviewers) test your changes? Is there anything specific they need to know? Execute `cargo run -p ci -- test` on Windows. - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? Windows ## Migration Guide - Not a breaking change - Projects should use bevy math where applicable --------- Co-authored-by: Alice Cecile Co-authored-by: IQuick 143 Co-authored-by: Joona Aalto --- clippy.toml | 30 +++++++++++++++++++ crates/bevy_animation/src/lib.rs | 10 +++---- crates/bevy_color/src/laba.rs | 14 ++++----- crates/bevy_color/src/lcha.rs | 11 +++---- crates/bevy_color/src/oklaba.rs | 14 ++++----- crates/bevy_color/src/oklcha.rs | 17 ++++++----- crates/bevy_color/src/srgba.rs | 6 ++-- crates/bevy_core_pipeline/src/bloom/mod.rs | 10 ++++--- crates/bevy_core_pipeline/src/dof/mod.rs | 3 +- crates/bevy_ecs/src/query/iter.rs | 14 ++++----- crates/bevy_gizmos/src/arcs.rs | 3 +- crates/bevy_gizmos/src/circles.rs | 4 +-- crates/bevy_gizmos/src/grid.rs | 4 +-- crates/bevy_gizmos/src/light.rs | 5 ++-- crates/bevy_gizmos/src/primitives/helpers.rs | 4 +-- .../bevy_math/src/bounding/bounded2d/mod.rs | 3 +- crates/bevy_math/src/lib.rs | 5 ++-- crates/bevy_math/src/ops.rs | 1 + crates/bevy_pbr/src/cluster/assign.rs | 16 ++++++---- crates/bevy_pbr/src/fog.rs | 18 +++++------ crates/bevy_pbr/src/light/mod.rs | 9 ++++-- .../meshlet/visibility_buffer_raster_node.rs | 7 ++--- crates/bevy_pbr/src/pbr_material.rs | 7 ++--- crates/bevy_pbr/src/render/light.rs | 14 ++++----- crates/bevy_render/src/camera/camera.rs | 11 +++---- crates/bevy_render/src/camera/projection.rs | 4 +-- .../bevy_render/src/mesh/primitives/dim2.rs | 13 ++++---- .../src/mesh/primitives/dim3/capsule.rs | 12 +++----- .../src/mesh/primitives/dim3/cone.rs | 6 ++-- .../mesh/primitives/dim3/conical_frustum.rs | 6 ++-- .../src/mesh/primitives/dim3/cylinder.rs | 6 ++-- .../src/mesh/primitives/dim3/sphere.rs | 14 ++++----- .../src/mesh/primitives/dim3/torus.rs | 15 ++++++---- examples/2d/bounding_2d.rs | 13 ++++---- examples/2d/mesh2d_manual.rs | 4 +-- examples/2d/rotation.rs | 3 +- examples/2d/text2d.rs | 9 +++--- examples/3d/anisotropy.rs | 2 +- examples/3d/bloom_3d.rs | 3 +- examples/3d/clearcoat.rs | 6 ++-- examples/3d/deferred_rendering.rs | 3 +- examples/3d/fog.rs | 7 +++-- examples/3d/motion_blur.rs | 18 ++++++----- examples/3d/parallax_mapping.rs | 6 ++-- examples/3d/spotlight.rs | 7 +++-- examples/3d/ssao.rs | 3 +- examples/3d/transmission.rs | 9 +++--- examples/3d/transparency_3d.rs | 3 +- examples/3d/update_gltf_scene.rs | 4 +-- examples/animation/color_animation.rs | 4 +-- examples/animation/cubic_curve.rs | 2 +- examples/animation/custom_skinned_mesh.rs | 3 +- examples/animation/gltf_skinned_mesh.rs | 4 +-- examples/audio/audio_control.rs | 3 +- examples/audio/decodable.rs | 3 +- examples/audio/pitch.rs | 4 +-- examples/audio/spatial_audio_2d.rs | 2 +- examples/audio/spatial_audio_3d.rs | 4 +-- examples/ecs/iter_combinations.rs | 6 ++-- examples/games/alien_cake_addict.rs | 5 ++-- examples/games/desk_toy.rs | 2 +- examples/gizmos/2d_gizmos.rs | 22 ++++++++------ examples/gizmos/3d_gizmos.rs | 10 +++---- examples/gizmos/axes.rs | 25 ++++++++-------- examples/math/custom_primitives.rs | 8 ++--- examples/math/render_primitives.rs | 12 ++++---- examples/picking/sprite_picking.rs | 4 +-- examples/shader/custom_post_processing.rs | 4 +-- examples/shader/shader_prepass.rs | 2 +- examples/shader/storage_buffer.rs | 6 ++-- examples/state/computed_states.rs | 2 +- examples/state/custom_transitions.rs | 2 +- examples/state/states.rs | 2 +- examples/state/sub_states.rs | 2 +- examples/stress_tests/many_cubes.rs | 4 +-- examples/stress_tests/many_foxes.rs | 2 +- examples/stress_tests/many_gizmos.rs | 2 +- examples/stress_tests/many_lights.rs | 3 +- examples/stress_tests/text_pipeline.rs | 2 +- examples/stress_tests/transform_hierarchy.rs | 4 +-- examples/time/virtual_time.rs | 2 +- examples/ui/overflow_debug.rs | 11 +++---- examples/ui/text.rs | 6 ++-- examples/ui/ui_scaling.rs | 2 +- 84 files changed, 331 insertions(+), 266 deletions(-) diff --git a/clippy.toml b/clippy.toml index ccf511898b..46c61a895f 100644 --- a/clippy.toml +++ b/clippy.toml @@ -10,3 +10,33 @@ doc-valid-idents = [ "WebGPU", "..", ] + +disallowed-methods = [ + { path = "f32::powi", reason = "use bevy_math::ops::FloatPow::squared, bevy_math::ops::FloatPow::cubed, or bevy_math::ops::powf instead for libm determinism" }, + { path = "f32::log", reason = "use bevy_math::ops::ln, bevy_math::ops::log2, or bevy_math::ops::log10 instead for libm determinism" }, + { path = "f32::abs_sub", reason = "deprecated and deeply confusing method" }, + { path = "f32::powf", reason = "use bevy_math::ops::powf instead for libm determinism" }, + { path = "f32::exp", reason = "use bevy_math::ops::exp instead for libm determinism" }, + { path = "f32::exp2", reason = "use bevy_math::ops::exp2 instead for libm determinism" }, + { path = "f32::ln", reason = "use bevy_math::ops::ln instead for libm determinism" }, + { path = "f32::log2", reason = "use bevy_math::ops::log2 instead for libm determinism" }, + { path = "f32::log10", reason = "use bevy_math::ops::log10 instead for libm determinism" }, + { path = "f32::cbrt", reason = "use bevy_math::ops::cbrt instead for libm determinism" }, + { path = "f32::hypot", reason = "use bevy_math::ops::hypot instead for libm determinism" }, + { path = "f32::sin", reason = "use bevy_math::ops::sin instead for libm determinism" }, + { path = "f32::cos", reason = "use bevy_math::ops::cos instead for libm determinism" }, + { path = "f32::tan", reason = "use bevy_math::ops::tan instead for libm determinism" }, + { path = "f32::asin", reason = "use bevy_math::ops::asin instead for libm determinism" }, + { path = "f32::acos", reason = "use bevy_math::ops::acos instead for libm determinism" }, + { path = "f32::atan", reason = "use bevy_math::ops::atan instead for libm determinism" }, + { path = "f32::atan2", reason = "use bevy_math::ops::atan2 instead for libm determinism" }, + { path = "f32::sin_cos", reason = "use bevy_math::ops::sin_cos instead for libm determinism" }, + { path = "f32::exp_m1", reason = "use bevy_math::ops::exp_m1 instead for libm determinism" }, + { path = "f32::ln_1p", reason = "use bevy_math::ops::ln_1p instead for libm determinism" }, + { path = "f32::sinh", reason = "use bevy_math::ops::sinh instead for libm determinism" }, + { path = "f32::cosh", reason = "use bevy_math::ops::cosh instead for libm determinism" }, + { path = "f32::tanh", reason = "use bevy_math::ops::tanh instead for libm determinism" }, + { path = "f32::asinh", reason = "use bevy_math::ops::asinh instead for libm determinism" }, + { path = "f32::acosh", reason = "use bevy_math::ops::acosh instead for libm determinism" }, + { path = "f32::atanh", reason = "use bevy_math::ops::atanh instead for libm determinism" }, +] diff --git a/crates/bevy_animation/src/lib.rs b/crates/bevy_animation/src/lib.rs index fa88b40d0c..c8f521fdbc 100755 --- a/crates/bevy_animation/src/lib.rs +++ b/crates/bevy_animation/src/lib.rs @@ -22,7 +22,7 @@ use bevy_app::{App, Plugin, PostUpdate}; use bevy_asset::{Asset, AssetApp, Assets, Handle}; use bevy_core::Name; use bevy_ecs::{entity::MapEntities, prelude::*, reflect::ReflectMapEntities}; -use bevy_math::{FloatExt, Quat, Vec3}; +use bevy_math::{FloatExt, FloatPow, Quat, Vec3}; use bevy_reflect::std_traits::ReflectDefault; use bevy_reflect::Reflect; use bevy_render::mesh::morph::MorphWeights; @@ -1211,10 +1211,10 @@ fn cubic_spline_interpolation( where T: Mul + Add, { - value_start * (2.0 * lerp.powi(3) - 3.0 * lerp.powi(2) + 1.0) - + tangent_out_start * (step_duration) * (lerp.powi(3) - 2.0 * lerp.powi(2) + lerp) - + value_end * (-2.0 * lerp.powi(3) + 3.0 * lerp.powi(2)) - + tangent_in_end * step_duration * (lerp.powi(3) - lerp.powi(2)) + value_start * (2.0 * lerp.cubed() - 3.0 * lerp.squared() + 1.0) + + tangent_out_start * (step_duration) * (lerp.cubed() - 2.0 * lerp.squared() + lerp) + + value_end * (-2.0 * lerp.cubed() + 3.0 * lerp.squared()) + + tangent_in_end * step_duration * (lerp.cubed() - lerp.squared()) } /// Adds animation support to an app diff --git a/crates/bevy_color/src/laba.rs b/crates/bevy_color/src/laba.rs index 391bb9b4fe..39ac37f8ff 100644 --- a/crates/bevy_color/src/laba.rs +++ b/crates/bevy_color/src/laba.rs @@ -2,7 +2,7 @@ use crate::{ impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hwba, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza, }; -use bevy_math::{Vec3, Vec4}; +use bevy_math::{ops, Vec3, Vec4}; #[cfg(feature = "bevy_reflect")] use bevy_reflect::prelude::*; @@ -225,7 +225,7 @@ impl From for Xyza { let fx = a / 500.0 + fy; let fz = fy - b / 200.0; let xr = { - let fx3 = fx.powf(3.0); + let fx3 = ops::powf(fx, 3.0); if fx3 > Laba::CIE_EPSILON { fx3 @@ -234,12 +234,12 @@ impl From for Xyza { } }; let yr = if l > Laba::CIE_EPSILON * Laba::CIE_KAPPA { - ((l + 16.0) / 116.0).powf(3.0) + ops::powf((l + 16.0) / 116.0, 3.0) } else { l / Laba::CIE_KAPPA }; let zr = { - let fz3 = fz.powf(3.0); + let fz3 = ops::powf(fz, 3.0); if fz3 > Laba::CIE_EPSILON { fz3 @@ -262,17 +262,17 @@ impl From for Laba { let yr = y / Xyza::D65_WHITE.y; let zr = z / Xyza::D65_WHITE.z; let fx = if xr > Laba::CIE_EPSILON { - xr.cbrt() + ops::cbrt(xr) } else { (Laba::CIE_KAPPA * xr + 16.0) / 116.0 }; let fy = if yr > Laba::CIE_EPSILON { - yr.cbrt() + ops::cbrt(yr) } else { (Laba::CIE_KAPPA * yr + 16.0) / 116.0 }; let fz = if yr > Laba::CIE_EPSILON { - zr.cbrt() + ops::cbrt(zr) } else { (Laba::CIE_KAPPA * zr + 16.0) / 116.0 }; diff --git a/crates/bevy_color/src/lcha.rs b/crates/bevy_color/src/lcha.rs index e372ff492a..f1437d3496 100644 --- a/crates/bevy_color/src/lcha.rs +++ b/crates/bevy_color/src/lcha.rs @@ -2,7 +2,7 @@ use crate::{ Alpha, ColorToComponents, Gray, Hue, Laba, LinearRgba, Luminance, Mix, Srgba, StandardColor, Xyza, }; -use bevy_math::{Vec3, Vec4}; +use bevy_math::{ops, Vec3, Vec4}; #[cfg(feature = "bevy_reflect")] use bevy_reflect::prelude::*; @@ -257,8 +257,9 @@ impl From for Laba { ) -> Self { // Based on http://www.brucelindbloom.com/index.html?Eqn_LCH_to_Lab.html let l = lightness; - let a = chroma * hue.to_radians().cos(); - let b = chroma * hue.to_radians().sin(); + let (sin, cos) = ops::sin_cos(hue.to_radians()); + let a = chroma * cos; + let b = chroma * sin; Laba::new(l, a, b, alpha) } @@ -274,9 +275,9 @@ impl From for Lcha { }: Laba, ) -> Self { // Based on http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html - let c = (a.powf(2.0) + b.powf(2.0)).sqrt(); + let c = ops::hypot(a, b); let h = { - let h = b.to_radians().atan2(a.to_radians()).to_degrees(); + let h = ops::atan2(b.to_radians(), a.to_radians()).to_degrees(); if h < 0.0 { h + 360.0 diff --git a/crates/bevy_color/src/oklaba.rs b/crates/bevy_color/src/oklaba.rs index bf0ffdba16..0ffb35ddd3 100644 --- a/crates/bevy_color/src/oklaba.rs +++ b/crates/bevy_color/src/oklaba.rs @@ -2,7 +2,7 @@ use crate::{ color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hwba, Lcha, LinearRgba, Luminance, Mix, Srgba, StandardColor, Xyza, }; -use bevy_math::{Vec3, Vec4}; +use bevy_math::{ops, FloatPow, Vec3, Vec4}; #[cfg(feature = "bevy_reflect")] use bevy_reflect::prelude::*; @@ -156,9 +156,9 @@ impl Luminance for Oklaba { impl EuclideanDistance for Oklaba { #[inline] fn distance_squared(&self, other: &Self) -> f32 { - (self.lightness - other.lightness).powi(2) - + (self.a - other.a).powi(2) - + (self.b - other.b).powi(2) + (self.lightness - other.lightness).squared() + + (self.a - other.a).squared() + + (self.b - other.b).squared() } } @@ -229,9 +229,9 @@ impl From for Oklaba { let l = 0.4122214708 * red + 0.5363325363 * green + 0.0514459929 * blue; let m = 0.2119034982 * red + 0.6806995451 * green + 0.1073969566 * blue; let s = 0.0883024619 * red + 0.2817188376 * green + 0.6299787005 * blue; - let l_ = l.cbrt(); - let m_ = m.cbrt(); - let s_ = s.cbrt(); + let l_ = ops::cbrt(l); + let m_ = ops::cbrt(m); + let s_ = ops::cbrt(s); let l = 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_; let a = 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_; let b = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_; diff --git a/crates/bevy_color/src/oklcha.rs b/crates/bevy_color/src/oklcha.rs index 165fa0af95..70c150ed0f 100644 --- a/crates/bevy_color/src/oklcha.rs +++ b/crates/bevy_color/src/oklcha.rs @@ -2,7 +2,7 @@ use crate::{ color_difference::EuclideanDistance, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hue, Hwba, Laba, Lcha, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza, }; -use bevy_math::{Vec3, Vec4}; +use bevy_math::{ops, FloatPow, Vec3, Vec4}; #[cfg(feature = "bevy_reflect")] use bevy_reflect::prelude::*; @@ -191,9 +191,9 @@ impl Luminance for Oklcha { impl EuclideanDistance for Oklcha { #[inline] fn distance_squared(&self, other: &Self) -> f32 { - (self.lightness - other.lightness).powi(2) - + (self.chroma - other.chroma).powi(2) - + (self.hue - other.hue).powi(2) + (self.lightness - other.lightness).squared() + + (self.chroma - other.chroma).squared() + + (self.hue - other.hue).squared() } } @@ -260,8 +260,8 @@ impl From for Oklcha { alpha, }: Oklaba, ) -> Self { - let chroma = a.hypot(b); - let hue = b.atan2(a).to_degrees(); + let chroma = ops::hypot(a, b); + let hue = ops::atan2(b, a).to_degrees(); let hue = if hue < 0.0 { hue + 360.0 } else { hue }; @@ -279,8 +279,9 @@ impl From for Oklaba { }: Oklcha, ) -> Self { let l = lightness; - let a = chroma * hue.to_radians().cos(); - let b = chroma * hue.to_radians().sin(); + let (sin, cos) = ops::sin_cos(hue.to_radians()); + let a = chroma * cos; + let b = chroma * sin; Oklaba::new(l, a, b, alpha) } diff --git a/crates/bevy_color/src/srgba.rs b/crates/bevy_color/src/srgba.rs index 100d35632d..b235749a64 100644 --- a/crates/bevy_color/src/srgba.rs +++ b/crates/bevy_color/src/srgba.rs @@ -3,7 +3,7 @@ use crate::{ impl_componentwise_vector_space, Alpha, ColorToComponents, ColorToPacked, Gray, LinearRgba, Luminance, Mix, StandardColor, Xyza, }; -use bevy_math::{Vec3, Vec4}; +use bevy_math::{ops, Vec3, Vec4}; #[cfg(feature = "bevy_reflect")] use bevy_reflect::prelude::*; use thiserror::Error; @@ -215,7 +215,7 @@ impl Srgba { if value <= 0.04045 { value / 12.92 // linear falloff in dark values } else { - ((value + 0.055) / 1.055).powf(2.4) // gamma curve in other area + ops::powf((value + 0.055) / 1.055, 2.4) // gamma curve in other area } } @@ -228,7 +228,7 @@ impl Srgba { if value <= 0.0031308 { value * 12.92 // linear falloff in dark values } else { - (1.055 * value.powf(1.0 / 2.4)) - 0.055 // gamma curve in other area + (1.055 * ops::powf(value, 1.0 / 2.4)) - 0.055 // gamma curve in other area } } } diff --git a/crates/bevy_core_pipeline/src/bloom/mod.rs b/crates/bevy_core_pipeline/src/bloom/mod.rs index f3d416f44c..ff642c1f2f 100644 --- a/crates/bevy_core_pipeline/src/bloom/mod.rs +++ b/crates/bevy_core_pipeline/src/bloom/mod.rs @@ -15,7 +15,7 @@ use crate::{ use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Handle}; use bevy_ecs::{prelude::*, query::QueryItem}; -use bevy_math::UVec2; +use bevy_math::{ops, UVec2}; use bevy_render::{ camera::ExtractedCamera, diagnostic::RecordDiagnostics, @@ -462,9 +462,11 @@ fn prepare_bloom_bind_groups( /// This function can be visually previewed for all values of *mip* (normalized) with tweakable /// [`Bloom`] parameters on [Desmos graphing calculator](https://www.desmos.com/calculator/ncc8xbhzzl). fn compute_blend_factor(bloom: &Bloom, mip: f32, max_mip: f32) -> f32 { - let mut lf_boost = (1.0 - - (1.0 - (mip / max_mip)).powf(1.0 / (1.0 - bloom.low_frequency_boost_curvature))) - * bloom.low_frequency_boost; + let mut lf_boost = + (1.0 - ops::powf( + 1.0 - (mip / max_mip), + 1.0 / (1.0 - bloom.low_frequency_boost_curvature), + )) * bloom.low_frequency_boost; let high_pass_lq = 1.0 - (((mip / max_mip) - bloom.high_pass_frequency) / bloom.high_pass_frequency) .clamp(0.0, 1.0); diff --git a/crates/bevy_core_pipeline/src/dof/mod.rs b/crates/bevy_core_pipeline/src/dof/mod.rs index 162fbf9d62..ba31dfb279 100644 --- a/crates/bevy_core_pipeline/src/dof/mod.rs +++ b/crates/bevy_core_pipeline/src/dof/mod.rs @@ -26,6 +26,7 @@ use bevy_ecs::{ system::{lifetimeless::Read, Commands, Query, Res, ResMut, Resource}, world::{FromWorld, World}, }; +use bevy_math::ops; use bevy_reflect::{prelude::ReflectDefault, Reflect}; use bevy_render::{ camera::{PhysicalCameraParameters, Projection}, @@ -848,7 +849,7 @@ fn extract_depth_of_field_settings( /// /// See . pub fn calculate_focal_length(sensor_height: f32, fov: f32) -> f32 { - 0.5 * sensor_height / f32::tan(0.5 * fov) + 0.5 * sensor_height / ops::tan(0.5 * fov) } impl DepthOfFieldPipelines { diff --git a/crates/bevy_ecs/src/query/iter.rs b/crates/bevy_ecs/src/query/iter.rs index 90749bcee9..c3faa4d50e 100644 --- a/crates/bevy_ecs/src/query/iter.rs +++ b/crates/bevy_ecs/src/query/iter.rs @@ -146,7 +146,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> { let range = range.unwrap_or(0..table.entity_count()); accum = - // SAFETY: + // SAFETY: // - The fetched table matches both D and F // - caller ensures `range` is within `[0, table.entity_count)` // - The if block ensures that the query iteration is dense @@ -2083,7 +2083,7 @@ mod tests { let mut query = world.query::<&Sparse>(); let mut iter = query.iter(&world); println!( - "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", + "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", iter.cursor.archetype_entities.len(), iter.cursor.table_entities.len(), iter.cursor.current_len, @@ -2091,7 +2091,7 @@ mod tests { ); _ = iter.next(); println!( - "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", + "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", iter.cursor.archetype_entities.len(), iter.cursor.table_entities.len(), iter.cursor.current_len, @@ -2108,7 +2108,7 @@ mod tests { let mut query = world.query::<(&A, &Sparse)>(); let mut iter = query.iter(&world); println!( - "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", + "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", iter.cursor.archetype_entities.len(), iter.cursor.table_entities.len(), iter.cursor.current_len, @@ -2116,7 +2116,7 @@ mod tests { ); _ = iter.next(); println!( - "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", + "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", iter.cursor.archetype_entities.len(), iter.cursor.table_entities.len(), iter.cursor.current_len, @@ -2136,7 +2136,7 @@ mod tests { let mut query = world.query::<(&A, &Sparse)>(); let mut iter = query.iter(&world); println!( - "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", + "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", iter.cursor.archetype_entities.len(), iter.cursor.table_entities.len(), iter.cursor.current_len, @@ -2145,7 +2145,7 @@ mod tests { assert!(iter.cursor.table_entities.len() | iter.cursor.archetype_entities.len() == 0); _ = iter.next(); println!( - "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", + "after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", iter.cursor.archetype_entities.len(), iter.cursor.table_entities.len(), iter.cursor.current_len, diff --git a/crates/bevy_gizmos/src/arcs.rs b/crates/bevy_gizmos/src/arcs.rs index 7164a6e79f..c3b96f75dc 100644 --- a/crates/bevy_gizmos/src/arcs.rs +++ b/crates/bevy_gizmos/src/arcs.rs @@ -114,8 +114,7 @@ fn arc_2d_inner(arc_angle: f32, radius: f32, resolution: u32) -> impl Iterator impl Iterator { (0..resolution + 1).map(move |i| { let angle = i as f32 * TAU / resolution as f32; - let (x, y) = angle.sin_cos(); + let (x, y) = ops::sin_cos(angle); Vec2::new(x, y) * half_size }) } diff --git a/crates/bevy_gizmos/src/grid.rs b/crates/bevy_gizmos/src/grid.rs index 8c387fa349..7e637c54e1 100644 --- a/crates/bevy_gizmos/src/grid.rs +++ b/crates/bevy_gizmos/src/grid.rs @@ -6,7 +6,7 @@ use crate::prelude::{GizmoConfigGroup, Gizmos}; use bevy_color::Color; use bevy_math::Vec3Swizzles; -use bevy_math::{Isometry2d, Isometry3d, Quat, UVec2, UVec3, Vec2, Vec3}; +use bevy_math::{ops, Isometry2d, Isometry3d, Quat, UVec2, UVec3, Vec2, Vec3}; /// A builder returned by [`Gizmos::grid_3d`] pub struct GridBuilder3d<'a, 'w, 's, Config, Clear> @@ -374,7 +374,7 @@ fn draw_grid( } // Offset between two adjacent grid cells along the x/y-axis and accounting for skew. - let skew_tan = Vec3::from(skew.to_array().map(f32::tan)); + let skew_tan = Vec3::from(skew.to_array().map(ops::tan)); let dx = or_zero( cell_count.x != 0, spacing.x * Vec3::new(1., skew_tan.y, skew_tan.z), diff --git a/crates/bevy_gizmos/src/light.rs b/crates/bevy_gizmos/src/light.rs index 3e193e578e..0debc8238c 100644 --- a/crates/bevy_gizmos/src/light.rs +++ b/crates/bevy_gizmos/src/light.rs @@ -18,6 +18,7 @@ use bevy_ecs::{ system::{Query, Res}, }; use bevy_math::{ + ops, primitives::{Cone, Sphere}, Isometry3d, Quat, Vec3, }; @@ -78,12 +79,12 @@ fn spot_light_gizmo( // Offset the tip of the cone to the light position. for angle in [spot_light.inner_angle, spot_light.outer_angle] { - let height = spot_light.range * angle.cos(); + let height = spot_light.range * ops::cos(angle); let position = translation + rotation * Vec3::NEG_Z * height / 2.0; gizmos .primitive_3d( &Cone { - radius: spot_light.range * angle.sin(), + radius: spot_light.range * ops::sin(angle), height, }, Isometry3d::new(position, rotation * Quat::from_rotation_x(PI / 2.0)), diff --git a/crates/bevy_gizmos/src/primitives/helpers.rs b/crates/bevy_gizmos/src/primitives/helpers.rs index 864c4bd0dc..fa86a6ebe0 100644 --- a/crates/bevy_gizmos/src/primitives/helpers.rs +++ b/crates/bevy_gizmos/src/primitives/helpers.rs @@ -1,6 +1,6 @@ use std::f32::consts::TAU; -use bevy_math::Vec2; +use bevy_math::{ops, Vec2}; /// Calculates the `nth` coordinate of a circle. /// @@ -9,7 +9,7 @@ use bevy_math::Vec2; /// and proceeds counter-clockwise. pub(crate) fn single_circle_coordinate(radius: f32, resolution: u32, nth_point: u32) -> Vec2 { let angle = nth_point as f32 * TAU / resolution as f32; - let (x, y) = angle.sin_cos(); + let (x, y) = ops::sin_cos(angle); Vec2::new(x, y) * radius } diff --git a/crates/bevy_math/src/bounding/bounded2d/mod.rs b/crates/bevy_math/src/bounding/bounded2d/mod.rs index 1fdf6c75b0..8db21c94ca 100644 --- a/crates/bevy_math/src/bounding/bounded2d/mod.rs +++ b/crates/bevy_math/src/bounding/bounded2d/mod.rs @@ -2,9 +2,8 @@ mod primitive_impls; use super::{BoundingVolume, IntersectsVolume}; use crate::{ - ops::FloatPow, prelude::{Mat2, Rot2, Vec2}, - Isometry2d, + FloatPow, Isometry2d, }; #[cfg(feature = "bevy_reflect")] diff --git a/crates/bevy_math/src/lib.rs b/crates/bevy_math/src/lib.rs index 70df008694..1020cb114c 100644 --- a/crates/bevy_math/src/lib.rs +++ b/crates/bevy_math/src/lib.rs @@ -21,7 +21,7 @@ pub mod curve; mod direction; mod float_ord; mod isometry; -mod ops; +pub mod ops; pub mod primitives; mod ray; mod rects; @@ -36,7 +36,7 @@ pub use common_traits::*; pub use direction::*; pub use float_ord::*; pub use isometry::{Isometry2d, Isometry3d}; -pub use ops::*; +pub use ops::FloatPow; pub use ray::{Ray2d, Ray3d}; pub use rects::*; pub use rotation2d::Rot2; @@ -59,6 +59,7 @@ pub mod prelude { }, curve::*, direction::{Dir2, Dir3, Dir3A}, + ops, primitives::*, BVec2, BVec3, BVec4, EulerRot, FloatExt, IRect, IVec2, IVec3, IVec4, Isometry2d, Isometry3d, Mat2, Mat3, Mat4, Quat, Ray2d, Ray3d, Rect, Rot2, StableInterpolate, URect, diff --git a/crates/bevy_math/src/ops.rs b/crates/bevy_math/src/ops.rs index 9a40e8434e..cee52df323 100644 --- a/crates/bevy_math/src/ops.rs +++ b/crates/bevy_math/src/ops.rs @@ -445,6 +445,7 @@ mod libm_ops { #[cfg(feature = "libm")] pub use libm_ops::*; + #[cfg(not(feature = "libm"))] pub use std_ops::*; diff --git a/crates/bevy_pbr/src/cluster/assign.rs b/crates/bevy_pbr/src/cluster/assign.rs index f2a6cdc3ae..8e358a29b9 100644 --- a/crates/bevy_pbr/src/cluster/assign.rs +++ b/crates/bevy_pbr/src/cluster/assign.rs @@ -4,7 +4,7 @@ use bevy_ecs::{ entity::Entity, system::{Commands, Local, Query, Res, ResMut}, }; -use bevy_math::{Mat4, UVec3, Vec2, Vec3, Vec3A, Vec3Swizzles as _, Vec4, Vec4Swizzles as _}; +use bevy_math::{ops, Mat4, UVec3, Vec2, Vec3, Vec3A, Vec3Swizzles as _, Vec4, Vec4Swizzles as _}; use bevy_render::{ camera::Camera, primitives::{Aabb, Frustum, HalfSpace, Sphere}, @@ -484,7 +484,7 @@ pub(crate) fn assign_objects_to_clusters( radius: clusterable_object_sphere.radius * view_from_world_scale_max, }; let spot_light_dir_sin_cos = clusterable_object.spot_light_angle.map(|angle| { - let (angle_sin, angle_cos) = angle.sin_cos(); + let (angle_sin, angle_cos) = ops::sin_cos(angle); ( (view_from_world * clusterable_object.transform.back().extend(0.0)) .truncate() @@ -723,14 +723,18 @@ fn compute_aabb_for_cluster( let cluster_near = if ijk.z == 0.0 { 0.0 } else { - -z_near * z_far_over_z_near.powf((ijk.z - 1.0) / (cluster_dimensions.z - 1) as f32) + -z_near + * ops::powf( + z_far_over_z_near, + (ijk.z - 1.0) / (cluster_dimensions.z - 1) as f32, + ) }; // NOTE: This could be simplified to: // cluster_far = cluster_near * z_far_over_z_near; let cluster_far = if cluster_dimensions.z == 1 { -z_far } else { - -z_near * z_far_over_z_near.powf(ijk.z / (cluster_dimensions.z - 1) as f32) + -z_near * ops::powf(z_far_over_z_near, ijk.z / (cluster_dimensions.z - 1) as f32) }; // Calculate the four intersection points of the min and max points with the cluster near and far planes @@ -762,7 +766,7 @@ fn z_slice_to_view_z( if z_slice == 0 { 0.0 } else { - -near * (far / near).powf((z_slice - 1) as f32 / (z_slices - 1) as f32) + -near * ops::powf(far / near, (z_slice - 1) as f32 / (z_slices - 1) as f32) } } @@ -900,7 +904,7 @@ fn view_z_to_z_slice( ((view_z - cluster_factors.x) * cluster_factors.y).floor() as u32 } else { // NOTE: had to use -view_z to make it positive else log(negative) is nan - ((-view_z).ln() * cluster_factors.x - cluster_factors.y + 1.0) as u32 + (ops::ln(-view_z) * cluster_factors.x - cluster_factors.y + 1.0) as u32 }; // NOTE: We use min as we may limit the far z plane used for clustering to be closer than // the furthest thing being drawn. This means that we need to limit to the maximum cluster. diff --git a/crates/bevy_pbr/src/fog.rs b/crates/bevy_pbr/src/fog.rs index 10682e09be..5f4738d619 100644 --- a/crates/bevy_pbr/src/fog.rs +++ b/crates/bevy_pbr/src/fog.rs @@ -1,6 +1,6 @@ use bevy_color::{Color, ColorToComponents, LinearRgba}; use bevy_ecs::prelude::*; -use bevy_math::Vec3; +use bevy_math::{ops, Vec3}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{extract_component::ExtractComponent, prelude::Camera}; @@ -207,7 +207,7 @@ pub enum FogFalloff { /// The fog intensity for a given point in the scene is determined by the following formula: /// /// ```text - /// let fog_intensity = 1.0 - 1.0 / (distance * density).powi(2).exp(); + /// let fog_intensity = 1.0 - 1.0 / (distance * density).squared().exp(); /// ``` /// /// @@ -419,15 +419,15 @@ impl FogFalloff { // Values are subtracted from 1.0 here to preserve the intuitive/artistic meaning of // colors, since they're later subtracted. (e.g. by giving a blue extinction color, you // get blue and _not_ yellow results) - (1.0 - r_e).powf(E), - (1.0 - g_e).powf(E), - (1.0 - b_e).powf(E), + ops::powf(1.0 - r_e, E), + ops::powf(1.0 - g_e, E), + ops::powf(1.0 - b_e, E), ) * FogFalloff::koschmieder(visibility, contrast_threshold) - * a_e.powf(E), + * ops::powf(a_e, E), - inscattering: Vec3::new(r_i.powf(E), g_i.powf(E), b_i.powf(E)) + inscattering: Vec3::new(ops::powf(r_i, E), ops::powf(g_i, E), ops::powf(b_i, E)) * FogFalloff::koschmieder(visibility, contrast_threshold) - * a_i.powf(E), + * ops::powf(a_i, E), } } @@ -462,7 +462,7 @@ impl FogFalloff { /// - /// - pub fn koschmieder(v: f32, c_t: f32) -> f32 { - -c_t.ln() / v + -ops::ln(c_t) / v } } diff --git a/crates/bevy_pbr/src/light/mod.rs b/crates/bevy_pbr/src/light/mod.rs index ab9410254b..9eed09b172 100644 --- a/crates/bevy_pbr/src/light/mod.rs +++ b/crates/bevy_pbr/src/light/mod.rs @@ -2,7 +2,7 @@ use std::ops::DerefMut; use bevy_ecs::entity::EntityHashMap; use bevy_ecs::prelude::*; -use bevy_math::{Mat4, Vec3A, Vec4}; +use bevy_math::{ops, Mat4, Vec3A, Vec4}; use bevy_reflect::prelude::*; use bevy_render::{ camera::{Camera, CameraProjection}, @@ -154,9 +154,12 @@ fn calculate_cascade_bounds( if num_cascades == 1 { return vec![shadow_maximum_distance]; } - let base = (shadow_maximum_distance / nearest_bound).powf(1.0 / (num_cascades - 1) as f32); + let base = ops::powf( + shadow_maximum_distance / nearest_bound, + 1.0 / (num_cascades - 1) as f32, + ); (0..num_cascades) - .map(|i| nearest_bound * base.powf(i as f32)) + .map(|i| nearest_bound * ops::powf(base, i as f32)) .collect() } diff --git a/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs b/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs index 3f2b8883e7..e05956fc80 100644 --- a/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs +++ b/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs @@ -9,6 +9,7 @@ use bevy_ecs::{ query::QueryState, world::{FromWorld, World}, }; +use bevy_math::ops; use bevy_render::{ camera::ExtractedCamera, render_graph::{Node, NodeRunError, RenderGraphContext}, @@ -101,10 +102,8 @@ impl Node for MeshletVisibilityBufferRasterPassNode { .first_node .fetch_and(false, Ordering::SeqCst); - let thread_per_cluster_workgroups = - (meshlet_view_resources.scene_cluster_count.div_ceil(128) as f32) - .cbrt() - .ceil() as u32; + let div_ceil = meshlet_view_resources.scene_cluster_count.div_ceil(128); + let thread_per_cluster_workgroups = ops::cbrt(div_ceil as f32).ceil() as u32; render_context .command_encoder() diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index 916a1f098c..9e4a1c920b 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -1,6 +1,6 @@ use bevy_asset::Asset; use bevy_color::{Alpha, ColorToComponents}; -use bevy_math::{vec2, Affine2, Affine3, Mat2, Mat3, Vec2, Vec3, Vec4}; +use bevy_math::{Affine2, Affine3, Mat2, Mat3, Vec2, Vec3, Vec4}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ mesh::MeshVertexBufferLayoutRef, render_asset::RenderAssets, render_resource::*, @@ -1068,10 +1068,7 @@ impl AsBindGroupShaderType for StandardMaterial { emissive[3] = self.emissive_exposure_weight; // Doing this up front saves having to do this repeatedly in the fragment shader. - let anisotropy_rotation = vec2( - self.anisotropy_rotation.cos(), - self.anisotropy_rotation.sin(), - ); + let anisotropy_rotation = Vec2::from_angle(self.anisotropy_rotation); StandardMaterialUniform { base_color: LinearRgba::from(self.base_color).to_vec4(), diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 6bf1013295..216fd93e78 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -4,7 +4,7 @@ use bevy_core_pipeline::core_3d::{Camera3d, CORE_3D_DEPTH_FORMAT}; use bevy_ecs::entity::EntityHashSet; use bevy_ecs::prelude::*; use bevy_ecs::{entity::EntityHashMap, system::lifetimeless::Read}; -use bevy_math::{Mat4, UVec4, Vec2, Vec3, Vec3Swizzles, Vec4, Vec4Swizzles}; +use bevy_math::{ops, Mat4, UVec4, Vec2, Vec3, Vec3Swizzles, Vec4, Vec4Swizzles}; use bevy_render::{ diagnostic::RecordDiagnostics, mesh::RenderMesh, @@ -283,7 +283,7 @@ pub fn extract_lights( // However, since exclusive access to the main world in extract is ill-advised, we just clone here. let render_visible_entities = visible_entities.clone(); let texel_size = - 2.0 * spot_light.outer_angle.tan() / directional_light_shadow_map.size as f32; + 2.0 * ops::tan(spot_light.outer_angle) / directional_light_shadow_map.size as f32; spot_lights_values.push(( entity, @@ -467,10 +467,10 @@ pub fn calculate_cluster_factors( if is_orthographic { Vec2::new(-near, z_slices / (-far - -near)) } else { - let z_slices_of_ln_zfar_over_znear = (z_slices - 1.0) / (far / near).ln(); + let z_slices_of_ln_zfar_over_znear = (z_slices - 1.0) / ops::ln(far / near); Vec2::new( z_slices_of_ln_zfar_over_znear, - near.ln() * z_slices_of_ln_zfar_over_znear, + ops::ln(near) * z_slices_of_ln_zfar_over_znear, ) } } @@ -692,14 +692,14 @@ pub fn prepare_lights( flags |= PointLightFlags::SPOT_LIGHT_Y_NEGATIVE; } - let cos_outer = outer.cos(); - let spot_scale = 1.0 / f32::max(inner.cos() - cos_outer, 1e-4); + let cos_outer = ops::cos(outer); + let spot_scale = 1.0 / f32::max(ops::cos(inner) - cos_outer, 1e-4); let spot_offset = -cos_outer * spot_scale; ( // For spot lights: the direction (x,z), spot_scale and spot_offset light_direction.xz().extend(spot_scale).extend(spot_offset), - outer.tan(), + ops::tan(outer), ) } None => { diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 105b987ed1..654254fd9b 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -24,7 +24,7 @@ use bevy_ecs::{ reflect::ReflectComponent, system::{Commands, Query, Res, ResMut, Resource}, }; -use bevy_math::{vec2, Dir3, Mat4, Ray3d, Rect, URect, UVec2, UVec4, Vec2, Vec3}; +use bevy_math::{ops, vec2, Dir3, Mat4, Ray3d, Rect, URect, UVec2, UVec4, Vec2, Vec3}; use bevy_reflect::prelude::*; use bevy_render_macros::ExtractComponent; use bevy_transform::components::GlobalTransform; @@ -136,7 +136,7 @@ impl Exposure { /// #[inline] pub fn exposure(&self) -> f32 { - (-self.ev100).exp2() / 1.2 + ops::exp2(-self.ev100) / 1.2 } } @@ -170,9 +170,10 @@ pub struct PhysicalCameraParameters { impl PhysicalCameraParameters { /// Calculate the [EV100](https://en.wikipedia.org/wiki/Exposure_value). pub fn ev100(&self) -> f32 { - (self.aperture_f_stops * self.aperture_f_stops * 100.0 - / (self.shutter_speed_s * self.sensitivity_iso)) - .log2() + ops::log2( + self.aperture_f_stops * self.aperture_f_stops * 100.0 + / (self.shutter_speed_s * self.sensitivity_iso), + ) } } diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index db5034b286..3a08506f37 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -5,7 +5,7 @@ use crate::primitives::Frustum; use crate::view::VisibilitySystems; use bevy_app::{App, Plugin, PostStartup, PostUpdate}; use bevy_ecs::prelude::*; -use bevy_math::{AspectRatio, Mat4, Rect, Vec2, Vec3A}; +use bevy_math::{ops, AspectRatio, Mat4, Rect, Vec2, Vec3A}; use bevy_reflect::{ std_traits::ReflectDefault, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectSerialize, }; @@ -200,7 +200,7 @@ impl CameraProjection for PerspectiveProjection { } fn get_frustum_corners(&self, z_near: f32, z_far: f32) -> [Vec3A; 8] { - let tan_half_fov = (self.fov / 2.).tan(); + let tan_half_fov = ops::tan(self.fov / 2.); let a = z_near.abs() * tan_half_fov; let b = z_far.abs() * tan_half_fov; let aspect_ratio = self.aspect_ratio; diff --git a/crates/bevy_render/src/mesh/primitives/dim2.rs b/crates/bevy_render/src/mesh/primitives/dim2.rs index 3b2d42b6c9..a7183f99f2 100644 --- a/crates/bevy_render/src/mesh/primitives/dim2.rs +++ b/crates/bevy_render/src/mesh/primitives/dim2.rs @@ -7,6 +7,7 @@ use crate::{ use super::{Extrudable, MeshBuilder, Meshable}; use bevy_math::{ + ops, primitives::{ Annulus, Capsule2d, Circle, CircularSector, CircularSegment, Ellipse, Rectangle, RegularPolygon, Rhombus, Triangle2d, Triangle3d, WindingOrder, @@ -217,7 +218,7 @@ impl MeshBuilder for CircularSectorMeshBuilder { impl Extrudable for CircularSectorMeshBuilder { fn perimeter(&self) -> Vec { - let (sin, cos) = self.sector.arc.half_angle.sin_cos(); + let (sin, cos) = ops::sin_cos(self.sector.arc.half_angle); let first_normal = Vec2::new(sin, cos); let last_normal = Vec2::new(-sin, cos); vec![ @@ -363,7 +364,7 @@ impl MeshBuilder for CircularSegmentMeshBuilder { impl Extrudable for CircularSegmentMeshBuilder { fn perimeter(&self) -> Vec { - let (sin, cos) = self.segment.arc.half_angle.sin_cos(); + let (sin, cos) = ops::sin_cos(self.segment.arc.half_angle); let first_normal = Vec2::new(sin, cos); let last_normal = Vec2::new(-sin, cos); vec![ @@ -493,7 +494,7 @@ impl MeshBuilder for EllipseMeshBuilder { for i in 0..self.resolution { // Compute vertex position at angle theta let theta = start_angle + i as f32 * step; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); let x = cos * self.ellipse.half_size.x; let y = sin * self.ellipse.half_size.y; @@ -599,7 +600,7 @@ impl MeshBuilder for AnnulusMeshBuilder { let step = std::f32::consts::TAU / self.resolution as f32; for i in 0..=self.resolution { let theta = start_angle + (i % self.resolution) as f32 * step; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); let inner_pos = [cos * inner_radius, sin * inner_radius, 0.]; let outer_pos = [cos * outer_radius, sin * outer_radius, 0.]; positions.push(inner_pos); @@ -915,7 +916,7 @@ impl MeshBuilder for Capsule2dMeshBuilder { for i in 0..resolution { // Compute vertex position at angle theta let theta = start_angle + i as f32 * step; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); let (x, y) = (cos * radius, sin * radius + self.capsule.half_length); positions.push([x, y, 0.0]); @@ -934,7 +935,7 @@ impl MeshBuilder for Capsule2dMeshBuilder { for i in resolution..vertex_count { // Compute vertex position at angle theta let theta = start_angle + i as f32 * step; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); let (x, y) = (cos * radius, sin * radius - self.capsule.half_length); positions.push([x, y, 0.0]); diff --git a/crates/bevy_render/src/mesh/primitives/dim3/capsule.rs b/crates/bevy_render/src/mesh/primitives/dim3/capsule.rs index 3c85fc629b..eeea5e906f 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/capsule.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/capsule.rs @@ -2,7 +2,7 @@ use crate::{ mesh::{Indices, Mesh, MeshBuilder, Meshable}, render_asset::RenderAssetUsages, }; -use bevy_math::{primitives::Capsule3d, Vec2, Vec3}; +use bevy_math::{ops, primitives::Capsule3d, Vec2, Vec3}; use wgpu::PrimitiveTopology; /// Manner in which UV coordinates are distributed vertically. @@ -158,11 +158,8 @@ impl MeshBuilder for Capsule3dMeshBuilder { let s_texture_polar = 1.0 - ((jf + 0.5) * to_tex_horizontal); let theta = jf * to_theta; - let cos_theta = theta.cos(); - let sin_theta = theta.sin(); - - theta_cartesian[j] = Vec2::new(cos_theta, sin_theta); - rho_theta_cartesian[j] = Vec2::new(radius * cos_theta, radius * sin_theta); + theta_cartesian[j] = Vec2::from_angle(theta); + rho_theta_cartesian[j] = radius * theta_cartesian[j]; // North. vs[j] = Vec3::new(0.0, summit, 0.0); @@ -205,8 +202,7 @@ impl MeshBuilder for Capsule3dMeshBuilder { let phi = ip1f * to_phi; // For coordinates. - let cos_phi_south = phi.cos(); - let sin_phi_south = phi.sin(); + let (sin_phi_south, cos_phi_south) = ops::sin_cos(phi); // Symmetrical hemispheres mean cosine and sine only needs // to be calculated once. diff --git a/crates/bevy_render/src/mesh/primitives/dim3/cone.rs b/crates/bevy_render/src/mesh/primitives/dim3/cone.rs index fb201bd5ef..7ad5394a3c 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/cone.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/cone.rs @@ -1,4 +1,4 @@ -use bevy_math::{primitives::Cone, Vec3}; +use bevy_math::{ops, primitives::Cone, Vec3}; use wgpu::PrimitiveTopology; use crate::{ @@ -116,7 +116,7 @@ impl MeshBuilder for ConeMeshBuilder { // Add vertices for the bottom of the lateral surface. for segment in 0..self.resolution { let theta = segment as f32 * step_theta; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); // The vertex normal perpendicular to the side let normal = Vec3::new(cos, normal_slope, sin) * normalization_factor; @@ -142,7 +142,7 @@ impl MeshBuilder for ConeMeshBuilder { // Add base vertices. for i in 0..self.resolution { let theta = i as f32 * step_theta; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); positions.push([cos * self.cone.radius, -half_height, sin * self.cone.radius]); normals.push([0.0, -1.0, 0.0]); diff --git a/crates/bevy_render/src/mesh/primitives/dim3/conical_frustum.rs b/crates/bevy_render/src/mesh/primitives/dim3/conical_frustum.rs index a7d09778a9..3b7da0bea5 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/conical_frustum.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/conical_frustum.rs @@ -2,7 +2,7 @@ use crate::{ mesh::{Indices, Mesh, MeshBuilder, Meshable}, render_asset::RenderAssetUsages, }; -use bevy_math::{primitives::ConicalFrustum, Vec3}; +use bevy_math::{ops, primitives::ConicalFrustum, Vec3}; use wgpu::PrimitiveTopology; /// A builder used for creating a [`Mesh`] with a [`ConicalFrustum`] shape. @@ -94,7 +94,7 @@ impl MeshBuilder for ConicalFrustumMeshBuilder { for segment in 0..=self.resolution { let theta = segment as f32 * step_theta; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); positions.push([radius * cos, y, radius * sin]); normals.push( @@ -137,7 +137,7 @@ impl MeshBuilder for ConicalFrustumMeshBuilder { for i in 0..self.resolution { let theta = i as f32 * step_theta; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); positions.push([cos * radius, y, sin * radius]); normals.push([0.0, normal_y, 0.0]); diff --git a/crates/bevy_render/src/mesh/primitives/dim3/cylinder.rs b/crates/bevy_render/src/mesh/primitives/dim3/cylinder.rs index 4b53f9dd34..c6522d98c7 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/cylinder.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/cylinder.rs @@ -1,4 +1,4 @@ -use bevy_math::primitives::Cylinder; +use bevy_math::{ops, primitives::Cylinder}; use wgpu::PrimitiveTopology; use crate::{ @@ -122,7 +122,7 @@ impl MeshBuilder for CylinderMeshBuilder { for segment in 0..=resolution { let theta = segment as f32 * step_theta; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); positions.push([self.cylinder.radius * cos, y, self.cylinder.radius * sin]); normals.push([cos, 0., sin]); @@ -163,7 +163,7 @@ impl MeshBuilder for CylinderMeshBuilder { for i in 0..self.resolution { let theta = i as f32 * step_theta; - let (sin, cos) = theta.sin_cos(); + let (sin, cos) = ops::sin_cos(theta); positions.push([cos * self.cylinder.radius, y, sin * self.cylinder.radius]); normals.push([0.0, normal_y, 0.0]); diff --git a/crates/bevy_render/src/mesh/primitives/dim3/sphere.rs b/crates/bevy_render/src/mesh/primitives/dim3/sphere.rs index 883afe16b1..0d2e4e84d8 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/sphere.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/sphere.rs @@ -4,7 +4,7 @@ use crate::{ mesh::{Indices, Mesh, MeshBuilder, Meshable}, render_asset::RenderAssetUsages, }; -use bevy_math::primitives::Sphere; +use bevy_math::{ops, primitives::Sphere}; use hexasphere::shapes::IcoSphere; use thiserror::Error; use wgpu::PrimitiveTopology; @@ -120,8 +120,8 @@ impl SphereMeshBuilder { }); } let generated = IcoSphere::new(subdivisions as usize, |point| { - let inclination = point.y.acos(); - let azimuth = point.z.atan2(point.x); + let inclination = ops::acos(point.y); + let azimuth = ops::atan2(point.z, point.x); let norm_inclination = inclination / PI; let norm_azimuth = 0.5 - (azimuth / std::f32::consts::TAU); @@ -183,13 +183,13 @@ impl SphereMeshBuilder { for i in 0..stacks + 1 { let stack_angle = PI / 2. - (i as f32) * stack_step; - let xy = self.sphere.radius * stack_angle.cos(); - let z = self.sphere.radius * stack_angle.sin(); + let xy = self.sphere.radius * ops::cos(stack_angle); + let z = self.sphere.radius * ops::sin(stack_angle); for j in 0..sectors + 1 { let sector_angle = (j as f32) * sector_step; - let x = xy * sector_angle.cos(); - let y = xy * sector_angle.sin(); + let x = xy * ops::cos(sector_angle); + let y = xy * ops::sin(sector_angle); vertices.push([x, y, z]); normals.push([x * length_inv, y * length_inv, z * length_inv]); diff --git a/crates/bevy_render/src/mesh/primitives/dim3/torus.rs b/crates/bevy_render/src/mesh/primitives/dim3/torus.rs index ec45f5f382..0dcbd68353 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/torus.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/torus.rs @@ -1,4 +1,4 @@ -use bevy_math::{primitives::Torus, Vec3}; +use bevy_math::{ops, primitives::Torus, Vec3}; use std::ops::RangeInclusive; use wgpu::PrimitiveTopology; @@ -98,17 +98,20 @@ impl MeshBuilder for TorusMeshBuilder { for side in 0..=self.minor_resolution { let phi = side_stride * side as f32; + let (sin_theta, cos_theta) = ops::sin_cos(theta); + let (sin_phi, cos_phi) = ops::sin_cos(phi); + let radius = self.torus.major_radius + self.torus.minor_radius * cos_phi; let position = Vec3::new( - theta.cos() * (self.torus.major_radius + self.torus.minor_radius * phi.cos()), - self.torus.minor_radius * phi.sin(), - theta.sin() * (self.torus.major_radius + self.torus.minor_radius * phi.cos()), + cos_theta * radius, + self.torus.minor_radius * sin_phi, + sin_theta * radius, ); let center = Vec3::new( - self.torus.major_radius * theta.cos(), + self.torus.major_radius * cos_theta, 0., - self.torus.major_radius * theta.sin(), + self.torus.major_radius * sin_theta, ); let normal = (position - center).normalize(); diff --git a/examples/2d/bounding_2d.rs b/examples/2d/bounding_2d.rs index 625a11aec6..1690a4827a 100644 --- a/examples/2d/bounding_2d.rs +++ b/examples/2d/bounding_2d.rs @@ -2,7 +2,7 @@ use bevy::{ color::palettes::css::*, - math::{bounding::*, Isometry2d}, + math::{bounding::*, ops, Isometry2d}, prelude::*, }; @@ -302,8 +302,11 @@ fn draw_ray(gizmos: &mut Gizmos, ray: &RayCast2d) { } fn get_and_draw_ray(gizmos: &mut Gizmos, time: &Time) -> RayCast2d { - let ray = Vec2::new(time.elapsed_seconds().cos(), time.elapsed_seconds().sin()); - let dist = 150. + (0.5 * time.elapsed_seconds()).sin().abs() * 500.; + let ray = Vec2::new( + ops::cos(time.elapsed_seconds()), + ops::sin(time.elapsed_seconds()), + ); + let dist = 150. + ops::sin(0.5 * time.elapsed_seconds()).abs() * 500.; let aabb_ray = Ray2d { origin: ray * 250., @@ -399,8 +402,8 @@ fn bounding_circle_cast_system( } fn get_intersection_position(time: &Time) -> Vec2 { - let x = (0.8 * time.elapsed_seconds()).cos() * 250.; - let y = (0.4 * time.elapsed_seconds()).sin() * 100.; + let x = ops::cos(0.8 * time.elapsed_seconds()) * 250.; + let y = ops::sin(0.4 * time.elapsed_seconds()) * 100.; Vec2::new(x, y) } diff --git a/examples/2d/mesh2d_manual.rs b/examples/2d/mesh2d_manual.rs index 4361c17b13..35380ec3e2 100644 --- a/examples/2d/mesh2d_manual.rs +++ b/examples/2d/mesh2d_manual.rs @@ -9,7 +9,7 @@ use bevy::{ color::palettes::basic::YELLOW, core_pipeline::core_2d::{Transparent2d, CORE_2D_DEPTH_FORMAT}, ecs::entity::EntityHashMap, - math::FloatOrd, + math::{ops, FloatOrd}, prelude::*, render::{ mesh::{Indices, MeshVertexAttribute, RenderMesh}, @@ -80,7 +80,7 @@ fn star( // The radius of inner vertices (even indices) is 100. For outer vertices (odd indices) it's 200. let r = (1 - i % 2) as f32 * 100.0 + 100.0; // Add the vertex position. - v_pos.push([r * a.sin(), r * a.cos(), 0.0]); + v_pos.push([r * ops::sin(a), r * ops::cos(a), 0.0]); } // Set the position attribute star.insert_attribute(Mesh::ATTRIBUTE_POSITION, v_pos); diff --git a/examples/2d/rotation.rs b/examples/2d/rotation.rs index 9cd944ac0c..421fd3fbd3 100644 --- a/examples/2d/rotation.rs +++ b/examples/2d/rotation.rs @@ -1,5 +1,6 @@ //! Demonstrates rotating entities in 2D using quaternions. +use bevy::math::ops; use bevy::prelude::*; const BOUNDS: Vec2 = Vec2::new(1200.0, 640.0); @@ -241,7 +242,7 @@ fn rotate_to_player_system( // limit rotation so we don't overshoot the target. We need to convert our dot product to // an angle here so we can get an angle of rotation to clamp against. - let max_angle = forward_dot_player.clamp(-1.0, 1.0).acos(); // clamp acos for safety + let max_angle = ops::acos(forward_dot_player.clamp(-1.0, 1.0)); // clamp acos for safety // calculate angle of rotation with limit let rotation_angle = diff --git a/examples/2d/text2d.rs b/examples/2d/text2d.rs index b7bfe22474..cab32980de 100644 --- a/examples/2d/text2d.rs +++ b/examples/2d/text2d.rs @@ -7,6 +7,7 @@ use bevy::{ color::palettes::css::*, + math::ops, prelude::*, sprite::Anchor, text::{BreakLineOn, TextBounds}, @@ -164,8 +165,8 @@ fn animate_translation( mut query: Query<&mut Transform, (With, With)>, ) { for mut transform in &mut query { - transform.translation.x = 100.0 * time.elapsed_seconds().sin() - 400.0; - transform.translation.y = 100.0 * time.elapsed_seconds().cos(); + transform.translation.x = 100.0 * ops::sin(time.elapsed_seconds()) - 400.0; + transform.translation.y = 100.0 * ops::cos(time.elapsed_seconds()); } } @@ -174,7 +175,7 @@ fn animate_rotation( mut query: Query<&mut Transform, (With, With)>, ) { for mut transform in &mut query { - transform.rotation = Quat::from_rotation_z(time.elapsed_seconds().cos()); + transform.rotation = Quat::from_rotation_z(ops::cos(time.elapsed_seconds())); } } @@ -185,7 +186,7 @@ fn animate_scale( // Consider changing font-size instead of scaling the transform. Scaling a Text2D will scale the // rendered quad, resulting in a pixellated look. for mut transform in &mut query { - let scale = (time.elapsed_seconds().sin() + 1.1) * 2.0; + let scale = (ops::sin(time.elapsed_seconds()) + 1.1) * 2.0; transform.scale.x = scale; transform.scale.y = scale; } diff --git a/examples/3d/anisotropy.rs b/examples/3d/anisotropy.rs index 728e792a04..40529d1445 100644 --- a/examples/3d/anisotropy.rs +++ b/examples/3d/anisotropy.rs @@ -132,7 +132,7 @@ fn animate_light( ) { let now = time.elapsed_seconds(); for mut transform in lights.iter_mut() { - transform.translation = vec3(f32::cos(now), 1.0, f32::sin(now)) * vec3(3.0, 4.0, 3.0); + transform.translation = vec3(ops::cos(now), 1.0, ops::sin(now)) * vec3(3.0, 4.0, 3.0); transform.look_at(Vec3::ZERO, Vec3::Y); } } diff --git a/examples/3d/bloom_3d.rs b/examples/3d/bloom_3d.rs index 0c483f679d..77d4365051 100644 --- a/examples/3d/bloom_3d.rs +++ b/examples/3d/bloom_3d.rs @@ -6,6 +6,7 @@ use bevy::{ bloom::{Bloom, BloomCompositeMode}, tonemapping::Tonemapping, }, + math::ops, prelude::*, }; use std::{ @@ -219,6 +220,6 @@ struct Bouncing; fn bounce_spheres(time: Res