mirror of
https://github.com/bevyengine/bevy
synced 2025-02-17 06:28:34 +00:00
I worked really hard to make ColorSource work, but sadly we need color to be instanceable and making it optional would add too much complexity. Maybe at some point in the future we can add it back. On the plus side, albedo color now modulates the albedo texture
173 lines
5.2 KiB
Rust
173 lines
5.2 KiB
Rust
use bevy::prelude::*;
|
|
use rand::{random, rngs::StdRng, Rng, SeedableRng};
|
|
|
|
struct Person;
|
|
|
|
struct Velocity {
|
|
pub value: math::Vec3,
|
|
}
|
|
|
|
struct NavigationPoint {
|
|
pub target: math::Vec3,
|
|
}
|
|
|
|
struct Wander {
|
|
pub duration_bounds: math::Vec2,
|
|
pub distance_bounds: math::Vec2,
|
|
pub duration: f32,
|
|
pub elapsed: f32,
|
|
}
|
|
|
|
fn main() {
|
|
AppBuilder::new()
|
|
.setup_world(setup)
|
|
.add_system(build_wander_system())
|
|
.add_system(build_navigate_system())
|
|
.add_system(build_move_system())
|
|
.add_system(bevy::diagnostics::build_fps_printer_system())
|
|
.run();
|
|
}
|
|
|
|
fn setup(world: &mut World, resources: &mut Resources) {
|
|
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
|
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
|
|
|
world.insert(
|
|
(),
|
|
vec![
|
|
// lights
|
|
(
|
|
Light::default(),
|
|
LocalToWorld::identity(),
|
|
Translation::new(4.0, -4.0, 5.0),
|
|
Rotation::from_euler_angles(0.0, 0.0, 0.0),
|
|
),
|
|
],
|
|
);
|
|
|
|
world.insert(
|
|
(),
|
|
vec![
|
|
// camera
|
|
(
|
|
Camera::new(CameraType::Projection {
|
|
fov: std::f32::consts::PI / 4.0,
|
|
near: 1.0,
|
|
far: 1000.0,
|
|
aspect_ratio: 1.0,
|
|
}),
|
|
ActiveCamera,
|
|
LocalToWorld(Mat4::look_at_rh(
|
|
Vec3::new(6.0, -40.0, 20.0),
|
|
Vec3::new(0.0, 0.0, 0.0),
|
|
Vec3::new(0.0, 0.0, 1.0),
|
|
)),
|
|
),
|
|
],
|
|
);
|
|
|
|
let mut rng = StdRng::from_entropy();
|
|
for _ in 0..70000 {
|
|
create_person(
|
|
world,
|
|
cube_handle,
|
|
Translation::new(rng.gen_range(-50.0, 50.0), 0.0, rng.gen_range(-50.0, 50.0)),
|
|
);
|
|
}
|
|
}
|
|
|
|
fn build_wander_system() -> Box<dyn Schedulable> {
|
|
let mut rng = StdRng::from_entropy();
|
|
|
|
SystemBuilder::new("Wander")
|
|
.read_resource::<Time>()
|
|
.with_query(<(
|
|
Read<Person>,
|
|
Read<Translation>,
|
|
Write<Wander>,
|
|
Write<NavigationPoint>,
|
|
)>::query())
|
|
.build(move |_, world, time, person_query| {
|
|
for (_, translation, mut wander, mut navigation_point) in person_query.iter_mut(world) {
|
|
wander.elapsed += time.delta_seconds;
|
|
if wander.elapsed >= wander.duration {
|
|
let direction = math::vec3(
|
|
rng.gen_range(-1.0, 1.0),
|
|
rng.gen_range(-1.0, 1.0),
|
|
rng.gen_range(0.0, 0.001),
|
|
)
|
|
.normalize();
|
|
let distance =
|
|
rng.gen_range(wander.distance_bounds.x(), wander.distance_bounds.y());
|
|
navigation_point.target = translation.0 + direction * distance;
|
|
wander.elapsed = 0.0;
|
|
wander.duration =
|
|
rng.gen_range(wander.duration_bounds.x(), wander.duration_bounds.y());
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
fn build_navigate_system() -> Box<dyn Schedulable> {
|
|
SystemBuilder::new("Navigate")
|
|
.with_query(<(
|
|
Read<Person>,
|
|
Write<Translation>,
|
|
Write<Velocity>,
|
|
Write<NavigationPoint>,
|
|
)>::query())
|
|
.build(move |_, world, _, person_query| {
|
|
for (_, translation, mut velocity, navigation_point) in person_query.iter_mut(world) {
|
|
let distance = navigation_point.target - translation.0;
|
|
if distance.length() > 0.01 {
|
|
let direction = distance.normalize();
|
|
velocity.value = direction * 2.0;
|
|
} else {
|
|
velocity.value = math::vec3(0.0, 0.0, 0.0);
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
fn build_move_system() -> Box<dyn Schedulable> {
|
|
SystemBuilder::new("Move")
|
|
.read_resource::<Time>()
|
|
.with_query(<(Write<Translation>, Read<Velocity>)>::query())
|
|
.build(move |_, world, time, person_query| {
|
|
for (mut translation, velocity) in person_query.iter_mut(world) {
|
|
translation.0 += velocity.value * time.delta_seconds;
|
|
}
|
|
})
|
|
}
|
|
|
|
fn create_person(world: &mut World, mesh_handle: Handle<Mesh>, translation: Translation) {
|
|
world.insert(
|
|
(),
|
|
vec![(
|
|
Person {},
|
|
Wander {
|
|
duration_bounds: math::vec2(3.0, 10.0),
|
|
distance_bounds: math::vec2(-50.0, 50.0),
|
|
elapsed: 0.0,
|
|
duration: 0.0,
|
|
},
|
|
NavigationPoint {
|
|
target: math::vec3(0.0, 0.0, 0.0),
|
|
},
|
|
Velocity {
|
|
value: math::vec3(0.0, 0.0, 0.0),
|
|
},
|
|
StandardMaterial {
|
|
albedo: (math::vec4(0.5, 0.3, 0.3, 1.0) * random::<f32>()).into(),
|
|
..Default::default()
|
|
},
|
|
Renderable {
|
|
instanced: true,
|
|
..Default::default()
|
|
},
|
|
mesh_handle,
|
|
LocalToWorld::identity(),
|
|
translation,
|
|
)],
|
|
);
|
|
}
|