Improve gizmo axes example (#12335)

# Objective

- Improve example from #12299 
- Make it frame rate independent
- Make it not randomly random

## Solution

- Transitions between transforms will take 2 seconds instead of 100
frames
- Random is seeded
This commit is contained in:
François 2024-03-09 00:05:11 +01:00 committed by GitHub
parent 52e3f2007b
commit 7546624471
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,9 +1,11 @@
//! This example demonstrates the implementation and behavior of the axes gizmo. //! This example demonstrates the implementation and behavior of the axes gizmo.
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::primitives::Aabb; use bevy::render::primitives::Aabb;
use rand::random; use rand::{rngs::StdRng, Rng, SeedableRng};
use std::f32::consts::PI; use std::f32::consts::PI;
const TRANSITION_DURATION: f32 = 2.0;
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
@ -27,15 +29,20 @@ struct TransformTracking {
/// The target transform of the cube during the move /// The target transform of the cube during the move
target_transform: Transform, target_transform: Transform,
/// The progress of the cube during the move in percentage points /// The progress of the cube during the move in seconds
progress: u16, progress: f32,
} }
#[derive(Resource)]
struct SeededRng(StdRng);
fn setup( fn setup(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
let mut rng = StdRng::seed_from_u64(19878367467713);
// Lights... // Lights...
commands.spawn(PointLightBundle { commands.spawn(PointLightBundle {
point_light: PointLight { point_light: PointLight {
@ -62,8 +69,8 @@ fn setup(
ShowAxes, ShowAxes,
TransformTracking { TransformTracking {
initial_transform: default(), initial_transform: default(),
target_transform: random_transform(), target_transform: random_transform(&mut rng),
progress: 0, progress: 0.0,
}, },
)); ));
@ -76,8 +83,8 @@ fn setup(
ShowAxes, ShowAxes,
TransformTracking { TransformTracking {
initial_transform: default(), initial_transform: default(),
target_transform: random_transform(), target_transform: random_transform(&mut rng),
progress: 0, progress: 0.0,
}, },
)); ));
@ -88,6 +95,8 @@ fn setup(
transform: Transform::from_xyz(0., -2., 0.), transform: Transform::from_xyz(0., -2., 0.),
..default() ..default()
}); });
commands.insert_resource(SeededRng(rng));
} }
// This system draws the axes based on the cube's transform, with length based on the size of // This system draws the axes based on the cube's transform, with length based on the size of
@ -100,19 +109,24 @@ fn draw_axes(mut gizmos: Gizmos, query: Query<(&Transform, &Aabb), With<ShowAxes
} }
// This system changes the cubes' transforms to interpolate between random transforms // This system changes the cubes' transforms to interpolate between random transforms
fn move_cubes(mut query: Query<(&mut Transform, &mut TransformTracking)>) { fn move_cubes(
mut query: Query<(&mut Transform, &mut TransformTracking)>,
time: Res<Time>,
mut rng: ResMut<SeededRng>,
) {
for (mut transform, mut tracking) in &mut query { for (mut transform, mut tracking) in &mut query {
let t = tracking.progress as f32 / 100.; *transform = interpolate_transforms(
tracking.initial_transform,
tracking.target_transform,
tracking.progress / TRANSITION_DURATION,
);
*transform = if tracking.progress < TRANSITION_DURATION {
interpolate_transforms(tracking.initial_transform, tracking.target_transform, t); tracking.progress += time.delta_seconds();
if tracking.progress < 100 {
tracking.progress += 1;
} else { } else {
tracking.initial_transform = *transform; tracking.initial_transform = *transform;
tracking.target_transform = random_transform(); tracking.target_transform = random_transform(&mut rng.0);
tracking.progress = 0; tracking.progress = 0.0;
} }
} }
} }
@ -129,31 +143,31 @@ const TRANSLATION_BOUND_UPPER_Z: f32 = 6.;
const SCALING_BOUND_LOWER_LOG: f32 = -1.2; const SCALING_BOUND_LOWER_LOG: f32 = -1.2;
const SCALING_BOUND_UPPER_LOG: f32 = 1.2; const SCALING_BOUND_UPPER_LOG: f32 = 1.2;
fn random_transform() -> Transform { fn random_transform(rng: &mut impl Rng) -> Transform {
Transform { Transform {
translation: random_translation(), translation: random_translation(rng),
rotation: random_rotation(), rotation: random_rotation(rng),
scale: random_scale(), scale: random_scale(rng),
} }
} }
fn random_translation() -> Vec3 { fn random_translation(rng: &mut impl Rng) -> Vec3 {
let x = random::<f32>() * (TRANSLATION_BOUND_UPPER_X - TRANSLATION_BOUND_LOWER_X) let x = rng.gen::<f32>() * (TRANSLATION_BOUND_UPPER_X - TRANSLATION_BOUND_LOWER_X)
+ TRANSLATION_BOUND_LOWER_X; + TRANSLATION_BOUND_LOWER_X;
let y = random::<f32>() * (TRANSLATION_BOUND_UPPER_Y - TRANSLATION_BOUND_LOWER_Y) let y = rng.gen::<f32>() * (TRANSLATION_BOUND_UPPER_Y - TRANSLATION_BOUND_LOWER_Y)
+ TRANSLATION_BOUND_LOWER_Y; + TRANSLATION_BOUND_LOWER_Y;
let z = random::<f32>() * (TRANSLATION_BOUND_UPPER_Z - TRANSLATION_BOUND_LOWER_Z) let z = rng.gen::<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() -> Vec3 { fn random_scale(rng: &mut impl Rng) -> Vec3 {
let x_factor_log = random::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG) let x_factor_log = rng.gen::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG)
+ SCALING_BOUND_LOWER_LOG; + SCALING_BOUND_LOWER_LOG;
let y_factor_log = random::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG) let y_factor_log = rng.gen::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG)
+ SCALING_BOUND_LOWER_LOG; + SCALING_BOUND_LOWER_LOG;
let z_factor_log = random::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG) let z_factor_log = rng.gen::<f32>() * (SCALING_BOUND_UPPER_LOG - SCALING_BOUND_LOWER_LOG)
+ SCALING_BOUND_LOWER_LOG; + SCALING_BOUND_LOWER_LOG;
Vec3::new( Vec3::new(
@ -175,16 +189,16 @@ fn elerp(v1: Vec3, v2: Vec3, t: f32) -> Vec3 {
) )
} }
fn random_rotation() -> Quat { fn random_rotation(rng: &mut impl Rng) -> Quat {
let dir = random_direction(); let dir = random_direction(rng);
let angle = random::<f32>() * 2. * PI; let angle = rng.gen::<f32>() * 2. * PI;
Quat::from_axis_angle(dir, angle) Quat::from_axis_angle(dir, angle)
} }
fn random_direction() -> Vec3 { fn random_direction(rng: &mut impl Rng) -> Vec3 {
let height = random::<f32>() * 2. - 1.; let height = rng.gen::<f32>() * 2. - 1.;
let theta = random::<f32>() * 2. * PI; let theta = rng.gen::<f32>() * 2. * PI;
build_direction(height, theta) build_direction(height, theta)
} }