Merge 3fb33b6dda
into f964ee1e3a
This commit is contained in:
commit
2cb05fab8b
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -222,6 +222,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
target: wasm32-unknown-unknown
|
target: wasm32-unknown-unknown
|
||||||
- name: Check wasm
|
- name: Check wasm
|
||||||
|
env:
|
||||||
|
RUSTFLAGS: --cfg getrandom_backend="wasm_js"
|
||||||
run: cargo check --target wasm32-unknown-unknown
|
run: cargo check --target wasm32-unknown-unknown
|
||||||
|
|
||||||
build-wasm-atomics:
|
build-wasm-atomics:
|
||||||
@ -247,7 +249,7 @@ jobs:
|
|||||||
- name: Check wasm
|
- name: Check wasm
|
||||||
run: cargo check --target wasm32-unknown-unknown -Z build-std=std,panic_abort
|
run: cargo check --target wasm32-unknown-unknown -Z build-std=std,panic_abort
|
||||||
env:
|
env:
|
||||||
RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory"
|
RUSTFLAGS: '-C target-feature=+atomics,+bulk-memory --cfg getrandom_backend="wasm_js"'
|
||||||
|
|
||||||
markdownlint:
|
markdownlint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
2
.github/workflows/validation-jobs.yml
vendored
2
.github/workflows/validation-jobs.yml
vendored
@ -112,6 +112,8 @@ jobs:
|
|||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
- name: First Wasm build
|
- name: First Wasm build
|
||||||
|
env:
|
||||||
|
RUSTFLAGS: --cfg getrandom_backend="wasm_js"
|
||||||
run: |
|
run: |
|
||||||
cargo build --release --example testbed_ui --target wasm32-unknown-unknown
|
cargo build --release --example testbed_ui --target wasm32-unknown-unknown
|
||||||
|
|
||||||
|
@ -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 }
|
bevy_dylib = { path = "crates/bevy_dylib", version = "0.17.0-dev", default-features = false, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.8.0"
|
rand = "0.9.0"
|
||||||
rand_chacha = "0.3.1"
|
rand_chacha = "0.9.0"
|
||||||
ron = "0.10"
|
ron = "0.10"
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
@ -627,6 +627,9 @@ smol-hyper = "0.1"
|
|||||||
ureq = { version = "3.0.8", features = ["json"] }
|
ureq = { version = "3.0.8", features = ["json"] }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||||
|
getrandom = { version = "0.3", default-features = false, features = [
|
||||||
|
"wasm_js",
|
||||||
|
] }
|
||||||
wasm-bindgen = { version = "0.2" }
|
wasm-bindgen = { version = "0.2" }
|
||||||
web-sys = { version = "0.3", features = ["Window"] }
|
web-sys = { version = "0.3", features = ["Window"] }
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ bevy_platform = { path = "../crates/bevy_platform", default-features = false, fe
|
|||||||
] }
|
] }
|
||||||
|
|
||||||
# Other crates
|
# Other crates
|
||||||
glam = "0.29"
|
glam = "0.30.1"
|
||||||
rand = "0.8"
|
rand = "0.9"
|
||||||
rand_chacha = "0.3"
|
rand_chacha = "0.9"
|
||||||
nonmax = { version = "0.5", default-features = false }
|
nonmax = { version = "0.5", default-features = false }
|
||||||
|
|
||||||
# Make `bevy_render` compile on Linux with x11 windowing. x11 vs. Wayland does not matter here
|
# Make `bevy_render` compile on Linux with x11 windowing. x11 vs. Wayland does not matter here
|
||||||
|
@ -66,7 +66,7 @@ pub fn event_propagation(criterion: &mut Criterion) {
|
|||||||
struct TestEvent<const N: usize> {}
|
struct TestEvent<const N: usize> {}
|
||||||
|
|
||||||
fn send_events<const N: usize, const N_EVENTS: usize>(world: &mut World, leaves: &[Entity]) {
|
fn send_events<const N: usize, const N_EVENTS: usize>(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(|_| {
|
(0..N_EVENTS).for_each(|_| {
|
||||||
world.trigger_targets(TestEvent::<N> {}, *target);
|
world.trigger_targets(TestEvent::<N> {}, *target);
|
||||||
@ -107,7 +107,7 @@ fn add_listeners_to_hierarchy<const DENSITY: usize, const N: usize>(
|
|||||||
}
|
}
|
||||||
let mut rng = deterministic_rand();
|
let mut rng = deterministic_rand();
|
||||||
for e in nodes.iter() {
|
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::<N>);
|
world.entity_mut(*e).observe(empty_listener::<N>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 ids, half are in [0, size), half are unboundedly larger.
|
||||||
// * For generations, half are in [1, 3), 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 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;
|
let generation = 1.0 + -(1.0 - x).log2() * 2.0;
|
||||||
|
|
||||||
// this is not reliable, but we're internal so a hack is ok
|
// this is not reliable, but we're internal so a hack is ok
|
||||||
|
@ -3,7 +3,7 @@ use core::{fmt::Write, hint::black_box, str, time::Duration};
|
|||||||
use benches::bench;
|
use benches::bench;
|
||||||
use bevy_reflect::ParsedPath;
|
use bevy_reflect::ParsedPath;
|
||||||
use criterion::{criterion_group, BatchSize, BenchmarkId, Criterion, Throughput};
|
use criterion::{criterion_group, BatchSize, BenchmarkId, Criterion, Throughput};
|
||||||
use rand::{distributions::Uniform, Rng, SeedableRng};
|
use rand::{distr::Uniform, Rng, SeedableRng};
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
|
||||||
criterion_group!(benches, parse_reflect_path);
|
criterion_group!(benches, parse_reflect_path);
|
||||||
@ -18,20 +18,20 @@ fn deterministic_rand() -> ChaCha8Rng {
|
|||||||
ChaCha8Rng::seed_from_u64(42)
|
ChaCha8Rng::seed_from_u64(42)
|
||||||
}
|
}
|
||||||
fn random_ident(rng: &mut ChaCha8Rng, f: &mut dyn Write) {
|
fn random_ident(rng: &mut ChaCha8Rng, f: &mut dyn Write) {
|
||||||
let between = Uniform::from(b'a'..=b'z');
|
let between = Uniform::new_inclusive(b'a', b'z').unwrap();
|
||||||
let ident_size = rng.gen_range(1..128);
|
let ident_size = rng.random_range(1..128);
|
||||||
let ident: Vec<u8> = rng.sample_iter(between).take(ident_size).collect();
|
let ident: Vec<u8> = rng.sample_iter(between).take(ident_size).collect();
|
||||||
let ident = str::from_utf8(&ident).unwrap();
|
let ident = str::from_utf8(&ident).unwrap();
|
||||||
let _ = write!(f, "{ident}");
|
let _ = write!(f, "{ident}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn random_index(rng: &mut ChaCha8Rng, f: &mut dyn Write) {
|
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}");
|
let _ = write!(f, "{index}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_random_access(rng: &mut ChaCha8Rng, f: &mut dyn Write) {
|
fn write_random_access(rng: &mut ChaCha8Rng, f: &mut dyn Write) {
|
||||||
match rng.gen_range(0..4) {
|
match rng.random_range(0..4) {
|
||||||
0 => {
|
0 => {
|
||||||
// Access::Field
|
// Access::Field
|
||||||
f.write_char('.').unwrap();
|
f.write_char('.').unwrap();
|
||||||
|
@ -21,7 +21,7 @@ serde = { version = "1.0", features = [
|
|||||||
thiserror = { version = "2", default-features = false }
|
thiserror = { version = "2", default-features = false }
|
||||||
derive_more = { version = "2", default-features = false, features = ["from"] }
|
derive_more = { version = "2", default-features = false, features = ["from"] }
|
||||||
wgpu-types = { version = "25", default-features = false, optional = true }
|
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]
|
[features]
|
||||||
default = ["std", "bevy_reflect", "encase"]
|
default = ["std", "bevy_reflect", "encase"]
|
||||||
|
@ -131,7 +131,7 @@ concurrent-queue = { version = "2.5.0", default-features = false, features = [
|
|||||||
] }
|
] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.8"
|
rand = "0.9"
|
||||||
static_assertions = "1.1.0"
|
static_assertions = "1.1.0"
|
||||||
serde_test = "1.0"
|
serde_test = "1.0"
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ enum SimulationSystems {
|
|||||||
// The entity will start with an age of 0 frames
|
// The entity will start with an age of 0 frames
|
||||||
// If an entity gets spawned, we increase the counter in the EntityCounter resource
|
// If an entity gets spawned, we increase the counter in the EntityCounter resource
|
||||||
fn spawn_entities(mut commands: Commands, mut entity_counter: ResMut<EntityCounter>) {
|
fn spawn_entities(mut commands: Commands, mut entity_counter: ResMut<EntityCounter>) {
|
||||||
if rand::thread_rng().gen_bool(0.6) {
|
if rand::rng().random_bool(0.6) {
|
||||||
let entity_id = commands.spawn(Age::default()).id();
|
let entity_id = commands.spawn(Age::default()).id();
|
||||||
println!(" spawning {entity_id:?}");
|
println!(" spawning {entity_id:?}");
|
||||||
entity_counter.value += 1;
|
entity_counter.value += 1;
|
||||||
|
@ -37,7 +37,7 @@ struct Counter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn increase_counter(mut counter: ResMut<Counter>) {
|
fn increase_counter(mut counter: ResMut<Counter>) {
|
||||||
if rand::thread_rng().gen_bool(0.5) {
|
if rand::rng().random_bool(0.5) {
|
||||||
counter.value += 1;
|
counter.value += 1;
|
||||||
println!(" Increased counter value");
|
println!(" Increased counter value");
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ proc-macro = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy_macro_utils = { path = "../bevy_macro_utils", version = "0.17.0-dev" }
|
bevy_macro_utils = { path = "../bevy_macro_utils", version = "0.17.0-dev" }
|
||||||
encase_derive_impl = "0.10"
|
encase_derive_impl = "0.11"
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
@ -10,7 +10,7 @@ keywords = ["bevy"]
|
|||||||
rust-version = "1.85.0"
|
rust-version = "1.85.0"
|
||||||
|
|
||||||
[dependencies]
|
[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 }
|
thiserror = { version = "2", default-features = false }
|
||||||
derive_more = { version = "2", default-features = false, features = [
|
derive_more = { version = "2", default-features = false, features = [
|
||||||
"from",
|
"from",
|
||||||
@ -22,8 +22,8 @@ serde = { version = "1", default-features = false, features = [
|
|||||||
], optional = true }
|
], optional = true }
|
||||||
libm = { version = "0.2", optional = true }
|
libm = { version = "0.2", optional = true }
|
||||||
approx = { version = "0.5", default-features = false, optional = true }
|
approx = { version = "0.5", default-features = false, optional = true }
|
||||||
rand = { version = "0.8", default-features = false, optional = true }
|
rand = { version = "0.9", default-features = false, optional = true }
|
||||||
rand_distr = { version = "0.4.3", optional = true }
|
rand_distr = { version = "0.5", optional = true }
|
||||||
smallvec = { version = "1", default-features = false }
|
smallvec = { version = "1", default-features = false }
|
||||||
bevy_reflect = { path = "../bevy_reflect", version = "0.17.0-dev", default-features = false, features = [
|
bevy_reflect = { path = "../bevy_reflect", version = "0.17.0-dev", default-features = false, features = [
|
||||||
"glam",
|
"glam",
|
||||||
@ -33,11 +33,16 @@ variadics_please = "1.1"
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
# Supply rngs for examples and tests
|
# Supply rngs for examples and tests
|
||||||
rand = "0.8"
|
rand = "0.9"
|
||||||
rand_chacha = "0.3"
|
rand_chacha = "0.9"
|
||||||
# Enable the approx feature when testing.
|
# Enable the approx feature when testing.
|
||||||
bevy_math = { path = ".", default-features = false, features = ["approx"] }
|
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]
|
[features]
|
||||||
default = ["std", "rand", "curve"]
|
default = ["std", "rand", "curve"]
|
||||||
|
@ -6,7 +6,10 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use rand::Rng;
|
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.
|
/// A [distribution] that caches data to allow fast sampling from a collection of triangles.
|
||||||
/// Generally used through [`sample`] or [`sample_iter`].
|
/// 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::{Vec3, primitives::*};
|
||||||
/// # use bevy_math::sampling::mesh_sampling::UniformMeshSampler;
|
/// # 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 faces = Tetrahedron::default().faces();
|
||||||
/// let sampler = UniformMeshSampler::try_new(faces).unwrap();
|
/// let sampler = UniformMeshSampler::try_new(faces).unwrap();
|
||||||
/// let rng = StdRng::seed_from_u64(8765309);
|
/// let rng = StdRng::seed_from_u64(8765309);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
//! # use rand::SeedableRng;
|
//! # use rand::SeedableRng;
|
||||||
//! # use rand::rngs::StdRng;
|
//! # use rand::rngs::StdRng;
|
||||||
//! // Get some `Rng`:
|
//! // Get some `Rng`:
|
||||||
//! let rng = &mut StdRng::from_entropy();
|
//! let rng = &mut StdRng::from_os_rng();
|
||||||
//! // Make a circle of radius 2:
|
//! // Make a circle of radius 2:
|
||||||
//! let circle = Circle::new(2.0);
|
//! let circle = Circle::new(2.0);
|
||||||
//! // Get a point inside this circle uniformly at random:
|
//! // Get a point inside this circle uniformly at random:
|
||||||
@ -23,9 +23,9 @@
|
|||||||
//! # use bevy_math::{Vec2, ShapeSample};
|
//! # use bevy_math::{Vec2, ShapeSample};
|
||||||
//! # use rand::SeedableRng;
|
//! # use rand::SeedableRng;
|
||||||
//! # use rand::rngs::StdRng;
|
//! # use rand::rngs::StdRng;
|
||||||
//! # use rand::distributions::Distribution;
|
//! # use rand::distr::Distribution;
|
||||||
//! # let rng1 = StdRng::from_entropy();
|
//! # let rng1 = StdRng::from_os_rng();
|
||||||
//! # let rng2 = StdRng::from_entropy();
|
//! # let rng2 = StdRng::from_os_rng();
|
||||||
//! // Use a rectangle this time:
|
//! // Use a rectangle this time:
|
||||||
//! let rectangle = Rectangle::new(1.0, 2.0);
|
//! let rectangle = Rectangle::new(1.0, 2.0);
|
||||||
//! // Get an iterator that spits out random interior points:
|
//! // 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 crate::{ops, primitives::*, NormedVectorSpace, ScalarField, Vec2, Vec3};
|
||||||
use rand::{
|
use rand::{
|
||||||
distributions::{Distribution, WeightedIndex},
|
distr::{
|
||||||
|
uniform::SampleUniform,
|
||||||
|
weighted::{Weight, WeightedIndex},
|
||||||
|
Distribution,
|
||||||
|
},
|
||||||
Rng,
|
Rng,
|
||||||
};
|
};
|
||||||
use rand_distr::uniform::SampleUniform;
|
|
||||||
|
|
||||||
/// Exposes methods to uniformly sample a variety of primitive shapes.
|
/// Exposes methods to uniformly sample a variety of primitive shapes.
|
||||||
pub trait ShapeSample {
|
pub trait ShapeSample {
|
||||||
@ -62,7 +65,7 @@ pub trait ShapeSample {
|
|||||||
/// let square = Rectangle::new(2.0, 2.0);
|
/// let square = Rectangle::new(2.0, 2.0);
|
||||||
///
|
///
|
||||||
/// // Returns a Vec2 with both x and y between -1 and 1.
|
/// // 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<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::Output;
|
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::Output;
|
||||||
|
|
||||||
@ -77,7 +80,7 @@ pub trait ShapeSample {
|
|||||||
///
|
///
|
||||||
/// // Returns a Vec2 where one of the coordinates is at ±1,
|
/// // Returns a Vec2 where one of the coordinates is at ±1,
|
||||||
/// // and the other is somewhere between -1 and 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<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::Output;
|
fn sample_boundary<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::Output;
|
||||||
|
|
||||||
@ -87,9 +90,9 @@ pub trait ShapeSample {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use bevy_math::prelude::*;
|
/// # use bevy_math::prelude::*;
|
||||||
/// # use rand::distributions::Distribution;
|
/// # use rand::distr::Distribution;
|
||||||
/// let square = Rectangle::new(2.0, 2.0);
|
/// 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:
|
/// // Iterate over points randomly drawn from `square`'s interior:
|
||||||
/// for random_val in square.interior_dist().sample_iter(rng).take(5) {
|
/// for random_val in square.interior_dist().sample_iter(rng).take(5) {
|
||||||
@ -109,9 +112,9 @@ pub trait ShapeSample {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use bevy_math::prelude::*;
|
/// # use bevy_math::prelude::*;
|
||||||
/// # use rand::distributions::Distribution;
|
/// # use rand::distr::Distribution;
|
||||||
/// let square = Rectangle::new(2.0, 2.0);
|
/// 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:
|
/// // Iterate over points randomly drawn from `square`'s boundary:
|
||||||
/// for random_val in square.boundary_dist().sample_iter(rng).take(5) {
|
/// for random_val in square.boundary_dist().sample_iter(rng).take(5) {
|
||||||
@ -153,15 +156,15 @@ impl ShapeSample for Circle {
|
|||||||
|
|
||||||
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec2 {
|
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec2 {
|
||||||
// https://mathworld.wolfram.com/DiskPointPicking.html
|
// https://mathworld.wolfram.com/DiskPointPicking.html
|
||||||
let theta = rng.gen_range(0.0..TAU);
|
let theta = rng.random_range(0.0..TAU);
|
||||||
let r_squared = rng.gen_range(0.0..=(self.radius * self.radius));
|
let r_squared = rng.random_range(0.0..=(self.radius * self.radius));
|
||||||
let r = ops::sqrt(r_squared);
|
let r = ops::sqrt(r_squared);
|
||||||
let (sin, cos) = ops::sin_cos(theta);
|
let (sin, cos) = ops::sin_cos(theta);
|
||||||
Vec2::new(r * cos, r * sin)
|
Vec2::new(r * cos, r * sin)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sample_boundary<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec2 {
|
fn sample_boundary<R: Rng + ?Sized>(&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);
|
let (sin, cos) = ops::sin_cos(theta);
|
||||||
Vec2::new(self.radius * cos, self.radius * sin)
|
Vec2::new(self.radius * cos, self.radius * sin)
|
||||||
}
|
}
|
||||||
@ -170,8 +173,8 @@ impl ShapeSample for Circle {
|
|||||||
/// Boundary sampling for unit-spheres
|
/// Boundary sampling for unit-spheres
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample_unit_sphere_boundary<R: Rng + ?Sized>(rng: &mut R) -> Vec3 {
|
fn sample_unit_sphere_boundary<R: Rng + ?Sized>(rng: &mut R) -> Vec3 {
|
||||||
let z = rng.gen_range(-1f32..=1f32);
|
let z = rng.random_range(-1f32..=1f32);
|
||||||
let (a_sin, a_cos) = ops::sin_cos(rng.gen_range(-PI..=PI));
|
let (a_sin, a_cos) = ops::sin_cos(rng.random_range(-PI..=PI));
|
||||||
let c = ops::sqrt(1f32 - z * z);
|
let c = ops::sqrt(1f32 - z * z);
|
||||||
let x = a_sin * c;
|
let x = a_sin * c;
|
||||||
let y = a_cos * c;
|
let y = a_cos * c;
|
||||||
@ -183,7 +186,7 @@ impl ShapeSample for Sphere {
|
|||||||
type Output = Vec3;
|
type Output = Vec3;
|
||||||
|
|
||||||
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
|
fn sample_interior<R: Rng + ?Sized>(&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);
|
let r = ops::cbrt(r_cubed);
|
||||||
|
|
||||||
r * sample_unit_sphere_boundary(rng)
|
r * sample_unit_sphere_boundary(rng)
|
||||||
@ -202,9 +205,10 @@ impl ShapeSample for Annulus {
|
|||||||
let outer_radius = self.outer_circle.radius;
|
let outer_radius = self.outer_circle.radius;
|
||||||
|
|
||||||
// Like random sampling for a circle, radius is weighted by the square.
|
// 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 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);
|
let (sin, cos) = ops::sin_cos(theta);
|
||||||
|
|
||||||
Vec2::new(r * cos, r * sin)
|
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;
|
let inner_prob = (self.inner_circle.perimeter() / total_perimeter) as f64;
|
||||||
|
|
||||||
// Sample from boundary circles, choosing which one by weighting by perimeter:
|
// 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 {
|
if inner {
|
||||||
self.inner_circle.sample_boundary(rng)
|
self.inner_circle.sample_boundary(rng)
|
||||||
} else {
|
} else {
|
||||||
@ -248,17 +252,17 @@ impl ShapeSample for Rectangle {
|
|||||||
type Output = Vec2;
|
type Output = Vec2;
|
||||||
|
|
||||||
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec2 {
|
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec2 {
|
||||||
let x = rng.gen_range(-self.half_size.x..=self.half_size.x);
|
let x = rng.random_range(-self.half_size.x..=self.half_size.x);
|
||||||
let y = rng.gen_range(-self.half_size.y..=self.half_size.y);
|
let y = rng.random_range(-self.half_size.y..=self.half_size.y);
|
||||||
Vec2::new(x, y)
|
Vec2::new(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sample_boundary<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec2 {
|
fn sample_boundary<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec2 {
|
||||||
let primary_side = rng.gen_range(-1.0..1.0);
|
let primary_side = rng.random_range(-1.0..1.0);
|
||||||
let other_side = if rng.r#gen() { -1.0 } else { 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 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
|
Vec2::new(primary_side, other_side) * self.half_size
|
||||||
} else {
|
} else {
|
||||||
Vec2::new(other_side, primary_side) * self.half_size
|
Vec2::new(other_side, primary_side) * self.half_size
|
||||||
@ -273,16 +277,16 @@ impl ShapeSample for Cuboid {
|
|||||||
type Output = Vec3;
|
type Output = Vec3;
|
||||||
|
|
||||||
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
|
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
|
||||||
let x = rng.gen_range(-self.half_size.x..=self.half_size.x);
|
let x = rng.random_range(-self.half_size.x..=self.half_size.x);
|
||||||
let y = rng.gen_range(-self.half_size.y..=self.half_size.y);
|
let y = rng.random_range(-self.half_size.y..=self.half_size.y);
|
||||||
let z = rng.gen_range(-self.half_size.z..=self.half_size.z);
|
let z = rng.random_range(-self.half_size.z..=self.half_size.z);
|
||||||
Vec3::new(x, y, z)
|
Vec3::new(x, y, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sample_boundary<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
|
fn sample_boundary<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
|
||||||
let primary_side1 = rng.gen_range(-1.0..1.0);
|
let primary_side1 = rng.random_range(-1.0..1.0);
|
||||||
let primary_side2 = rng.gen_range(-1.0..1.0);
|
let primary_side2 = rng.random_range(-1.0..1.0);
|
||||||
let other_side = if rng.r#gen() { -1.0 } else { 1.0 };
|
let other_side = if rng.random() { -1.0 } else { 1.0 };
|
||||||
|
|
||||||
if let Ok(dist) = WeightedIndex::new([
|
if let Ok(dist) = WeightedIndex::new([
|
||||||
self.half_size.y * self.half_size.z,
|
self.half_size.y * self.half_size.z,
|
||||||
@ -314,8 +318,8 @@ where
|
|||||||
|
|
||||||
// Generate random points on a parallelepiped and reflect so that
|
// Generate random points on a parallelepiped and reflect so that
|
||||||
// we can use the points that lie outside the triangle
|
// we can use the points that lie outside the triangle
|
||||||
let u = rng.gen_range(P::Scalar::ZERO..=P::Scalar::ONE);
|
let u = rng.random_range(P::Scalar::ZERO..=P::Scalar::ONE);
|
||||||
let v = rng.gen_range(P::Scalar::ZERO..=P::Scalar::ONE);
|
let v = rng.random_range(P::Scalar::ZERO..=P::Scalar::ONE);
|
||||||
|
|
||||||
if u + v > P::Scalar::ONE {
|
if u + v > P::Scalar::ONE {
|
||||||
let u1 = P::Scalar::ONE - v;
|
let u1 = P::Scalar::ONE - v;
|
||||||
@ -330,7 +334,7 @@ where
|
|||||||
fn sample_triangle_boundary<P, R>(vertices: [P; 3], rng: &mut R) -> P
|
fn sample_triangle_boundary<P, R>(vertices: [P; 3], rng: &mut R) -> P
|
||||||
where
|
where
|
||||||
P: NormedVectorSpace,
|
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,
|
R: Rng + ?Sized,
|
||||||
{
|
{
|
||||||
let [a, b, c] = vertices;
|
let [a, b, c] = vertices;
|
||||||
@ -338,7 +342,7 @@ where
|
|||||||
let ac = c - a;
|
let ac = c - a;
|
||||||
let bc = c - b;
|
let bc = c - b;
|
||||||
|
|
||||||
let t = rng.gen_range(P::Scalar::ZERO..=P::Scalar::ONE);
|
let t = rng.random_range(<P::Scalar as ScalarField>::ZERO..=P::Scalar::ONE);
|
||||||
|
|
||||||
if let Ok(dist) = WeightedIndex::new([ab.norm(), ac.norm(), bc.norm()]) {
|
if let Ok(dist) = WeightedIndex::new([ab.norm(), ac.norm(), bc.norm()]) {
|
||||||
match dist.sample(rng) {
|
match dist.sample(rng) {
|
||||||
@ -386,9 +390,9 @@ impl ShapeSample for Tetrahedron {
|
|||||||
|
|
||||||
// Generate a random point in a cube:
|
// Generate a random point in a cube:
|
||||||
let mut coords: [f32; 3] = [
|
let mut coords: [f32; 3] = [
|
||||||
rng.gen_range(0.0..1.0),
|
rng.random_range(0.0..1.0),
|
||||||
rng.gen_range(0.0..1.0),
|
rng.random_range(0.0..1.0),
|
||||||
rng.gen_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,
|
// The cube is broken into six tetrahedra of the form 0 <= c_0 <= c_1 <= c_2 <= 1,
|
||||||
@ -440,7 +444,7 @@ impl ShapeSample for Cylinder {
|
|||||||
|
|
||||||
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
|
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
|
||||||
let Vec2 { x, y: z } = self.base().sample_interior(rng);
|
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)
|
Vec3::new(x, y, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,16 +452,16 @@ impl ShapeSample for Cylinder {
|
|||||||
// This uses the area of the ends divided by the overall surface area (optimized)
|
// 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)
|
// [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 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);
|
let Vec2 { x, y: z } = self.base().sample_interior(rng);
|
||||||
if rng.r#gen() {
|
if rng.random() {
|
||||||
Vec3::new(x, self.half_height, z)
|
Vec3::new(x, self.half_height, z)
|
||||||
} else {
|
} else {
|
||||||
Vec3::new(x, -self.half_height, z)
|
Vec3::new(x, -self.half_height, z)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let Vec2 { x, y: z } = self.base().sample_boundary(rng);
|
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)
|
Vec3::new(x, y, z)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -474,7 +478,7 @@ impl ShapeSample for Capsule2d {
|
|||||||
let capsule_area = rectangle_area + PI * self.radius * self.radius;
|
let capsule_area = rectangle_area + PI * self.radius * self.radius;
|
||||||
if capsule_area > 0.0 {
|
if capsule_area > 0.0 {
|
||||||
// Check if the random point should be inside the rectangle
|
// 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)
|
self.to_inner_rectangle().sample_interior(rng)
|
||||||
} else {
|
} else {
|
||||||
let circle = Circle::new(self.radius);
|
let circle = Circle::new(self.radius);
|
||||||
@ -495,9 +499,9 @@ impl ShapeSample for Capsule2d {
|
|||||||
let rectangle_surface = 4.0 * self.half_length;
|
let rectangle_surface = 4.0 * self.half_length;
|
||||||
let capsule_surface = rectangle_surface + TAU * self.radius;
|
let capsule_surface = rectangle_surface + TAU * self.radius;
|
||||||
if capsule_surface > 0.0 {
|
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 =
|
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 {
|
if side_distance < 0.0 {
|
||||||
Vec2::new(self.radius, side_distance + self.half_length)
|
Vec2::new(self.radius, side_distance + self.half_length)
|
||||||
} else {
|
} else {
|
||||||
@ -528,7 +532,7 @@ impl ShapeSample for Capsule3d {
|
|||||||
let capsule_vol = cylinder_vol + 4.0 / 3.0 * PI * self.radius * self.radius * self.radius;
|
let capsule_vol = cylinder_vol + 4.0 / 3.0 * PI * self.radius * self.radius * self.radius;
|
||||||
if capsule_vol > 0.0 {
|
if capsule_vol > 0.0 {
|
||||||
// Check if the random point should be inside the cylinder
|
// 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)
|
self.to_cylinder().sample_interior(rng)
|
||||||
} else {
|
} else {
|
||||||
let sphere = Sphere::new(self.radius);
|
let sphere = Sphere::new(self.radius);
|
||||||
@ -549,9 +553,9 @@ impl ShapeSample for Capsule3d {
|
|||||||
let cylinder_surface = TAU * self.radius * 2.0 * self.half_length;
|
let cylinder_surface = TAU * self.radius * 2.0 * self.half_length;
|
||||||
let capsule_surface = cylinder_surface + 4.0 * PI * self.radius * self.radius;
|
let capsule_surface = cylinder_surface + 4.0 * PI * self.radius * self.radius;
|
||||||
if capsule_surface > 0.0 {
|
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 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)
|
Vec3::new(x, y, z)
|
||||||
} else {
|
} else {
|
||||||
let sphere = Sphere::new(self.radius);
|
let sphere = Sphere::new(self.radius);
|
||||||
@ -574,7 +578,7 @@ impl<P: Primitive2d + Measured2d + ShapeSample<Output = Vec2>> ShapeSample for E
|
|||||||
|
|
||||||
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::Output {
|
fn sample_interior<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::Output {
|
||||||
let base_point = self.base_shape.sample_interior(rng);
|
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)
|
base_point.extend(depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,7 +586,7 @@ impl<P: Primitive2d + Measured2d + ShapeSample<Output = Vec2>> ShapeSample for E
|
|||||||
let base_area = self.base_shape.area();
|
let base_area = self.base_shape.area();
|
||||||
let total_area = self.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 {
|
match random {
|
||||||
x if x < base_area => self.base_shape.sample_interior(rng).extend(self.half_depth),
|
x if x < base_area => self.base_shape.sample_interior(rng).extend(self.half_depth),
|
||||||
x if x < 2. * base_area => self
|
x if x < 2. * base_area => self
|
||||||
@ -592,7 +596,7 @@ impl<P: Primitive2d + Measured2d + ShapeSample<Output = Vec2>> ShapeSample for E
|
|||||||
_ => self
|
_ => self
|
||||||
.base_shape
|
.base_shape
|
||||||
.sample_boundary(rng)
|
.sample_boundary(rng)
|
||||||
.extend(rng.gen_range(-self.half_depth..self.half_depth)),
|
.extend(rng.random_range(-self.half_depth..self.half_depth)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
//! 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`],
|
//! 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.
|
//! an ergonomic extension to that functionality which permits the omission of type annotations.
|
||||||
//!
|
//!
|
||||||
//! For instance:
|
//! 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};
|
//! # use bevy_math::{Dir3, sampling::FromRng};
|
||||||
//! let mut rng = StdRng::seed_from_u64(7313429298);
|
//! let mut rng = StdRng::seed_from_u64(7313429298);
|
||||||
//! // Random direction using thread-local rng
|
//! // Random direction using thread-local rng
|
||||||
//! let random_direction1: Dir3 = random();
|
//! let random_direction1: Dir3 = random();
|
||||||
//!
|
//!
|
||||||
//! // Random direction using the rng constructed above
|
//! // 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
|
//! // The same as the previous but with different syntax
|
||||||
//! let random_direction3 = Dir3::from_rng(&mut rng);
|
//! let random_direction3 = Dir3::from_rng(&mut rng);
|
||||||
//!
|
//!
|
||||||
//! // Five random directions, using Standard explicitly
|
//! // Five random directions, using StandardUniform explicitly
|
||||||
//! let many_random_directions: Vec<Dir3> = rng.sample_iter(Standard).take(5).collect();
|
//! let many_random_directions: Vec<Dir3> = rng.sample_iter(StandardUniform).take(5).collect();
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use core::f32::consts::TAU;
|
use core::f32::consts::TAU;
|
||||||
@ -28,11 +28,11 @@ use crate::{
|
|||||||
Dir2, Dir3, Dir3A, Quat, Rot2, ShapeSample, Vec3A,
|
Dir2, Dir3, Dir3A, Quat, Rot2, ShapeSample, Vec3A,
|
||||||
};
|
};
|
||||||
use rand::{
|
use rand::{
|
||||||
distributions::{Distribution, Standard},
|
distr::{Distribution, StandardUniform},
|
||||||
Rng,
|
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.
|
/// uniformly from an [`Rng`] by a method in its own namespace.
|
||||||
///
|
///
|
||||||
/// Example
|
/// Example
|
||||||
@ -45,15 +45,15 @@ use rand::{
|
|||||||
pub trait FromRng
|
pub trait FromRng
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
Standard: Distribution<Self>,
|
StandardUniform: Distribution<Self>,
|
||||||
{
|
{
|
||||||
/// Construct a value of this type uniformly at random using `rng` as the source of randomness.
|
/// Construct a value of this type uniformly at random using `rng` as the source of randomness.
|
||||||
fn from_rng<R: Rng + ?Sized>(rng: &mut R) -> Self {
|
fn from_rng<R: Rng + ?Sized>(rng: &mut R) -> Self {
|
||||||
rng.r#gen()
|
rng.random()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Distribution<Dir2> for Standard {
|
impl Distribution<Dir2> for StandardUniform {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Dir2 {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Dir2 {
|
||||||
let circle = Circle::new(1.0);
|
let circle = Circle::new(1.0);
|
||||||
@ -64,7 +64,7 @@ impl Distribution<Dir2> for Standard {
|
|||||||
|
|
||||||
impl FromRng for Dir2 {}
|
impl FromRng for Dir2 {}
|
||||||
|
|
||||||
impl Distribution<Dir3> for Standard {
|
impl Distribution<Dir3> for StandardUniform {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Dir3 {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Dir3 {
|
||||||
let sphere = Sphere::new(1.0);
|
let sphere = Sphere::new(1.0);
|
||||||
@ -75,7 +75,7 @@ impl Distribution<Dir3> for Standard {
|
|||||||
|
|
||||||
impl FromRng for Dir3 {}
|
impl FromRng for Dir3 {}
|
||||||
|
|
||||||
impl Distribution<Dir3A> for Standard {
|
impl Distribution<Dir3A> for StandardUniform {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Dir3A {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Dir3A {
|
||||||
let sphere = Sphere::new(1.0);
|
let sphere = Sphere::new(1.0);
|
||||||
@ -86,10 +86,10 @@ impl Distribution<Dir3A> for Standard {
|
|||||||
|
|
||||||
impl FromRng for Dir3A {}
|
impl FromRng for Dir3A {}
|
||||||
|
|
||||||
impl Distribution<Rot2> for Standard {
|
impl Distribution<Rot2> for StandardUniform {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Rot2 {
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Rot2 {
|
||||||
let angle = rng.gen_range(0.0..TAU);
|
let angle = rng.random_range(0.0..TAU);
|
||||||
Rot2::radians(angle)
|
Rot2::radians(angle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ wgpu-types = { version = "25", default-features = false }
|
|||||||
serde = { version = "1", default-features = false, features = [
|
serde = { version = "1", default-features = false, features = [
|
||||||
"derive",
|
"derive",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
hexasphere = "15.0"
|
hexasphere = "16.0"
|
||||||
thiserror = { version = "2", default-features = false }
|
thiserror = { version = "2", default-features = false }
|
||||||
tracing = { version = "0.1", default-features = false, features = ["std"] }
|
tracing = { version = "0.1", default-features = false, features = ["std"] }
|
||||||
derive_more = { version = "2", default-features = false, features = ["from"] }
|
derive_more = { version = "2", default-features = false, features = ["from"] }
|
||||||
|
@ -22,7 +22,7 @@ std = ["glam/std"]
|
|||||||
libm = ["glam/libm", "dep:libm"]
|
libm = ["glam/libm", "dep:libm"]
|
||||||
|
|
||||||
[dependencies]
|
[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 }
|
libm = { version = "0.2", default-features = false, optional = true }
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
|
@ -65,8 +65,8 @@ rayon = { version = "1", default-features = false, optional = true }
|
|||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
web-time = { version = "1.1", default-features = false, optional = true }
|
web-time = { version = "1.1", default-features = false, optional = true }
|
||||||
getrandom = { version = "0.2.0", default-features = false, optional = true, features = [
|
getrandom = { version = "0.3.0", default-features = false, optional = true, features = [
|
||||||
"js",
|
"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]
|
[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]
|
||||||
|
@ -97,7 +97,7 @@ derive_more = { version = "2", default-features = false, features = ["from"] }
|
|||||||
serde = { version = "1", default-features = false, features = ["alloc"] }
|
serde = { version = "1", default-features = false, features = ["alloc"] }
|
||||||
assert_type_match = "0.1.1"
|
assert_type_match = "0.1.1"
|
||||||
smallvec = { version = "1", default-features = false, optional = true }
|
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",
|
"serde",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
petgraph = { version = "0.8", features = ["serde-1"], optional = true }
|
petgraph = { version = "0.8", features = ["serde-1"], optional = true }
|
||||||
|
@ -108,7 +108,7 @@ downcast-rs = { version = "2", default-features = false, features = ["std"] }
|
|||||||
thiserror = { version = "2", default-features = false }
|
thiserror = { version = "2", default-features = false }
|
||||||
derive_more = { version = "2", default-features = false, features = ["from"] }
|
derive_more = { version = "2", default-features = false, features = ["from"] }
|
||||||
futures-lite = "2.0.1"
|
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.
|
# For wgpu profiling using tracing. Use `RUST_LOG=info` to also capture the wgpu spans.
|
||||||
profiling = { version = "1", features = [
|
profiling = { version = "1", features = [
|
||||||
"profile-with-tracing",
|
"profile-with-tracing",
|
||||||
|
@ -102,9 +102,9 @@ fn draw(
|
|||||||
if *i == 0 {
|
if *i == 0 {
|
||||||
// Generate a random color on first run.
|
// Generate a random color on first run.
|
||||||
*draw_color = Color::linear_rgb(
|
*draw_color = Color::linear_rgb(
|
||||||
seeded_rng.0.r#gen(),
|
seeded_rng.0.random(),
|
||||||
seeded_rng.0.r#gen(),
|
seeded_rng.0.random(),
|
||||||
seeded_rng.0.r#gen(),
|
seeded_rng.0.random(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,9 +129,9 @@ fn draw(
|
|||||||
let tolerance = 1.0 / 255.0;
|
let tolerance = 1.0 / 255.0;
|
||||||
if old_color.distance(&draw_color) <= tolerance {
|
if old_color.distance(&draw_color) <= tolerance {
|
||||||
*draw_color = Color::linear_rgb(
|
*draw_color = Color::linear_rgb(
|
||||||
seeded_rng.0.r#gen(),
|
seeded_rng.0.random(),
|
||||||
seeded_rng.0.r#gen(),
|
seeded_rng.0.random(),
|
||||||
seeded_rng.0.r#gen(),
|
seeded_rng.0.random(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ fn setup(mut commands: Commands, assets: Res<AssetServer>) {
|
|||||||
let chunk_size = UVec2::splat(64);
|
let chunk_size = UVec2::splat(64);
|
||||||
let tile_display_size = UVec2::splat(8);
|
let tile_display_size = UVec2::splat(8);
|
||||||
let indices: Vec<Option<u16>> = (0..chunk_size.element_product())
|
let indices: Vec<Option<u16>> = (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) })
|
.map(|i| if i == 0 { None } else { Some(i - 1) })
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -73,8 +73,8 @@ fn update_tilemap(
|
|||||||
|
|
||||||
if timer.just_finished() {
|
if timer.just_finished() {
|
||||||
for _ in 0..50 {
|
for _ in 0..50 {
|
||||||
let index = rng.gen_range(0..indices.len());
|
let index = rng.random_range(0..indices.len());
|
||||||
indices[index] = Some(rng.gen_range(0..5));
|
indices[index] = Some(rng.random_range(0..5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,9 @@ fn setup(
|
|||||||
let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
|
let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
|
||||||
for i in 0..num_obs {
|
for i in 0..num_obs {
|
||||||
for j 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_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(
|
let transform = Transform::from_xyz(
|
||||||
(-num_obs + 1) as f32 / 2.0 + i as f32,
|
(-num_obs + 1) as f32 / 2.0 + i as f32,
|
||||||
-0.2,
|
-0.2,
|
||||||
|
@ -57,9 +57,9 @@ fn setup(
|
|||||||
|
|
||||||
commands.spawn_batch(
|
commands.spawn_batch(
|
||||||
std::iter::repeat_with(move || {
|
std::iter::repeat_with(move || {
|
||||||
let x = rng.gen_range(-5.0..5.0);
|
let x = rng.random_range(-5.0..5.0);
|
||||||
let y = rng.gen_range(0.0..3.0);
|
let y = rng.random_range(0.0..3.0);
|
||||||
let z = rng.gen_range(-5.0..5.0);
|
let z = rng.random_range(-5.0..5.0);
|
||||||
|
|
||||||
(
|
(
|
||||||
Mesh3d(cube_mesh.clone()),
|
Mesh3d(cube_mesh.clone()),
|
||||||
|
@ -50,14 +50,14 @@ fn observe_on_step(
|
|||||||
let translation = transforms.get(trigger.target()).unwrap().translation();
|
let translation = transforms.get(trigger.target()).unwrap().translation();
|
||||||
// Spawn a bunch of particles.
|
// Spawn a bunch of particles.
|
||||||
for _ in 0..14 {
|
for _ in 0..14 {
|
||||||
let horizontal = seeded_rng.0.r#gen::<Dir2>() * seeded_rng.0.gen_range(8.0..12.0);
|
let horizontal = seeded_rng.0.random::<Dir2>() * seeded_rng.0.random_range(8.0..12.0);
|
||||||
let vertical = seeded_rng.0.gen_range(0.0..4.0);
|
let vertical = seeded_rng.0.random_range(0.0..4.0);
|
||||||
let size = seeded_rng.0.gen_range(0.2..1.0);
|
let size = seeded_rng.0.random_range(0.2..1.0);
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Particle {
|
Particle {
|
||||||
lifetime_timer: Timer::from_seconds(
|
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,
|
TimerMode::Once,
|
||||||
),
|
),
|
||||||
size,
|
size,
|
||||||
|
@ -169,9 +169,9 @@ fn setup(
|
|||||||
Mesh3d(mesh.clone()),
|
Mesh3d(mesh.clone()),
|
||||||
MeshMaterial3d(materials.add(StandardMaterial {
|
MeshMaterial3d(materials.add(StandardMaterial {
|
||||||
base_color: Color::srgb(
|
base_color: Color::srgb(
|
||||||
rng.gen_range(0.0..1.0),
|
rng.random_range(0.0..1.0),
|
||||||
rng.gen_range(0.0..1.0),
|
rng.random_range(0.0..1.0),
|
||||||
rng.gen_range(0.0..1.0),
|
rng.random_range(0.0..1.0),
|
||||||
),
|
),
|
||||||
base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
|
base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
|
||||||
..default()
|
..default()
|
||||||
|
@ -59,7 +59,7 @@ fn spawn_tasks(mut commands: Commands) {
|
|||||||
// spawn() can be used to poll for the result
|
// spawn() can be used to poll for the result
|
||||||
let entity = commands.spawn_empty().id();
|
let entity = commands.spawn_empty().id();
|
||||||
let task = thread_pool.spawn(async move {
|
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. :)
|
// Pretend this is a time-intensive function. :)
|
||||||
async_std::task::sleep(duration).await;
|
async_std::task::sleep(duration).await;
|
||||||
|
@ -36,7 +36,7 @@ fn setup(mut commands: Commands) {
|
|||||||
// This is where you could connect to an external data source
|
// 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`
|
// 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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ fn setup(mut commands: Commands) {
|
|||||||
|
|
||||||
fn change_component(time: Res<Time>, mut query: Query<(Entity, &mut MyComponent)>) {
|
fn change_component(time: Res<Time>, mut query: Query<(Entity, &mut MyComponent)>) {
|
||||||
for (entity, mut component) in &mut query {
|
for (entity, mut component) in &mut query {
|
||||||
if rand::thread_rng().gen_bool(0.1) {
|
if rand::rng().random_bool(0.1) {
|
||||||
let new_component = MyComponent(time.elapsed_secs().round());
|
let new_component = MyComponent(time.elapsed_secs().round());
|
||||||
info!("New value: {new_component:?} {entity}");
|
info!("New value: {new_component:?} {entity}");
|
||||||
// Change detection occurs on mutable dereference, and does not consider whether or not
|
// Change detection occurs on mutable dereference, and does not consider whether or not
|
||||||
@ -51,7 +51,7 @@ fn change_component(time: Res<Time>, mut query: Query<(Entity, &mut MyComponent)
|
|||||||
/// locations.
|
/// locations.
|
||||||
fn change_component_2(time: Res<Time>, mut query: Query<(Entity, &mut MyComponent)>) {
|
fn change_component_2(time: Res<Time>, mut query: Query<(Entity, &mut MyComponent)>) {
|
||||||
for (entity, mut component) in &mut query {
|
for (entity, mut component) in &mut query {
|
||||||
if rand::thread_rng().gen_bool(0.1) {
|
if rand::rng().random_bool(0.1) {
|
||||||
let new_component = MyComponent(time.elapsed_secs().round());
|
let new_component = MyComponent(time.elapsed_secs().round());
|
||||||
info!("New value: {new_component:?} {entity}");
|
info!("New value: {new_component:?} {entity}");
|
||||||
component.set_if_neq(new_component);
|
component.set_if_neq(new_component);
|
||||||
@ -61,7 +61,7 @@ fn change_component_2(time: Res<Time>, mut query: Query<(Entity, &mut MyComponen
|
|||||||
|
|
||||||
/// Change detection concepts for components apply similarly to resources.
|
/// Change detection concepts for components apply similarly to resources.
|
||||||
fn change_resource(time: Res<Time>, mut my_resource: ResMut<MyResource>) {
|
fn change_resource(time: Res<Time>, mut my_resource: ResMut<MyResource>) {
|
||||||
if rand::thread_rng().gen_bool(0.1) {
|
if rand::rng().random_bool(0.1) {
|
||||||
let new_resource = MyResource(time.elapsed_secs().round());
|
let new_resource = MyResource(time.elapsed_secs().round());
|
||||||
info!("New value: {new_resource:?}");
|
info!("New value: {new_resource:?}");
|
||||||
my_resource.set_if_neq(new_resource);
|
my_resource.set_if_neq(new_resource);
|
||||||
|
@ -5,7 +5,7 @@ use bevy::ecs::{error::warn, world::DeferredWorld};
|
|||||||
use bevy::math::sampling::UniformMeshSampler;
|
use bevy::math::sampling::UniformMeshSampler;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use rand::distributions::Distribution;
|
use rand::distr::Distribution;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
|
||||||
|
@ -91,15 +91,18 @@ fn user_input(
|
|||||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
) {
|
) {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
if keyboard_input.just_pressed(KeyCode::KeyA) {
|
if keyboard_input.just_pressed(KeyCode::KeyA) {
|
||||||
let texture = asset_server.load("textures/simplespace/enemy_A.png");
|
let texture = asset_server.load("textures/simplespace/enemy_A.png");
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Enemy {
|
Enemy {
|
||||||
origin: Vec2::new(rng.gen_range(-200.0..200.0), rng.gen_range(-200.0..200.0)),
|
origin: Vec2::new(
|
||||||
radius: rng.gen_range(50.0..150.0),
|
rng.random_range(-200.0..200.0),
|
||||||
rotation: rng.gen_range(0.0..std::f32::consts::TAU),
|
rng.random_range(-200.0..200.0),
|
||||||
rotation_speed: rng.gen_range(0.5..1.5),
|
),
|
||||||
|
radius: rng.random_range(50.0..150.0),
|
||||||
|
rotation: rng.random_range(0.0..std::f32::consts::TAU),
|
||||||
|
rotation_speed: rng.random_range(0.5..1.5),
|
||||||
},
|
},
|
||||||
Sprite {
|
Sprite {
|
||||||
image: texture,
|
image: texture,
|
||||||
|
@ -50,34 +50,34 @@ fn generate_bodies(
|
|||||||
// This isn't strictly required in practical use unless you need your app to be deterministic.
|
// This isn't strictly required in practical use unless you need your app to be deterministic.
|
||||||
let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
|
let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
|
||||||
for _ in 0..NUM_BODIES {
|
for _ in 0..NUM_BODIES {
|
||||||
let radius: f32 = rng.gen_range(0.1..0.7);
|
let radius: f32 = rng.random_range(0.1..0.7);
|
||||||
let mass_value = FloatPow::cubed(radius) * 10.;
|
let mass_value = FloatPow::cubed(radius) * 10.;
|
||||||
|
|
||||||
let position = Vec3::new(
|
let position = Vec3::new(
|
||||||
rng.gen_range(-1.0..1.0),
|
rng.random_range(-1.0..1.0),
|
||||||
rng.gen_range(-1.0..1.0),
|
rng.random_range(-1.0..1.0),
|
||||||
rng.gen_range(-1.0..1.0),
|
rng.random_range(-1.0..1.0),
|
||||||
)
|
)
|
||||||
.normalize()
|
.normalize()
|
||||||
* ops::cbrt(rng.gen_range(0.2f32..1.0))
|
* ops::cbrt(rng.random_range(0.2f32..1.0))
|
||||||
* 15.;
|
* 15.;
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
BodyBundle {
|
BodyBundle {
|
||||||
mesh: Mesh3d(mesh.clone()),
|
mesh: Mesh3d(mesh.clone()),
|
||||||
material: MeshMaterial3d(materials.add(Color::srgb(
|
material: MeshMaterial3d(materials.add(Color::srgb(
|
||||||
rng.gen_range(color_range.clone()),
|
rng.random_range(color_range.clone()),
|
||||||
rng.gen_range(color_range.clone()),
|
rng.random_range(color_range.clone()),
|
||||||
rng.gen_range(color_range.clone()),
|
rng.random_range(color_range.clone()),
|
||||||
))),
|
))),
|
||||||
mass: Mass(mass_value),
|
mass: Mass(mass_value),
|
||||||
acceleration: Acceleration(Vec3::ZERO),
|
acceleration: Acceleration(Vec3::ZERO),
|
||||||
last_pos: LastPos(
|
last_pos: LastPos(
|
||||||
position
|
position
|
||||||
- Vec3::new(
|
- Vec3::new(
|
||||||
rng.gen_range(vel_range.clone()),
|
rng.random_range(vel_range.clone()),
|
||||||
rng.gen_range(vel_range.clone()),
|
rng.random_range(vel_range.clone()),
|
||||||
rng.gen_range(vel_range.clone()),
|
rng.random_range(vel_range.clone()),
|
||||||
) * time.timestep().as_secs_f32(),
|
) * time.timestep().as_secs_f32(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use bevy::{log::LogPlugin, prelude::*, time::common_conditions::on_timer};
|
use bevy::{log::LogPlugin, prelude::*, time::common_conditions::on_timer};
|
||||||
use rand::{seq::IteratorRandom, thread_rng, Rng};
|
use rand::{rng, seq::IteratorRandom, Rng};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
@ -69,9 +69,9 @@ struct Armor(u16);
|
|||||||
|
|
||||||
/// A normal bevy system that attacks a piece of the goblin's armor on a timer.
|
/// A normal bevy system that attacks a piece of the goblin's armor on a timer.
|
||||||
fn attack_armor(entities: Query<Entity, With<Armor>>, mut commands: Commands) {
|
fn attack_armor(entities: Query<Entity, With<Armor>>, mut commands: Commands) {
|
||||||
let mut rng = thread_rng();
|
let mut rng = rng();
|
||||||
if let Some(target) = entities.iter().choose(&mut rng) {
|
if let Some(target) = entities.iter().choose(&mut rng) {
|
||||||
let damage = rng.gen_range(1..20);
|
let damage = rng.random_range(1..20);
|
||||||
commands.trigger_targets(Attack { damage }, target);
|
commands.trigger_targets(Attack { damage }, target);
|
||||||
info!("⚔️ Attack for {} damage", damage);
|
info!("⚔️ Attack for {} damage", damage);
|
||||||
}
|
}
|
||||||
|
@ -52,10 +52,10 @@ impl Mine {
|
|||||||
fn random(rand: &mut ChaCha8Rng) -> Self {
|
fn random(rand: &mut ChaCha8Rng) -> Self {
|
||||||
Mine {
|
Mine {
|
||||||
pos: Vec2::new(
|
pos: Vec2::new(
|
||||||
(rand.r#gen::<f32>() - 0.5) * 1200.0,
|
(rand.random::<f32>() - 0.5) * 1200.0,
|
||||||
(rand.r#gen::<f32>() - 0.5) * 600.0,
|
(rand.random::<f32>() - 0.5) * 600.0,
|
||||||
),
|
),
|
||||||
size: 4.0 + rand.r#gen::<f32>() * 16.0,
|
size: 4.0 + rand.random::<f32>() * 16.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ fn spawn_system(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||||||
Sprite::from_image(texture.clone()),
|
Sprite::from_image(texture.clone()),
|
||||||
Transform::from_scale(Vec3::splat(0.1))
|
Transform::from_scale(Vec3::splat(0.1))
|
||||||
.with_translation(Vec2::splat(0.0).extend(z as f32)),
|
.with_translation(Vec2::splat(0.0).extend(z as f32)),
|
||||||
Velocity(20.0 * Vec2::new(rng.r#gen::<f32>() - 0.5, rng.r#gen::<f32>() - 0.5)),
|
Velocity(20.0 * Vec2::new(rng.random::<f32>() - 0.5, rng.random::<f32>() - 0.5)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
|
|||||||
// This isn't strictly required in practical use unless you need your app to be deterministic.
|
// This isn't strictly required in practical use unless you need your app to be deterministic.
|
||||||
ChaCha8Rng::seed_from_u64(19878367467713)
|
ChaCha8Rng::seed_from_u64(19878367467713)
|
||||||
} else {
|
} else {
|
||||||
ChaCha8Rng::from_entropy()
|
ChaCha8Rng::from_os_rng()
|
||||||
};
|
};
|
||||||
|
|
||||||
// reset the game state
|
// reset the game state
|
||||||
@ -137,7 +137,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
|
|||||||
.map(|j| {
|
.map(|j| {
|
||||||
(0..BOARD_SIZE_I)
|
(0..BOARD_SIZE_I)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let height = rng.gen_range(-0.1..0.1);
|
let height = rng.random_range(-0.1..0.1);
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
DespawnOnExitState(GameState::Playing),
|
DespawnOnExitState(GameState::Playing),
|
||||||
Transform::from_xyz(i as f32, height - 0.2, j as f32),
|
Transform::from_xyz(i as f32, height - 0.2, j as f32),
|
||||||
@ -330,8 +330,8 @@ fn spawn_bonus(
|
|||||||
|
|
||||||
// ensure bonus doesn't spawn on the player
|
// ensure bonus doesn't spawn on the player
|
||||||
loop {
|
loop {
|
||||||
game.bonus.i = rng.gen_range(0..BOARD_SIZE_I);
|
game.bonus.i = rng.random_range(0..BOARD_SIZE_I);
|
||||||
game.bonus.j = rng.gen_range(0..BOARD_SIZE_J);
|
game.bonus.j = rng.random_range(0..BOARD_SIZE_J);
|
||||||
if game.bonus.i != game.player.i || game.bonus.j != game.player.j {
|
if game.bonus.i != game.player.i || game.bonus.j != game.player.j {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -96,16 +96,16 @@ fn setup_contributor_selection(
|
|||||||
|
|
||||||
for (name, num_commits) in contribs {
|
for (name, num_commits) in contribs {
|
||||||
let transform = Transform::from_xyz(
|
let transform = Transform::from_xyz(
|
||||||
rng.gen_range(-400.0..400.0),
|
rng.random_range(-400.0..400.0),
|
||||||
rng.gen_range(0.0..400.0),
|
rng.random_range(0.0..400.0),
|
||||||
rng.r#gen(),
|
rng.random(),
|
||||||
);
|
);
|
||||||
let dir = rng.gen_range(-1.0..1.0);
|
let dir = rng.random_range(-1.0..1.0);
|
||||||
let velocity = Vec3::new(dir * 500.0, 0.0, 0.0);
|
let velocity = Vec3::new(dir * 500.0, 0.0, 0.0);
|
||||||
let hue = name_to_hue(&name);
|
let hue = name_to_hue(&name);
|
||||||
|
|
||||||
// Some sprites should be flipped for variety
|
// Some sprites should be flipped for variety
|
||||||
let flipped = rng.r#gen();
|
let flipped = rng.random();
|
||||||
|
|
||||||
let entity = commands
|
let entity = commands
|
||||||
.spawn((
|
.spawn((
|
||||||
@ -274,7 +274,7 @@ fn collisions(
|
|||||||
transform.translation.y = collision_area.min.y;
|
transform.translation.y = collision_area.min.y;
|
||||||
|
|
||||||
// How high this birb will bounce.
|
// How high this birb will bounce.
|
||||||
let bounce_height = rng.gen_range(min_bounce_height..=max_bounce_height);
|
let bounce_height = rng.random_range(min_bounce_height..=max_bounce_height);
|
||||||
|
|
||||||
// Apply the velocity that would bounce the birb up to bounce_height.
|
// Apply the velocity that would bounce the birb up to bounce_height.
|
||||||
velocity.translation.y = (bounce_height * GRAVITY * 2.).sqrt();
|
velocity.translation.y = (bounce_height * GRAVITY * 2.).sqrt();
|
||||||
|
@ -147,22 +147,22 @@ fn random_transform(rng: &mut impl Rng) -> Transform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn random_translation(rng: &mut impl Rng) -> Vec3 {
|
fn random_translation(rng: &mut impl Rng) -> Vec3 {
|
||||||
let x = rng.r#gen::<f32>() * (TRANSLATION_BOUND_UPPER_X - TRANSLATION_BOUND_LOWER_X)
|
let x = rng.random::<f32>() * (TRANSLATION_BOUND_UPPER_X - TRANSLATION_BOUND_LOWER_X)
|
||||||
+ TRANSLATION_BOUND_LOWER_X;
|
+ TRANSLATION_BOUND_LOWER_X;
|
||||||
let y = rng.r#gen::<f32>() * (TRANSLATION_BOUND_UPPER_Y - TRANSLATION_BOUND_LOWER_Y)
|
let y = rng.random::<f32>() * (TRANSLATION_BOUND_UPPER_Y - TRANSLATION_BOUND_LOWER_Y)
|
||||||
+ TRANSLATION_BOUND_LOWER_Y;
|
+ TRANSLATION_BOUND_LOWER_Y;
|
||||||
let z = rng.r#gen::<f32>() * (TRANSLATION_BOUND_UPPER_Z - TRANSLATION_BOUND_LOWER_Z)
|
let z = rng.random::<f32>() * (TRANSLATION_BOUND_UPPER_Z - TRANSLATION_BOUND_LOWER_Z)
|
||||||
+ TRANSLATION_BOUND_LOWER_Z;
|
+ TRANSLATION_BOUND_LOWER_Z;
|
||||||
|
|
||||||
Vec3::new(x, y, z)
|
Vec3::new(x, y, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn random_scale(rng: &mut impl Rng) -> Vec3 {
|
fn random_scale(rng: &mut impl Rng) -> Vec3 {
|
||||||
let x_factor_log = rng.r#gen::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG)
|
let x_factor_log = rng.random::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG)
|
||||||
+ SCALING_BOUND_LOWER_LOG;
|
+ SCALING_BOUND_LOWER_LOG;
|
||||||
let y_factor_log = rng.r#gen::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG)
|
let y_factor_log = rng.random::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG)
|
||||||
+ SCALING_BOUND_LOWER_LOG;
|
+ SCALING_BOUND_LOWER_LOG;
|
||||||
let z_factor_log = rng.r#gen::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG)
|
let z_factor_log = rng.random::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG)
|
||||||
+ SCALING_BOUND_LOWER_LOG;
|
+ SCALING_BOUND_LOWER_LOG;
|
||||||
|
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
@ -186,14 +186,14 @@ fn elerp(v1: Vec3, v2: Vec3, t: f32) -> Vec3 {
|
|||||||
|
|
||||||
fn random_rotation(rng: &mut impl Rng) -> Quat {
|
fn random_rotation(rng: &mut impl Rng) -> Quat {
|
||||||
let dir = random_direction(rng);
|
let dir = random_direction(rng);
|
||||||
let angle = rng.r#gen::<f32>() * 2. * PI;
|
let angle = rng.random::<f32>() * 2. * PI;
|
||||||
|
|
||||||
Quat::from_axis_angle(dir, angle)
|
Quat::from_axis_angle(dir, angle)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn random_direction(rng: &mut impl Rng) -> Vec3 {
|
fn random_direction(rng: &mut impl Rng) -> Vec3 {
|
||||||
let height = rng.r#gen::<f32>() * 2. - 1.;
|
let height = rng.random::<f32>() * 2. - 1.;
|
||||||
let theta = rng.r#gen::<f32>() * 2. * PI;
|
let theta = rng.random::<f32>() * 2. * PI;
|
||||||
|
|
||||||
build_direction(height, theta)
|
build_direction(height, theta)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use bevy::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
render::mesh::SphereKind,
|
render::mesh::SphereKind,
|
||||||
};
|
};
|
||||||
use rand::{distributions::Distribution, SeedableRng};
|
use rand::{distr::Distribution, SeedableRng};
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -8,7 +8,7 @@ use bevy::{
|
|||||||
math::prelude::*,
|
math::prelude::*,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use rand::{seq::SliceRandom, Rng, SeedableRng};
|
use rand::{seq::IndexedRandom, Rng, SeedableRng};
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -614,7 +614,7 @@ fn despawn_points(
|
|||||||
|
|
||||||
let rng = &mut random_source.0;
|
let rng = &mut random_source.0;
|
||||||
// Skip a random amount of points to ensure random despawning
|
// Skip a random amount of points to ensure random despawning
|
||||||
let skip = rng.gen_range(0..counter.0);
|
let skip = rng.random_range(0..counter.0);
|
||||||
let despawn_amount = (counter.0 - MAX_POINTS).min(100);
|
let despawn_amount = (counter.0 - MAX_POINTS).min(100);
|
||||||
counter.0 -= samples
|
counter.0 -= samples
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -87,8 +87,7 @@ fn update(
|
|||||||
1.0,
|
1.0,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.collect::<Vec<[f32; 4]>>()
|
.collect::<Vec<[f32; 4]>>(),
|
||||||
.as_slice(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use bevy::{
|
|||||||
window::{PresentMode, WindowResolution},
|
window::{PresentMode, WindowResolution},
|
||||||
winit::{UpdateMode, WinitSettings},
|
winit::{UpdateMode, WinitSettings},
|
||||||
};
|
};
|
||||||
use rand::{seq::SliceRandom, Rng, SeedableRng};
|
use rand::{seq::IndexedRandom, Rng, SeedableRng};
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
|
||||||
const BIRDS_PER_SECOND: u32 = 10000;
|
const BIRDS_PER_SECOND: u32 = 10000;
|
||||||
@ -345,7 +345,7 @@ fn mouse_handler(
|
|||||||
let rng = rng.as_mut().unwrap();
|
let rng = rng.as_mut().unwrap();
|
||||||
|
|
||||||
if mouse_button_input.just_released(MouseButton::Left) {
|
if mouse_button_input.just_released(MouseButton::Left) {
|
||||||
counter.color = Color::linear_rgb(rng.r#gen(), rng.r#gen(), rng.r#gen());
|
counter.color = Color::linear_rgb(rng.random(), rng.random(), rng.random());
|
||||||
}
|
}
|
||||||
|
|
||||||
if mouse_button_input.pressed(MouseButton::Left) {
|
if mouse_button_input.pressed(MouseButton::Left) {
|
||||||
@ -371,7 +371,7 @@ fn bird_velocity_transform(
|
|||||||
waves: Option<usize>,
|
waves: Option<usize>,
|
||||||
dt: f32,
|
dt: f32,
|
||||||
) -> (Transform, Vec3) {
|
) -> (Transform, Vec3) {
|
||||||
let mut velocity = Vec3::new(MAX_VELOCITY * (velocity_rng.r#gen::<f32>() - 0.5), 0., 0.);
|
let mut velocity = Vec3::new(MAX_VELOCITY * (velocity_rng.random::<f32>() - 0.5), 0., 0.);
|
||||||
|
|
||||||
if let Some(waves) = waves {
|
if let Some(waves) = waves {
|
||||||
// Step the movement and handle collisions as if the wave had been spawned at fixed time intervals
|
// Step the movement and handle collisions as if the wave had been spawned at fixed time intervals
|
||||||
@ -414,7 +414,7 @@ fn spawn_birds(
|
|||||||
let bird_z = if args.ordered_z {
|
let bird_z = if args.ordered_z {
|
||||||
(current_count + count) as f32 * 0.00001
|
(current_count + count) as f32 * 0.00001
|
||||||
} else {
|
} else {
|
||||||
bird_resources.transform_rng.r#gen::<f32>()
|
bird_resources.transform_rng.random::<f32>()
|
||||||
};
|
};
|
||||||
|
|
||||||
let (transform, velocity) = bird_velocity_transform(
|
let (transform, velocity) = bird_velocity_transform(
|
||||||
@ -427,9 +427,9 @@ fn spawn_birds(
|
|||||||
|
|
||||||
let color = if args.vary_per_instance {
|
let color = if args.vary_per_instance {
|
||||||
Color::linear_rgb(
|
Color::linear_rgb(
|
||||||
bird_resources.color_rng.r#gen(),
|
bird_resources.color_rng.random(),
|
||||||
bird_resources.color_rng.r#gen(),
|
bird_resources.color_rng.random(),
|
||||||
bird_resources.color_rng.r#gen(),
|
bird_resources.color_rng.random(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
color
|
color
|
||||||
@ -457,7 +457,7 @@ fn spawn_birds(
|
|||||||
let bird_z = if args.ordered_z {
|
let bird_z = if args.ordered_z {
|
||||||
(current_count + count) as f32 * 0.00001
|
(current_count + count) as f32 * 0.00001
|
||||||
} else {
|
} else {
|
||||||
bird_resources.transform_rng.r#gen::<f32>()
|
bird_resources.transform_rng.random::<f32>()
|
||||||
};
|
};
|
||||||
|
|
||||||
let (transform, velocity) = bird_velocity_transform(
|
let (transform, velocity) = bird_velocity_transform(
|
||||||
@ -492,9 +492,9 @@ fn spawn_birds(
|
|||||||
|
|
||||||
counter.count += spawn_count;
|
counter.count += spawn_count;
|
||||||
counter.color = Color::linear_rgb(
|
counter.color = Color::linear_rgb(
|
||||||
bird_resources.color_rng.r#gen(),
|
bird_resources.color_rng.random(),
|
||||||
bird_resources.color_rng.r#gen(),
|
bird_resources.color_rng.random(),
|
||||||
bird_resources.color_rng.r#gen(),
|
bird_resources.color_rng.random(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,7 +575,12 @@ fn init_textures(textures: &mut Vec<Handle<Image>>, args: &Args, images: &mut As
|
|||||||
// This isn't strictly required in practical use unless you need your app to be deterministic.
|
// This isn't strictly required in practical use unless you need your app to be deterministic.
|
||||||
let mut color_rng = ChaCha8Rng::seed_from_u64(42);
|
let mut color_rng = ChaCha8Rng::seed_from_u64(42);
|
||||||
while textures.len() < args.material_texture_count {
|
while textures.len() < args.material_texture_count {
|
||||||
let pixel = [color_rng.r#gen(), color_rng.r#gen(), color_rng.r#gen(), 255];
|
let pixel = [
|
||||||
|
color_rng.random(),
|
||||||
|
color_rng.random(),
|
||||||
|
color_rng.random(),
|
||||||
|
255,
|
||||||
|
];
|
||||||
textures.push(images.add(Image::new_fill(
|
textures.push(images.add(Image::new_fill(
|
||||||
Extent3d {
|
Extent3d {
|
||||||
width: BIRD_TEXTURE_SIZE as u32,
|
width: BIRD_TEXTURE_SIZE as u32,
|
||||||
@ -623,7 +628,7 @@ fn init_materials(
|
|||||||
materials.extend(
|
materials.extend(
|
||||||
std::iter::repeat_with(|| {
|
std::iter::repeat_with(|| {
|
||||||
assets.add(ColorMaterial {
|
assets.add(ColorMaterial {
|
||||||
color: Color::srgb_u8(color_rng.r#gen(), color_rng.r#gen(), color_rng.r#gen()),
|
color: Color::srgb_u8(color_rng.random(), color_rng.random(), color_rng.random()),
|
||||||
texture: textures.choose(&mut texture_rng).cloned(),
|
texture: textures.choose(&mut texture_rng).cloned(),
|
||||||
alpha_mode,
|
alpha_mode,
|
||||||
..default()
|
..default()
|
||||||
|
@ -55,7 +55,7 @@ fn setup(
|
|||||||
) {
|
) {
|
||||||
warn!(include_str!("warning_string.txt"));
|
warn!(include_str!("warning_string.txt"));
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
let tile_size = Vec2::splat(64.0);
|
let tile_size = Vec2::splat(64.0);
|
||||||
let map_size = Vec2::splat(320.0);
|
let map_size = Vec2::splat(320.0);
|
||||||
@ -75,11 +75,11 @@ fn setup(
|
|||||||
for y in -half_y..half_y {
|
for y in -half_y..half_y {
|
||||||
for x in -half_x..half_x {
|
for x in -half_x..half_x {
|
||||||
let position = Vec2::new(x as f32, y as f32);
|
let position = Vec2::new(x as f32, y as f32);
|
||||||
let translation = (position * tile_size).extend(rng.r#gen::<f32>());
|
let translation = (position * tile_size).extend(rng.random::<f32>());
|
||||||
let rotation = Quat::from_rotation_z(rng.r#gen::<f32>());
|
let rotation = Quat::from_rotation_z(rng.random::<f32>());
|
||||||
let scale = Vec3::splat(rng.r#gen::<f32>() * 2.0);
|
let scale = Vec3::splat(rng.random::<f32>() * 2.0);
|
||||||
let mut timer = Timer::from_seconds(0.1, TimerMode::Repeating);
|
let mut timer = Timer::from_seconds(0.1, TimerMode::Repeating);
|
||||||
timer.set_elapsed(Duration::from_secs_f32(rng.r#gen::<f32>()));
|
timer.set_elapsed(Duration::from_secs_f32(rng.random::<f32>()));
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Sprite {
|
Sprite {
|
||||||
|
@ -28,7 +28,7 @@ use bevy::{
|
|||||||
MinimalPlugins,
|
MinimalPlugins,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rand::prelude::{Rng, SeedableRng, SliceRandom};
|
use rand::prelude::{IndexedRandom, Rng, SeedableRng};
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
use std::{alloc::Layout, mem::ManuallyDrop, num::Wrapping};
|
use std::{alloc::Layout, mem::ManuallyDrop, num::Wrapping};
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ fn stress_test(num_entities: u32, num_components: u32, num_systems: u32) {
|
|||||||
// fill the schedule with systems
|
// fill the schedule with systems
|
||||||
let mut schedule = Schedule::new(Update);
|
let mut schedule = Schedule::new(Update);
|
||||||
for _ in 1..=num_systems {
|
for _ in 1..=num_systems {
|
||||||
let num_access_components = rng.gen_range(1..10);
|
let num_access_components = rng.random_range(1..10);
|
||||||
let access_components: Vec<ComponentId> = component_ids
|
let access_components: Vec<ComponentId> = component_ids
|
||||||
.choose_multiple(&mut rng, num_access_components)
|
.choose_multiple(&mut rng, num_access_components)
|
||||||
.copied()
|
.copied()
|
||||||
@ -127,7 +127,7 @@ fn stress_test(num_entities: u32, num_components: u32, num_systems: u32) {
|
|||||||
|
|
||||||
// spawn a bunch of entities
|
// spawn a bunch of entities
|
||||||
for _ in 1..=num_entities {
|
for _ in 1..=num_entities {
|
||||||
let num_components = rng.gen_range(1..10);
|
let num_components = rng.random_range(1..10);
|
||||||
let components: Vec<ComponentId> = component_ids
|
let components: Vec<ComponentId> = component_ids
|
||||||
.choose_multiple(&mut rng, num_components)
|
.choose_multiple(&mut rng, num_components)
|
||||||
.copied()
|
.copied()
|
||||||
@ -139,7 +139,7 @@ fn stress_test(num_entities: u32, num_components: u32, num_systems: u32) {
|
|||||||
// But we do want to deallocate the memory when values is dropped.
|
// But we do want to deallocate the memory when values is dropped.
|
||||||
let mut values: Vec<ManuallyDrop<u8>> = components
|
let mut values: Vec<ManuallyDrop<u8>> = components
|
||||||
.iter()
|
.iter()
|
||||||
.map(|_id| ManuallyDrop::new(rng.gen_range(0..255)))
|
.map(|_id| ManuallyDrop::new(rng.random_range(0..255)))
|
||||||
.collect();
|
.collect();
|
||||||
let ptrs: Vec<OwningPtr> = values
|
let ptrs: Vec<OwningPtr> = values
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
@ -25,7 +25,7 @@ use bevy::{
|
|||||||
window::{PresentMode, WindowResolution},
|
window::{PresentMode, WindowResolution},
|
||||||
winit::{UpdateMode, WinitSettings},
|
winit::{UpdateMode, WinitSettings},
|
||||||
};
|
};
|
||||||
use rand::{seq::SliceRandom, Rng, SeedableRng};
|
use rand::{seq::IndexedRandom, Rng, SeedableRng};
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
|
||||||
#[derive(FromArgs, Resource)]
|
#[derive(FromArgs, Resource)]
|
||||||
@ -262,7 +262,13 @@ fn init_textures(args: &Args, images: &mut Assets<Image>) -> Vec<Handle<Image>>
|
|||||||
// This isn't strictly required in practical use unless you need your app to be deterministic.
|
// This isn't strictly required in practical use unless you need your app to be deterministic.
|
||||||
let mut color_rng = ChaCha8Rng::seed_from_u64(42);
|
let mut color_rng = ChaCha8Rng::seed_from_u64(42);
|
||||||
let color_bytes: Vec<u8> = (0..(args.material_texture_count * 4))
|
let color_bytes: Vec<u8> = (0..(args.material_texture_count * 4))
|
||||||
.map(|i| if (i % 4) == 3 { 255 } else { color_rng.r#gen() })
|
.map(|i| {
|
||||||
|
if (i % 4) == 3 {
|
||||||
|
255
|
||||||
|
} else {
|
||||||
|
color_rng.random()
|
||||||
|
}
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
color_bytes
|
color_bytes
|
||||||
.chunks(4)
|
.chunks(4)
|
||||||
@ -307,7 +313,11 @@ fn init_materials(
|
|||||||
materials.extend(
|
materials.extend(
|
||||||
std::iter::repeat_with(|| {
|
std::iter::repeat_with(|| {
|
||||||
assets.add(StandardMaterial {
|
assets.add(StandardMaterial {
|
||||||
base_color: Color::srgb_u8(color_rng.r#gen(), color_rng.r#gen(), color_rng.r#gen()),
|
base_color: Color::srgb_u8(
|
||||||
|
color_rng.random(),
|
||||||
|
color_rng.random(),
|
||||||
|
color_rng.random(),
|
||||||
|
),
|
||||||
base_color_texture: textures.choose(&mut texture_rng).cloned(),
|
base_color_texture: textures.choose(&mut texture_rng).cloned(),
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
@ -326,7 +336,7 @@ fn init_meshes(args: &Args, assets: &mut Assets<Mesh>) -> Vec<(Handle<Mesh>, Tra
|
|||||||
let mut radius_rng = ChaCha8Rng::seed_from_u64(42);
|
let mut radius_rng = ChaCha8Rng::seed_from_u64(42);
|
||||||
let mut variant = 0;
|
let mut variant = 0;
|
||||||
std::iter::repeat_with(|| {
|
std::iter::repeat_with(|| {
|
||||||
let radius = radius_rng.gen_range(0.25f32..=0.75f32);
|
let radius = radius_rng.random_range(0.25f32..=0.75f32);
|
||||||
let (handle, transform) = match variant % 15 {
|
let (handle, transform) = match variant % 15 {
|
||||||
0 => (
|
0 => (
|
||||||
assets.add(Cuboid {
|
assets.add(Cuboid {
|
||||||
|
@ -13,7 +13,7 @@ use bevy::{
|
|||||||
window::{PresentMode, WindowResolution},
|
window::{PresentMode, WindowResolution},
|
||||||
winit::{UpdateMode, WinitSettings},
|
winit::{UpdateMode, WinitSettings},
|
||||||
};
|
};
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{rng, Rng};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
@ -72,7 +72,7 @@ fn setup(
|
|||||||
|
|
||||||
// Spawn N_LIGHTS many lights
|
// Spawn N_LIGHTS many lights
|
||||||
commands.spawn_batch((0..N_LIGHTS).map(move |i| {
|
commands.spawn_batch((0..N_LIGHTS).map(move |i| {
|
||||||
let mut rng = thread_rng();
|
let mut rng = rng();
|
||||||
|
|
||||||
let spherical_polar_theta_phi = fibonacci_spiral_on_sphere(golden_ratio, i, N_LIGHTS);
|
let spherical_polar_theta_phi = fibonacci_spiral_on_sphere(golden_ratio, i, N_LIGHTS);
|
||||||
let unit_sphere_p = spherical_polar_to_cartesian(spherical_polar_theta_phi);
|
let unit_sphere_p = spherical_polar_to_cartesian(spherical_polar_theta_phi);
|
||||||
@ -81,7 +81,7 @@ fn setup(
|
|||||||
PointLight {
|
PointLight {
|
||||||
range: LIGHT_RADIUS,
|
range: LIGHT_RADIUS,
|
||||||
intensity: LIGHT_INTENSITY,
|
intensity: LIGHT_INTENSITY,
|
||||||
color: Color::hsl(rng.gen_range(0.0..360.0), 1.0, 0.5),
|
color: Color::hsl(rng.random_range(0.0..360.0), 1.0, 0.5),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Transform::from_translation((RADIUS as f64 * unit_sphere_p).as_vec3()),
|
Transform::from_translation((RADIUS as f64 * unit_sphere_p).as_vec3()),
|
||||||
|
@ -58,7 +58,7 @@ fn main() {
|
|||||||
fn setup(mut commands: Commands, assets: Res<AssetServer>, color_tint: Res<ColorTint>) {
|
fn setup(mut commands: Commands, assets: Res<AssetServer>, color_tint: Res<ColorTint>) {
|
||||||
warn!(include_str!("warning_string.txt"));
|
warn!(include_str!("warning_string.txt"));
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
let tile_size = Vec2::splat(64.0);
|
let tile_size = Vec2::splat(64.0);
|
||||||
let map_size = Vec2::splat(320.0);
|
let map_size = Vec2::splat(320.0);
|
||||||
@ -77,16 +77,16 @@ fn setup(mut commands: Commands, assets: Res<AssetServer>, color_tint: Res<Color
|
|||||||
for y in -half_y..half_y {
|
for y in -half_y..half_y {
|
||||||
for x in -half_x..half_x {
|
for x in -half_x..half_x {
|
||||||
let position = Vec2::new(x as f32, y as f32);
|
let position = Vec2::new(x as f32, y as f32);
|
||||||
let translation = (position * tile_size).extend(rng.r#gen::<f32>());
|
let translation = (position * tile_size).extend(rng.random::<f32>());
|
||||||
let rotation = Quat::from_rotation_z(rng.r#gen::<f32>());
|
let rotation = Quat::from_rotation_z(rng.random::<f32>());
|
||||||
let scale = Vec3::splat(rng.r#gen::<f32>() * 2.0);
|
let scale = Vec3::splat(rng.random::<f32>() * 2.0);
|
||||||
|
|
||||||
sprites.push((
|
sprites.push((
|
||||||
Sprite {
|
Sprite {
|
||||||
image: sprite_handle.clone(),
|
image: sprite_handle.clone(),
|
||||||
custom_size: Some(tile_size),
|
custom_size: Some(tile_size),
|
||||||
color: if color_tint.0 {
|
color: if color_tint.0 {
|
||||||
COLORS[rng.gen_range(0..3)]
|
COLORS[rng.random_range(0..3)]
|
||||||
} else {
|
} else {
|
||||||
Color::WHITE
|
Color::WHITE
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@ use bevy::{
|
|||||||
|
|
||||||
use argh::FromArgs;
|
use argh::FromArgs;
|
||||||
use rand::{
|
use rand::{
|
||||||
seq::{IteratorRandom, SliceRandom},
|
seq::{IndexedRandom, IteratorRandom},
|
||||||
Rng, SeedableRng,
|
Rng, SeedableRng,
|
||||||
};
|
};
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
@ -122,10 +122,10 @@ fn setup(mut commands: Commands, font: Res<FontHandle>, args: Res<Args>) {
|
|||||||
for y in -half_y..half_y {
|
for y in -half_y..half_y {
|
||||||
for x in -half_x..half_x {
|
for x in -half_x..half_x {
|
||||||
let position = Vec2::new(x as f32, y as f32);
|
let position = Vec2::new(x as f32, y as f32);
|
||||||
let translation = (position * tile_size).extend(rng.r#gen::<f32>());
|
let translation = (position * tile_size).extend(rng.random::<f32>());
|
||||||
let rotation = Quat::from_rotation_z(rng.r#gen::<f32>());
|
let rotation = Quat::from_rotation_z(rng.random::<f32>());
|
||||||
let scale = Vec3::splat(rng.r#gen::<f32>() * 2.0);
|
let scale = Vec3::splat(rng.random::<f32>() * 2.0);
|
||||||
let color = Hsla::hsl(rng.gen_range(0.0..360.0), 0.8, 0.8);
|
let color = Hsla::hsl(rng.random_range(0.0..360.0), 0.8, 0.8);
|
||||||
|
|
||||||
text2ds.push((
|
text2ds.push((
|
||||||
Text2d(random_text(&mut rng, &args)),
|
Text2d(random_text(&mut rng, &args)),
|
||||||
|
@ -290,7 +290,7 @@ fn setup(mut commands: Commands, cfg: Res<Cfg>) {
|
|||||||
}
|
}
|
||||||
TestCase::Humanoids { active, inactive } => {
|
TestCase::Humanoids { active, inactive } => {
|
||||||
let mut result = InsertResult::default();
|
let mut result = InsertResult::default();
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
for _ in 0..active {
|
for _ in 0..active {
|
||||||
result.combine(spawn_tree(
|
result.combine(spawn_tree(
|
||||||
@ -298,8 +298,8 @@ fn setup(mut commands: Commands, cfg: Res<Cfg>) {
|
|||||||
&mut commands,
|
&mut commands,
|
||||||
&cfg.update_filter,
|
&cfg.update_filter,
|
||||||
Transform::from_xyz(
|
Transform::from_xyz(
|
||||||
rng.r#gen::<f32>() * 500.0 - 250.0,
|
rng.random::<f32>() * 500.0 - 250.0,
|
||||||
rng.r#gen::<f32>() * 500.0 - 250.0,
|
rng.random::<f32>() * 500.0 - 250.0,
|
||||||
0.0,
|
0.0,
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -315,8 +315,8 @@ fn setup(mut commands: Commands, cfg: Res<Cfg>) {
|
|||||||
..cfg.update_filter
|
..cfg.update_filter
|
||||||
},
|
},
|
||||||
Transform::from_xyz(
|
Transform::from_xyz(
|
||||||
rng.r#gen::<f32>() * 500.0 - 250.0,
|
rng.random::<f32>() * 500.0 - 250.0,
|
||||||
rng.r#gen::<f32>() * 500.0 - 250.0,
|
rng.random::<f32>() * 500.0 - 250.0,
|
||||||
0.0,
|
0.0,
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -379,7 +379,7 @@ fn spawn_tree(
|
|||||||
ents.push(commands.spawn(root_transform).id());
|
ents.push(commands.spawn(root_transform).id());
|
||||||
|
|
||||||
let mut result = InsertResult::default();
|
let mut result = InsertResult::default();
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
// used to count through the number of children (used only for visual layout)
|
// used to count through the number of children (used only for visual layout)
|
||||||
let mut child_idx: Vec<u16> = vec![0; count];
|
let mut child_idx: Vec<u16> = vec![0; count];
|
||||||
|
|
||||||
@ -405,7 +405,7 @@ fn spawn_tree(
|
|||||||
let mut cmd = commands.spawn_empty();
|
let mut cmd = commands.spawn_empty();
|
||||||
|
|
||||||
// check whether or not to update this node
|
// check whether or not to update this node
|
||||||
let update = (rng.r#gen::<f32>() <= update_filter.probability)
|
let update = (rng.random::<f32>() <= update_filter.probability)
|
||||||
&& (depth >= update_filter.min_depth && depth <= update_filter.max_depth);
|
&& (depth >= update_filter.min_depth && depth <= update_filter.max_depth);
|
||||||
|
|
||||||
if update {
|
if update {
|
||||||
|
@ -75,8 +75,8 @@ fn setup(
|
|||||||
));
|
));
|
||||||
|
|
||||||
// Initialize random axes
|
// Initialize random axes
|
||||||
let first = seeded_rng.r#gen();
|
let first = seeded_rng.random();
|
||||||
let second = seeded_rng.r#gen();
|
let second = seeded_rng.random();
|
||||||
commands.spawn(RandomAxes(first, second));
|
commands.spawn(RandomAxes(first, second));
|
||||||
|
|
||||||
// Finally, our ship that is going to rotate
|
// Finally, our ship that is going to rotate
|
||||||
@ -165,8 +165,8 @@ fn handle_keypress(
|
|||||||
) {
|
) {
|
||||||
if keyboard.just_pressed(KeyCode::KeyR) {
|
if keyboard.just_pressed(KeyCode::KeyR) {
|
||||||
// Randomize the target axes
|
// Randomize the target axes
|
||||||
let first = seeded_rng.0.r#gen();
|
let first = seeded_rng.0.random();
|
||||||
let second = seeded_rng.0.r#gen();
|
let second = seeded_rng.0.random();
|
||||||
**random_axes = RandomAxes(first, second);
|
**random_axes = RandomAxes(first, second);
|
||||||
|
|
||||||
// Stop the ship and set it up to transform from its present orientation to the new one
|
// Stop the ship and set it up to transform from its present orientation to the new one
|
||||||
|
@ -74,7 +74,7 @@ fn text_update_system(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for mut text in &mut query {
|
for mut text in &mut query {
|
||||||
let c = seeded_rng.r#gen::<u8>() as char;
|
let c = seeded_rng.random::<u8>() as char;
|
||||||
let string = &mut **text;
|
let string = &mut **text;
|
||||||
if !string.contains(c) {
|
if !string.contains(c) {
|
||||||
string.push(c);
|
string.push(c);
|
||||||
|
10
release-content/migration-guides/glam-rand-upgrades.md
Normal file
10
release-content/migration-guides/glam-rand-upgrades.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: Updated `glam` and `rand` versions.
|
||||||
|
pull_requests: [18047]
|
||||||
|
---
|
||||||
|
|
||||||
|
With newer versions of `glam` & `encase`, the updated versions don't seem to have introduced breakages, though as always, best to consult their docs [1](https://docs.rs/glam/latest/glam/) [2](https://docs.rs/encase/0.11.0/encase/) for any changes.
|
||||||
|
|
||||||
|
`rand` changes are more extensive, with changes such as `thread_rng()` -> `rng()`, `from_entropy()` -> `from_os_rng()`, and so forth. `RngCore` is now split into infallible `RngCore` and fallible `TryRngCore`, and the `distributions` module has been renamed to `distr`. Most of this affects only internals, and doesn't directly affect Bevy's APIs. For the full set of changes, see `rand` [migration notes](https://rust-random.github.io/book/update-0.9.html).
|
||||||
|
|
||||||
|
`getrandom` is also updated, and will require additional configuration when building Bevy for WASM/Web (if also using `rand`). The full details of how to do this is in the `getrandom` docs [1](https://github.com/rust-random/getrandom?tab=readme-ov-file#opt-in-backends) [2](https://github.com/rust-random/getrandom?tab=readme-ov-file#webassembly-support).
|
@ -89,7 +89,9 @@ fn main() {
|
|||||||
sh,
|
sh,
|
||||||
"cargo build {parameters...} --target wasm32-unknown-unknown --example {example}"
|
"cargo build {parameters...} --target wasm32-unknown-unknown --example {example}"
|
||||||
);
|
);
|
||||||
cmd.run().expect("Error building example");
|
cmd.env("RUSTFLAGS", "--cfg getrandom_backend=\"wasm_js\"")
|
||||||
|
.run()
|
||||||
|
.expect("Error building example");
|
||||||
|
|
||||||
cmd!(
|
cmd!(
|
||||||
sh,
|
sh,
|
||||||
|
Loading…
Reference in New Issue
Block a user