diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 08d34fec7adbd..f0fdcad7fa55b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -222,6 +222,8 @@ jobs: with: target: wasm32-unknown-unknown - name: Check wasm + env: + RUSTFLAGS: --cfg getrandom_backend="wasm_js" run: cargo check --target wasm32-unknown-unknown build-wasm-atomics: @@ -247,7 +249,7 @@ jobs: - name: Check wasm run: cargo check --target wasm32-unknown-unknown -Z build-std=std,panic_abort env: - RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory" + RUSTFLAGS: '-C target-feature=+atomics,+bulk-memory --cfg getrandom_backend="wasm_js"' markdownlint: runs-on: ubuntu-latest diff --git a/.github/workflows/validation-jobs.yml b/.github/workflows/validation-jobs.yml index 36679408578ed..a79aa45d11715 100644 --- a/.github/workflows/validation-jobs.yml +++ b/.github/workflows/validation-jobs.yml @@ -112,6 +112,8 @@ jobs: cd ../.. - name: First Wasm build + env: + RUSTFLAGS: --cfg getrandom_backend="wasm_js" run: | cargo build --release --example testbed_ui --target wasm32-unknown-unknown diff --git a/Cargo.toml b/Cargo.toml index 9d6e9216384bc..7a796b3cbdfd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -591,8 +591,8 @@ tracing = { version = "0.1", default-features = false, optional = true } bevy_dylib = { path = "crates/bevy_dylib", version = "0.17.0-dev", default-features = false, optional = true } [dev-dependencies] -rand = "0.8.0" -rand_chacha = "0.3.1" +rand = "0.9.0" +rand_chacha = "0.9.0" ron = "0.10" flate2 = "1.0" serde = { version = "1", features = ["derive"] } @@ -627,6 +627,9 @@ smol-hyper = "0.1" ureq = { version = "3.0.8", features = ["json"] } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] +getrandom = { version = "0.3", default-features = false, features = [ + "wasm_js", +] } wasm-bindgen = { version = "0.2" } web-sys = { version = "0.3", features = ["Window"] } diff --git a/benches/Cargo.toml b/benches/Cargo.toml index 789207d8234be..ee97a06968b1c 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -29,9 +29,9 @@ bevy_platform = { path = "../crates/bevy_platform", default-features = false, fe ] } # Other crates -glam = "0.29" -rand = "0.8" -rand_chacha = "0.3" +glam = "0.30.1" +rand = "0.9" +rand_chacha = "0.9" nonmax = { version = "0.5", default-features = false } # Make `bevy_render` compile on Linux with x11 windowing. x11 vs. Wayland does not matter here diff --git a/benches/benches/bevy_ecs/observers/propagation.rs b/benches/benches/bevy_ecs/observers/propagation.rs index 808c3727d5af9..39ddccd2b0234 100644 --- a/benches/benches/bevy_ecs/observers/propagation.rs +++ b/benches/benches/bevy_ecs/observers/propagation.rs @@ -66,7 +66,7 @@ pub fn event_propagation(criterion: &mut Criterion) { struct TestEvent {} fn send_events(world: &mut World, leaves: &[Entity]) { - let target = leaves.iter().choose(&mut rand::thread_rng()).unwrap(); + let target = leaves.iter().choose(&mut rand::rng()).unwrap(); (0..N_EVENTS).for_each(|_| { world.trigger_targets(TestEvent:: {}, *target); @@ -107,7 +107,7 @@ fn add_listeners_to_hierarchy( } let mut rng = deterministic_rand(); for e in nodes.iter() { - if rng.gen_bool(DENSITY as f64 / 100.0) { + if rng.random_bool(DENSITY as f64 / 100.0) { world.entity_mut(*e).observe(empty_listener::); } } diff --git a/benches/benches/bevy_ecs/world/entity_hash.rs b/benches/benches/bevy_ecs/world/entity_hash.rs index 2f92a715b4411..36d998022614d 100644 --- a/benches/benches/bevy_ecs/world/entity_hash.rs +++ b/benches/benches/bevy_ecs/world/entity_hash.rs @@ -11,9 +11,9 @@ fn make_entity(rng: &mut impl Rng, size: usize) -> Entity { // * For ids, half are in [0, size), half are unboundedly larger. // * For generations, half are in [1, 3), half are unboundedly larger. - let x: f64 = rng.r#gen(); + let x: f64 = rng.random(); let id = -(1.0 - x).log2() * (size as f64); - let x: f64 = rng.r#gen(); + let x: f64 = rng.random(); let generation = 1.0 + -(1.0 - x).log2() * 2.0; // this is not reliable, but we're internal so a hack is ok diff --git a/benches/benches/bevy_reflect/path.rs b/benches/benches/bevy_reflect/path.rs index c0d8bfe0da732..c8c82ff6ba97e 100644 --- a/benches/benches/bevy_reflect/path.rs +++ b/benches/benches/bevy_reflect/path.rs @@ -3,7 +3,7 @@ use core::{fmt::Write, hint::black_box, str, time::Duration}; use benches::bench; use bevy_reflect::ParsedPath; use criterion::{criterion_group, BatchSize, BenchmarkId, Criterion, Throughput}; -use rand::{distributions::Uniform, Rng, SeedableRng}; +use rand::{distr::Uniform, Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; criterion_group!(benches, parse_reflect_path); @@ -18,20 +18,20 @@ fn deterministic_rand() -> ChaCha8Rng { ChaCha8Rng::seed_from_u64(42) } fn random_ident(rng: &mut ChaCha8Rng, f: &mut dyn Write) { - let between = Uniform::from(b'a'..=b'z'); - let ident_size = rng.gen_range(1..128); + let between = Uniform::new_inclusive(b'a', b'z').unwrap(); + let ident_size = rng.random_range(1..128); let ident: Vec = rng.sample_iter(between).take(ident_size).collect(); let ident = str::from_utf8(&ident).unwrap(); let _ = write!(f, "{ident}"); } fn random_index(rng: &mut ChaCha8Rng, f: &mut dyn Write) { - let index = rng.gen_range(1..128); + let index = rng.random_range(1..128); let _ = write!(f, "{index}"); } fn write_random_access(rng: &mut ChaCha8Rng, f: &mut dyn Write) { - match rng.gen_range(0..4) { + match rng.random_range(0..4) { 0 => { // Access::Field f.write_char('.').unwrap(); diff --git a/crates/bevy_color/Cargo.toml b/crates/bevy_color/Cargo.toml index 22ade1270900b..58639224eb002 100644 --- a/crates/bevy_color/Cargo.toml +++ b/crates/bevy_color/Cargo.toml @@ -21,7 +21,7 @@ serde = { version = "1.0", features = [ thiserror = { version = "2", default-features = false } derive_more = { version = "2", default-features = false, features = ["from"] } wgpu-types = { version = "25", default-features = false, optional = true } -encase = { version = "0.10", default-features = false, optional = true } +encase = { version = "0.11", default-features = false, optional = true } [features] default = ["std", "bevy_reflect", "encase"] diff --git a/crates/bevy_ecs/Cargo.toml b/crates/bevy_ecs/Cargo.toml index f0f9b782afff2..da2c0b4c9709c 100644 --- a/crates/bevy_ecs/Cargo.toml +++ b/crates/bevy_ecs/Cargo.toml @@ -131,7 +131,7 @@ concurrent-queue = { version = "2.5.0", default-features = false, features = [ ] } [dev-dependencies] -rand = "0.8" +rand = "0.9" static_assertions = "1.1.0" serde_test = "1.0" diff --git a/crates/bevy_ecs/examples/change_detection.rs b/crates/bevy_ecs/examples/change_detection.rs index 42611e57e1978..e186f9b6e3365 100644 --- a/crates/bevy_ecs/examples/change_detection.rs +++ b/crates/bevy_ecs/examples/change_detection.rs @@ -66,7 +66,7 @@ enum SimulationSystems { // The entity will start with an age of 0 frames // If an entity gets spawned, we increase the counter in the EntityCounter resource fn spawn_entities(mut commands: Commands, mut entity_counter: ResMut) { - if rand::thread_rng().gen_bool(0.6) { + if rand::rng().random_bool(0.6) { let entity_id = commands.spawn(Age::default()).id(); println!(" spawning {entity_id:?}"); entity_counter.value += 1; diff --git a/crates/bevy_ecs/examples/resources.rs b/crates/bevy_ecs/examples/resources.rs index bb079d249d147..25eddfff57209 100644 --- a/crates/bevy_ecs/examples/resources.rs +++ b/crates/bevy_ecs/examples/resources.rs @@ -37,7 +37,7 @@ struct Counter { } fn increase_counter(mut counter: ResMut) { - if rand::thread_rng().gen_bool(0.5) { + if rand::rng().random_bool(0.5) { counter.value += 1; println!(" Increased counter value"); } diff --git a/crates/bevy_encase_derive/Cargo.toml b/crates/bevy_encase_derive/Cargo.toml index 9e05bc7a853fe..d700b7d11bfa2 100644 --- a/crates/bevy_encase_derive/Cargo.toml +++ b/crates/bevy_encase_derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] bevy_macro_utils = { path = "../bevy_macro_utils", version = "0.17.0-dev" } -encase_derive_impl = "0.10" +encase_derive_impl = "0.11" [lints] workspace = true diff --git a/crates/bevy_math/Cargo.toml b/crates/bevy_math/Cargo.toml index 459ff6e90a545..02787ee528113 100644 --- a/crates/bevy_math/Cargo.toml +++ b/crates/bevy_math/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["bevy"] rust-version = "1.85.0" [dependencies] -glam = { version = "0.29.3", default-features = false, features = ["bytemuck"] } +glam = { version = "0.30.1", default-features = false, features = ["bytemuck"] } thiserror = { version = "2", default-features = false } derive_more = { version = "2", default-features = false, features = [ "from", @@ -22,8 +22,8 @@ serde = { version = "1", default-features = false, features = [ ], optional = true } libm = { version = "0.2", optional = true } approx = { version = "0.5", default-features = false, optional = true } -rand = { version = "0.8", default-features = false, optional = true } -rand_distr = { version = "0.4.3", optional = true } +rand = { version = "0.9", default-features = false, optional = true } +rand_distr = { version = "0.5", optional = true } smallvec = { version = "1", default-features = false } bevy_reflect = { path = "../bevy_reflect", version = "0.17.0-dev", default-features = false, features = [ "glam", @@ -33,11 +33,16 @@ variadics_please = "1.1" [dev-dependencies] approx = "0.5" # Supply rngs for examples and tests -rand = "0.8" -rand_chacha = "0.3" +rand = "0.9" +rand_chacha = "0.9" # Enable the approx feature when testing. bevy_math = { path = ".", default-features = false, features = ["approx"] } -glam = { version = "0.29.3", default-features = false, features = ["approx"] } +glam = { version = "0.30.1", default-features = false, features = ["approx"] } + +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +getrandom = { version = "0.3", default-features = false, features = [ + "wasm_js", +] } [features] default = ["std", "rand", "curve"] diff --git a/crates/bevy_math/src/sampling/mesh_sampling.rs b/crates/bevy_math/src/sampling/mesh_sampling.rs index 898198dea4261..f7e2d5cf7ab6b 100644 --- a/crates/bevy_math/src/sampling/mesh_sampling.rs +++ b/crates/bevy_math/src/sampling/mesh_sampling.rs @@ -6,7 +6,10 @@ use crate::{ }; use alloc::vec::Vec; use rand::Rng; -use rand_distr::{Distribution, WeightedAliasIndex, WeightedError}; +use rand_distr::{ + weighted::{Error as WeightedError, WeightedAliasIndex}, + Distribution, +}; /// A [distribution] that caches data to allow fast sampling from a collection of triangles. /// Generally used through [`sample`] or [`sample_iter`]. @@ -19,7 +22,7 @@ use rand_distr::{Distribution, WeightedAliasIndex, WeightedError}; /// ``` /// # use bevy_math::{Vec3, primitives::*}; /// # use bevy_math::sampling::mesh_sampling::UniformMeshSampler; -/// # use rand::{SeedableRng, rngs::StdRng, distributions::Distribution}; +/// # use rand::{SeedableRng, rngs::StdRng, distr::Distribution}; /// let faces = Tetrahedron::default().faces(); /// let sampler = UniformMeshSampler::try_new(faces).unwrap(); /// let rng = StdRng::seed_from_u64(8765309); diff --git a/crates/bevy_math/src/sampling/shape_sampling.rs b/crates/bevy_math/src/sampling/shape_sampling.rs index c17bc6fa76600..e40804ddbf5f4 100644 --- a/crates/bevy_math/src/sampling/shape_sampling.rs +++ b/crates/bevy_math/src/sampling/shape_sampling.rs @@ -8,7 +8,7 @@ //! # use rand::SeedableRng; //! # use rand::rngs::StdRng; //! // Get some `Rng`: -//! let rng = &mut StdRng::from_entropy(); +//! let rng = &mut StdRng::from_os_rng(); //! // Make a circle of radius 2: //! let circle = Circle::new(2.0); //! // Get a point inside this circle uniformly at random: @@ -23,9 +23,9 @@ //! # use bevy_math::{Vec2, ShapeSample}; //! # use rand::SeedableRng; //! # use rand::rngs::StdRng; -//! # use rand::distributions::Distribution; -//! # let rng1 = StdRng::from_entropy(); -//! # let rng2 = StdRng::from_entropy(); +//! # use rand::distr::Distribution; +//! # let rng1 = StdRng::from_os_rng(); +//! # let rng2 = StdRng::from_os_rng(); //! // Use a rectangle this time: //! let rectangle = Rectangle::new(1.0, 2.0); //! // Get an iterator that spits out random interior points: @@ -42,10 +42,13 @@ use core::f32::consts::{PI, TAU}; use crate::{ops, primitives::*, NormedVectorSpace, ScalarField, Vec2, Vec3}; use rand::{ - distributions::{Distribution, WeightedIndex}, + distr::{ + uniform::SampleUniform, + weighted::{Weight, WeightedIndex}, + Distribution, + }, Rng, }; -use rand_distr::uniform::SampleUniform; /// Exposes methods to uniformly sample a variety of primitive shapes. pub trait ShapeSample { @@ -62,7 +65,7 @@ pub trait ShapeSample { /// let square = Rectangle::new(2.0, 2.0); /// /// // Returns a Vec2 with both x and y between -1 and 1. - /// println!("{}", square.sample_interior(&mut rand::thread_rng())); + /// println!("{}", square.sample_interior(&mut rand::rng())); /// ``` fn sample_interior(&self, rng: &mut R) -> Self::Output; @@ -77,7 +80,7 @@ pub trait ShapeSample { /// /// // Returns a Vec2 where one of the coordinates is at ±1, /// // and the other is somewhere between -1 and 1. - /// println!("{}", square.sample_boundary(&mut rand::thread_rng())); + /// println!("{}", square.sample_boundary(&mut rand::rng())); /// ``` fn sample_boundary(&self, rng: &mut R) -> Self::Output; @@ -87,9 +90,9 @@ pub trait ShapeSample { /// /// ``` /// # use bevy_math::prelude::*; - /// # use rand::distributions::Distribution; + /// # use rand::distr::Distribution; /// let square = Rectangle::new(2.0, 2.0); - /// let rng = rand::thread_rng(); + /// let rng = rand::rng(); /// /// // Iterate over points randomly drawn from `square`'s interior: /// for random_val in square.interior_dist().sample_iter(rng).take(5) { @@ -109,9 +112,9 @@ pub trait ShapeSample { /// /// ``` /// # use bevy_math::prelude::*; - /// # use rand::distributions::Distribution; + /// # use rand::distr::Distribution; /// let square = Rectangle::new(2.0, 2.0); - /// let rng = rand::thread_rng(); + /// let rng = rand::rng(); /// /// // Iterate over points randomly drawn from `square`'s boundary: /// for random_val in square.boundary_dist().sample_iter(rng).take(5) { @@ -153,15 +156,15 @@ impl ShapeSample for Circle { fn sample_interior(&self, rng: &mut R) -> Vec2 { // https://mathworld.wolfram.com/DiskPointPicking.html - let theta = rng.gen_range(0.0..TAU); - let r_squared = rng.gen_range(0.0..=(self.radius * self.radius)); + let theta = rng.random_range(0.0..TAU); + let r_squared = rng.random_range(0.0..=(self.radius * self.radius)); let r = ops::sqrt(r_squared); let (sin, cos) = ops::sin_cos(theta); Vec2::new(r * cos, r * sin) } fn sample_boundary(&self, rng: &mut R) -> Vec2 { - let theta = rng.gen_range(0.0..TAU); + let theta = rng.random_range(0.0..TAU); let (sin, cos) = ops::sin_cos(theta); Vec2::new(self.radius * cos, self.radius * sin) } @@ -170,8 +173,8 @@ impl ShapeSample for Circle { /// Boundary sampling for unit-spheres #[inline] fn sample_unit_sphere_boundary(rng: &mut R) -> Vec3 { - let z = rng.gen_range(-1f32..=1f32); - let (a_sin, a_cos) = ops::sin_cos(rng.gen_range(-PI..=PI)); + let z = rng.random_range(-1f32..=1f32); + let (a_sin, a_cos) = ops::sin_cos(rng.random_range(-PI..=PI)); let c = ops::sqrt(1f32 - z * z); let x = a_sin * c; let y = a_cos * c; @@ -183,7 +186,7 @@ impl ShapeSample for Sphere { type Output = Vec3; fn sample_interior(&self, rng: &mut R) -> Vec3 { - let r_cubed = rng.gen_range(0.0..=(self.radius * self.radius * self.radius)); + let r_cubed = rng.random_range(0.0..=(self.radius * self.radius * self.radius)); let r = ops::cbrt(r_cubed); r * sample_unit_sphere_boundary(rng) @@ -202,9 +205,10 @@ impl ShapeSample for Annulus { let outer_radius = self.outer_circle.radius; // Like random sampling for a circle, radius is weighted by the square. - let r_squared = rng.gen_range((inner_radius * inner_radius)..(outer_radius * outer_radius)); + let r_squared = + rng.random_range((inner_radius * inner_radius)..(outer_radius * outer_radius)); let r = ops::sqrt(r_squared); - let theta = rng.gen_range(0.0..TAU); + let theta = rng.random_range(0.0..TAU); let (sin, cos) = ops::sin_cos(theta); Vec2::new(r * cos, r * sin) @@ -215,7 +219,7 @@ impl ShapeSample for Annulus { let inner_prob = (self.inner_circle.perimeter() / total_perimeter) as f64; // Sample from boundary circles, choosing which one by weighting by perimeter: - let inner = rng.gen_bool(inner_prob); + let inner = rng.random_bool(inner_prob); if inner { self.inner_circle.sample_boundary(rng) } else { @@ -228,17 +232,17 @@ impl ShapeSample for Rectangle { type Output = Vec2; fn sample_interior(&self, rng: &mut R) -> Vec2 { - let x = rng.gen_range(-self.half_size.x..=self.half_size.x); - let y = rng.gen_range(-self.half_size.y..=self.half_size.y); + let x = rng.random_range(-self.half_size.x..=self.half_size.x); + let y = rng.random_range(-self.half_size.y..=self.half_size.y); Vec2::new(x, y) } fn sample_boundary(&self, rng: &mut R) -> Vec2 { - let primary_side = rng.gen_range(-1.0..1.0); - let other_side = if rng.r#gen() { -1.0 } else { 1.0 }; + let primary_side = rng.random_range(-1.0..1.0); + let other_side = if rng.random() { -1.0 } else { 1.0 }; if self.half_size.x + self.half_size.y > 0.0 { - if rng.gen_bool((self.half_size.x / (self.half_size.x + self.half_size.y)) as f64) { + if rng.random_bool((self.half_size.x / (self.half_size.x + self.half_size.y)) as f64) { Vec2::new(primary_side, other_side) * self.half_size } else { Vec2::new(other_side, primary_side) * self.half_size @@ -253,16 +257,16 @@ impl ShapeSample for Cuboid { type Output = Vec3; fn sample_interior(&self, rng: &mut R) -> Vec3 { - let x = rng.gen_range(-self.half_size.x..=self.half_size.x); - let y = rng.gen_range(-self.half_size.y..=self.half_size.y); - let z = rng.gen_range(-self.half_size.z..=self.half_size.z); + let x = rng.random_range(-self.half_size.x..=self.half_size.x); + let y = rng.random_range(-self.half_size.y..=self.half_size.y); + let z = rng.random_range(-self.half_size.z..=self.half_size.z); Vec3::new(x, y, z) } fn sample_boundary(&self, rng: &mut R) -> Vec3 { - let primary_side1 = rng.gen_range(-1.0..1.0); - let primary_side2 = rng.gen_range(-1.0..1.0); - let other_side = if rng.r#gen() { -1.0 } else { 1.0 }; + let primary_side1 = rng.random_range(-1.0..1.0); + let primary_side2 = rng.random_range(-1.0..1.0); + let other_side = if rng.random() { -1.0 } else { 1.0 }; if let Ok(dist) = WeightedIndex::new([ self.half_size.y * self.half_size.z, @@ -294,8 +298,8 @@ where // Generate random points on a parallelepiped and reflect so that // we can use the points that lie outside the triangle - let u = rng.gen_range(P::Scalar::ZERO..=P::Scalar::ONE); - let v = rng.gen_range(P::Scalar::ZERO..=P::Scalar::ONE); + let u = rng.random_range(P::Scalar::ZERO..=P::Scalar::ONE); + let v = rng.random_range(P::Scalar::ZERO..=P::Scalar::ONE); if u + v > P::Scalar::ONE { let u1 = P::Scalar::ONE - v; @@ -310,7 +314,7 @@ where fn sample_triangle_boundary(vertices: [P; 3], rng: &mut R) -> P where P: NormedVectorSpace, - P::Scalar: SampleUniform + PartialOrd + for<'a> ::core::ops::AddAssign<&'a P::Scalar>, + P::Scalar: Weight + SampleUniform + PartialOrd + for<'a> ::core::ops::AddAssign<&'a P::Scalar>, R: Rng + ?Sized, { let [a, b, c] = vertices; @@ -318,7 +322,7 @@ where let ac = c - a; let bc = c - b; - let t = rng.gen_range(P::Scalar::ZERO..=P::Scalar::ONE); + let t = rng.random_range(::ZERO..=P::Scalar::ONE); if let Ok(dist) = WeightedIndex::new([ab.norm(), ac.norm(), bc.norm()]) { match dist.sample(rng) { @@ -366,9 +370,9 @@ impl ShapeSample for Tetrahedron { // Generate a random point in a cube: let mut coords: [f32; 3] = [ - rng.gen_range(0.0..1.0), - rng.gen_range(0.0..1.0), - rng.gen_range(0.0..1.0), + rng.random_range(0.0..1.0), + rng.random_range(0.0..1.0), + rng.random_range(0.0..1.0), ]; // The cube is broken into six tetrahedra of the form 0 <= c_0 <= c_1 <= c_2 <= 1, @@ -420,7 +424,7 @@ impl ShapeSample for Cylinder { fn sample_interior(&self, rng: &mut R) -> Vec3 { let Vec2 { x, y: z } = self.base().sample_interior(rng); - let y = rng.gen_range(-self.half_height..=self.half_height); + let y = rng.random_range(-self.half_height..=self.half_height); Vec3::new(x, y, z) } @@ -428,16 +432,16 @@ impl ShapeSample for Cylinder { // This uses the area of the ends divided by the overall surface area (optimized) // [2 (\pi r^2)]/[2 (\pi r^2) + 2 \pi r h] = r/(r + h) if self.radius + 2.0 * self.half_height > 0.0 { - if rng.gen_bool((self.radius / (self.radius + 2.0 * self.half_height)) as f64) { + if rng.random_bool((self.radius / (self.radius + 2.0 * self.half_height)) as f64) { let Vec2 { x, y: z } = self.base().sample_interior(rng); - if rng.r#gen() { + if rng.random() { Vec3::new(x, self.half_height, z) } else { Vec3::new(x, -self.half_height, z) } } else { let Vec2 { x, y: z } = self.base().sample_boundary(rng); - let y = rng.gen_range(-self.half_height..=self.half_height); + let y = rng.random_range(-self.half_height..=self.half_height); Vec3::new(x, y, z) } } else { @@ -454,7 +458,7 @@ impl ShapeSample for Capsule2d { let capsule_area = rectangle_area + PI * self.radius * self.radius; if capsule_area > 0.0 { // Check if the random point should be inside the rectangle - if rng.gen_bool((rectangle_area / capsule_area) as f64) { + if rng.random_bool((rectangle_area / capsule_area) as f64) { self.to_inner_rectangle().sample_interior(rng) } else { let circle = Circle::new(self.radius); @@ -475,9 +479,9 @@ impl ShapeSample for Capsule2d { let rectangle_surface = 4.0 * self.half_length; let capsule_surface = rectangle_surface + TAU * self.radius; if capsule_surface > 0.0 { - if rng.gen_bool((rectangle_surface / capsule_surface) as f64) { + if rng.random_bool((rectangle_surface / capsule_surface) as f64) { let side_distance = - rng.gen_range((-2.0 * self.half_length)..=(2.0 * self.half_length)); + rng.random_range((-2.0 * self.half_length)..=(2.0 * self.half_length)); if side_distance < 0.0 { Vec2::new(self.radius, side_distance + self.half_length) } else { @@ -508,7 +512,7 @@ impl ShapeSample for Capsule3d { let capsule_vol = cylinder_vol + 4.0 / 3.0 * PI * self.radius * self.radius * self.radius; if capsule_vol > 0.0 { // Check if the random point should be inside the cylinder - if rng.gen_bool((cylinder_vol / capsule_vol) as f64) { + if rng.random_bool((cylinder_vol / capsule_vol) as f64) { self.to_cylinder().sample_interior(rng) } else { let sphere = Sphere::new(self.radius); @@ -529,9 +533,9 @@ impl ShapeSample for Capsule3d { let cylinder_surface = TAU * self.radius * 2.0 * self.half_length; let capsule_surface = cylinder_surface + 4.0 * PI * self.radius * self.radius; if capsule_surface > 0.0 { - if rng.gen_bool((cylinder_surface / capsule_surface) as f64) { + if rng.random_bool((cylinder_surface / capsule_surface) as f64) { let Vec2 { x, y: z } = Circle::new(self.radius).sample_boundary(rng); - let y = rng.gen_range(-self.half_length..=self.half_length); + let y = rng.random_range(-self.half_length..=self.half_length); Vec3::new(x, y, z) } else { let sphere = Sphere::new(self.radius); @@ -554,7 +558,7 @@ impl> ShapeSample for E fn sample_interior(&self, rng: &mut R) -> Self::Output { let base_point = self.base_shape.sample_interior(rng); - let depth = rng.gen_range(-self.half_depth..self.half_depth); + let depth = rng.random_range(-self.half_depth..self.half_depth); base_point.extend(depth) } @@ -562,7 +566,7 @@ impl> ShapeSample for E let base_area = self.base_shape.area(); let total_area = self.area(); - let random = rng.gen_range(0.0..total_area); + let random = rng.random_range(0.0..total_area); match random { x if x < base_area => self.base_shape.sample_interior(rng).extend(self.half_depth), x if x < 2. * base_area => self @@ -572,7 +576,7 @@ impl> ShapeSample for E _ => self .base_shape .sample_boundary(rng) - .extend(rng.gen_range(-self.half_depth..self.half_depth)), + .extend(rng.random_range(-self.half_depth..self.half_depth)), } } } diff --git a/crates/bevy_math/src/sampling/standard.rs b/crates/bevy_math/src/sampling/standard.rs index d4e82fdc81c14..47002f5781077 100644 --- a/crates/bevy_math/src/sampling/standard.rs +++ b/crates/bevy_math/src/sampling/standard.rs @@ -1,24 +1,24 @@ -//! This module holds local implementations of the [`Distribution`] trait for [`Standard`], which +//! This module holds local implementations of the [`Distribution`] trait for [`StandardUniform`], which //! allow certain Bevy math types (those whose values can be randomly generated without additional //! input other than an [`Rng`]) to be produced using [`rand`]'s APIs. It also holds [`FromRng`], //! an ergonomic extension to that functionality which permits the omission of type annotations. //! //! For instance: //! ``` -//! # use rand::{random, Rng, SeedableRng, rngs::StdRng, distributions::Standard}; +//! # use rand::{random, Rng, SeedableRng, rngs::StdRng, distr::StandardUniform}; //! # use bevy_math::{Dir3, sampling::FromRng}; //! let mut rng = StdRng::seed_from_u64(7313429298); //! // Random direction using thread-local rng //! let random_direction1: Dir3 = random(); //! //! // Random direction using the rng constructed above -//! let random_direction2: Dir3 = rng.r#gen(); +//! let random_direction2: Dir3 = rng.random(); //! //! // The same as the previous but with different syntax //! let random_direction3 = Dir3::from_rng(&mut rng); //! -//! // Five random directions, using Standard explicitly -//! let many_random_directions: Vec = rng.sample_iter(Standard).take(5).collect(); +//! // Five random directions, using StandardUniform explicitly +//! let many_random_directions: Vec = rng.sample_iter(StandardUniform).take(5).collect(); //! ``` use core::f32::consts::TAU; @@ -28,11 +28,11 @@ use crate::{ Dir2, Dir3, Dir3A, Quat, Rot2, ShapeSample, Vec3A, }; use rand::{ - distributions::{Distribution, Standard}, + distr::{Distribution, StandardUniform}, Rng, }; -/// Ergonomics trait for a type with a [`Standard`] distribution, allowing values to be generated +/// Ergonomics trait for a type with a [`StandardUniform`] distribution, allowing values to be generated /// uniformly from an [`Rng`] by a method in its own namespace. /// /// Example @@ -45,15 +45,15 @@ use rand::{ pub trait FromRng where Self: Sized, - Standard: Distribution, + StandardUniform: Distribution, { /// Construct a value of this type uniformly at random using `rng` as the source of randomness. fn from_rng(rng: &mut R) -> Self { - rng.r#gen() + rng.random() } } -impl Distribution for Standard { +impl Distribution for StandardUniform { #[inline] fn sample(&self, rng: &mut R) -> Dir2 { let circle = Circle::new(1.0); @@ -64,7 +64,7 @@ impl Distribution for Standard { impl FromRng for Dir2 {} -impl Distribution for Standard { +impl Distribution for StandardUniform { #[inline] fn sample(&self, rng: &mut R) -> Dir3 { let sphere = Sphere::new(1.0); @@ -75,7 +75,7 @@ impl Distribution for Standard { impl FromRng for Dir3 {} -impl Distribution for Standard { +impl Distribution for StandardUniform { #[inline] fn sample(&self, rng: &mut R) -> Dir3A { let sphere = Sphere::new(1.0); @@ -86,10 +86,10 @@ impl Distribution for Standard { impl FromRng for Dir3A {} -impl Distribution for Standard { +impl Distribution for StandardUniform { #[inline] fn sample(&self, rng: &mut R) -> Rot2 { - let angle = rng.gen_range(0.0..TAU); + let angle = rng.random_range(0.0..TAU); Rot2::radians(angle) } } diff --git a/crates/bevy_mesh/Cargo.toml b/crates/bevy_mesh/Cargo.toml index a34b0e7436719..c5034475dff98 100644 --- a/crates/bevy_mesh/Cargo.toml +++ b/crates/bevy_mesh/Cargo.toml @@ -31,7 +31,7 @@ wgpu-types = { version = "25", default-features = false } serde = { version = "1", default-features = false, features = [ "derive", ], optional = true } -hexasphere = "15.0" +hexasphere = "16.0" thiserror = { version = "2", default-features = false } tracing = { version = "0.1", default-features = false, features = ["std"] } derive_more = { version = "2", default-features = false, features = ["from"] } diff --git a/crates/bevy_mikktspace/Cargo.toml b/crates/bevy_mikktspace/Cargo.toml index 82c2d86553c74..77f1917b15361 100644 --- a/crates/bevy_mikktspace/Cargo.toml +++ b/crates/bevy_mikktspace/Cargo.toml @@ -22,7 +22,7 @@ std = ["glam/std"] libm = ["glam/libm", "dep:libm"] [dependencies] -glam = { version = "0.29.3", default-features = false } +glam = { version = "0.30.1", default-features = false } libm = { version = "0.2", default-features = false, optional = true } [[example]] diff --git a/crates/bevy_platform/Cargo.toml b/crates/bevy_platform/Cargo.toml index 614ff15fce0fb..93ede4cc3e939 100644 --- a/crates/bevy_platform/Cargo.toml +++ b/crates/bevy_platform/Cargo.toml @@ -65,8 +65,8 @@ rayon = { version = "1", default-features = false, optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] web-time = { version = "1.1", default-features = false, optional = true } -getrandom = { version = "0.2.0", default-features = false, optional = true, features = [ - "js", +getrandom = { version = "0.3.0", default-features = false, optional = true, features = [ + "wasm_js", ] } [target.'cfg(not(all(target_has_atomic = "8", target_has_atomic = "16", target_has_atomic = "32", target_has_atomic = "64", target_has_atomic = "ptr")))'.dependencies] diff --git a/crates/bevy_reflect/Cargo.toml b/crates/bevy_reflect/Cargo.toml index 8e2d4d0f38c4b..942b6c2f1ec1c 100644 --- a/crates/bevy_reflect/Cargo.toml +++ b/crates/bevy_reflect/Cargo.toml @@ -97,7 +97,7 @@ derive_more = { version = "2", default-features = false, features = ["from"] } serde = { version = "1", default-features = false, features = ["alloc"] } assert_type_match = "0.1.1" smallvec = { version = "1", default-features = false, optional = true } -glam = { version = "0.29.3", default-features = false, features = [ +glam = { version = "0.30.1", default-features = false, features = [ "serde", ], optional = true } petgraph = { version = "0.8", features = ["serde-1"], optional = true } diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index 27463b9272feb..3be3ceb819c26 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -107,7 +107,7 @@ downcast-rs = { version = "2", default-features = false, features = ["std"] } thiserror = { version = "2", default-features = false } derive_more = { version = "2", default-features = false, features = ["from"] } futures-lite = "2.0.1" -encase = { version = "0.10", features = ["glam"] } +encase = { version = "0.11", features = ["glam"] } # For wgpu profiling using tracing. Use `RUST_LOG=info` to also capture the wgpu spans. profiling = { version = "1", features = [ "profile-with-tracing", diff --git a/examples/2d/cpu_draw.rs b/examples/2d/cpu_draw.rs index ba98e1051e8f7..c8498c60941d3 100644 --- a/examples/2d/cpu_draw.rs +++ b/examples/2d/cpu_draw.rs @@ -102,9 +102,9 @@ fn draw( if *i == 0 { // Generate a random color on first run. *draw_color = Color::linear_rgb( - seeded_rng.0.r#gen(), - seeded_rng.0.r#gen(), - seeded_rng.0.r#gen(), + seeded_rng.0.random(), + seeded_rng.0.random(), + seeded_rng.0.random(), ); } @@ -129,9 +129,9 @@ fn draw( let tolerance = 1.0 / 255.0; if old_color.distance(&draw_color) <= tolerance { *draw_color = Color::linear_rgb( - seeded_rng.0.r#gen(), - seeded_rng.0.r#gen(), - seeded_rng.0.r#gen(), + seeded_rng.0.random(), + seeded_rng.0.random(), + seeded_rng.0.random(), ); } diff --git a/examples/2d/tilemap_chunk.rs b/examples/2d/tilemap_chunk.rs index 8663b036b1574..dcaa5b46d2ff6 100644 --- a/examples/2d/tilemap_chunk.rs +++ b/examples/2d/tilemap_chunk.rs @@ -29,7 +29,7 @@ fn setup(mut commands: Commands, assets: Res) { let chunk_size = UVec2::splat(64); let tile_display_size = UVec2::splat(8); let indices: Vec> = (0..chunk_size.element_product()) - .map(|_| rng.gen_range(0..5)) + .map(|_| rng.random_range(0..5)) .map(|i| if i == 0 { None } else { Some(i - 1) }) .collect(); @@ -73,8 +73,8 @@ fn update_tilemap( if timer.just_finished() { for _ in 0..50 { - let index = rng.gen_range(0..indices.len()); - indices[index] = Some(rng.gen_range(0..5)); + let index = rng.random_range(0..indices.len()); + indices[index] = Some(rng.random_range(0..5)); } } } diff --git a/examples/3d/decal.rs b/examples/3d/decal.rs index 7fd45cd53cee6..9aa0056c1178b 100644 --- a/examples/3d/decal.rs +++ b/examples/3d/decal.rs @@ -64,9 +64,9 @@ fn setup( let mut rng = ChaCha8Rng::seed_from_u64(19878367467713); for i in 0..num_obs { for j in 0..num_obs { - let rotation_axis: [f32; 3] = rng.r#gen(); + let rotation_axis: [f32; 3] = rng.random(); let rotation_vec: Vec3 = rotation_axis.into(); - let rotation: u32 = rng.gen_range(0..360); + let rotation: u32 = rng.random_range(0..360); let transform = Transform::from_xyz( (-num_obs + 1) as f32 / 2.0 + i as f32, -0.2, diff --git a/examples/3d/spotlight.rs b/examples/3d/spotlight.rs index 3885f47e65fbf..863c07b15b27c 100644 --- a/examples/3d/spotlight.rs +++ b/examples/3d/spotlight.rs @@ -57,9 +57,9 @@ fn setup( commands.spawn_batch( std::iter::repeat_with(move || { - let x = rng.gen_range(-5.0..5.0); - let y = rng.gen_range(0.0..3.0); - let z = rng.gen_range(-5.0..5.0); + let x = rng.random_range(-5.0..5.0); + let y = rng.random_range(0.0..3.0); + let z = rng.random_range(-5.0..5.0); ( Mesh3d(cube_mesh.clone()), diff --git a/examples/animation/animated_mesh_events.rs b/examples/animation/animated_mesh_events.rs index b9ce729bad665..b44fca137c581 100644 --- a/examples/animation/animated_mesh_events.rs +++ b/examples/animation/animated_mesh_events.rs @@ -50,14 +50,14 @@ fn observe_on_step( let translation = transforms.get(trigger.target()).unwrap().translation(); // Spawn a bunch of particles. for _ in 0..14 { - let horizontal = seeded_rng.0.r#gen::() * seeded_rng.0.gen_range(8.0..12.0); - let vertical = seeded_rng.0.gen_range(0.0..4.0); - let size = seeded_rng.0.gen_range(0.2..1.0); + let horizontal = seeded_rng.0.random::() * seeded_rng.0.random_range(8.0..12.0); + let vertical = seeded_rng.0.random_range(0.0..4.0); + let size = seeded_rng.0.random_range(0.2..1.0); commands.spawn(( Particle { lifetime_timer: Timer::from_seconds( - seeded_rng.0.gen_range(0.2..0.6), + seeded_rng.0.random_range(0.2..0.6), TimerMode::Once, ), size, diff --git a/examples/animation/custom_skinned_mesh.rs b/examples/animation/custom_skinned_mesh.rs index b091f2dd4254c..d9c1d420588ae 100644 --- a/examples/animation/custom_skinned_mesh.rs +++ b/examples/animation/custom_skinned_mesh.rs @@ -169,9 +169,9 @@ fn setup( Mesh3d(mesh.clone()), MeshMaterial3d(materials.add(StandardMaterial { base_color: Color::srgb( - rng.gen_range(0.0..1.0), - rng.gen_range(0.0..1.0), - rng.gen_range(0.0..1.0), + rng.random_range(0.0..1.0), + rng.random_range(0.0..1.0), + rng.random_range(0.0..1.0), ), base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")), ..default() diff --git a/examples/async_tasks/async_compute.rs b/examples/async_tasks/async_compute.rs index 0b5a044563528..e55634c9a9a51 100644 --- a/examples/async_tasks/async_compute.rs +++ b/examples/async_tasks/async_compute.rs @@ -59,7 +59,7 @@ fn spawn_tasks(mut commands: Commands) { // spawn() can be used to poll for the result let entity = commands.spawn_empty().id(); let task = thread_pool.spawn(async move { - let duration = Duration::from_secs_f32(rand::thread_rng().gen_range(0.05..5.0)); + let duration = Duration::from_secs_f32(rand::rng().random_range(0.05..5.0)); // Pretend this is a time-intensive function. :) async_std::task::sleep(duration).await; diff --git a/examples/async_tasks/external_source_external_thread.rs b/examples/async_tasks/external_source_external_thread.rs index 9cd7a57ae4cc1..94be33c83283d 100644 --- a/examples/async_tasks/external_source_external_thread.rs +++ b/examples/async_tasks/external_source_external_thread.rs @@ -36,7 +36,7 @@ fn setup(mut commands: Commands) { // This is where you could connect to an external data source // This will block until the previous value has been read in system `read_stream` - tx.send(rng.gen_range(0..2000)).unwrap(); + tx.send(rng.random_range(0..2000)).unwrap(); } }); diff --git a/examples/ecs/change_detection.rs b/examples/ecs/change_detection.rs index b63b7bfd33838..4f01c9e516be4 100644 --- a/examples/ecs/change_detection.rs +++ b/examples/ecs/change_detection.rs @@ -34,7 +34,7 @@ fn setup(mut commands: Commands) { fn change_component(time: Res