
Must follow VertexBufferDescriptorName_AttributeName format I_VertexBufferDescriptorName_AttributeName indicates that an attribute is instanced Currently all attributes must be defined in shaders or offsets will be incorrect.
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(),
|
|
},
|
|
Renderable {
|
|
instanced: true,
|
|
..Default::default()
|
|
},
|
|
mesh_handle,
|
|
LocalToWorld::identity(),
|
|
translation,
|
|
)],
|
|
);
|
|
}
|