Particle fountain
This commit is contained in:
parent
8b80192347
commit
50510e6946
|
@ -10,6 +10,7 @@ multimap = "0.8"
|
||||||
notify = "^4"
|
notify = "^4"
|
||||||
parking_lot = "^0.11"
|
parking_lot = "^0.11"
|
||||||
pollster = "0.2"
|
pollster = "0.2"
|
||||||
|
rand = "^0.8"
|
||||||
rayon = "1"
|
rayon = "1"
|
||||||
slab = "^0.4"
|
slab = "^0.4"
|
||||||
smallmap = "^1.0"
|
smallmap = "^1.0"
|
||||||
|
|
145
src/main.rs
145
src/main.rs
|
@ -5,6 +5,7 @@ use cyborg::storage::mesh::*;
|
||||||
use cyborg::viewport::*;
|
use cyborg::viewport::*;
|
||||||
use cyborg::Renderer;
|
use cyborg::Renderer;
|
||||||
use legion::*;
|
use legion::*;
|
||||||
|
use rand::prelude::*;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use winit::{
|
use winit::{
|
||||||
event::*,
|
event::*,
|
||||||
|
@ -12,6 +13,118 @@ use winit::{
|
||||||
window::WindowBuilder,
|
window::WindowBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DeltaTime {
|
||||||
|
pub dt: f32,
|
||||||
|
last_update: std::time::Instant,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DeltaTime {
|
||||||
|
fn default() -> Self {
|
||||||
|
DeltaTime {
|
||||||
|
dt: 0.0,
|
||||||
|
last_update: std::time::Instant::now(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpawnDistributions {
|
||||||
|
theta: rand::distributions::Uniform<f32>,
|
||||||
|
radius: rand::distributions::Uniform<f32>,
|
||||||
|
up: rand::distributions::Uniform<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SpawnDistributions {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
theta: rand::distributions::Uniform::new(0.0, std::f32::consts::TAU),
|
||||||
|
radius: rand::distributions::Uniform::new(4.0, 5.0),
|
||||||
|
up: rand::distributions::Uniform::new(10.0, 15.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Particle {
|
||||||
|
position: glam::Vec3A,
|
||||||
|
mass: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Velocity {
|
||||||
|
linear: glam::Vec3A,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[system]
|
||||||
|
fn update_dt(#[resource] dt: &mut DeltaTime) {
|
||||||
|
dt.dt = dt.last_update.elapsed().as_secs_f32();
|
||||||
|
dt.last_update = std::time::Instant::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[system(for_each)]
|
||||||
|
fn apply_gravity(#[resource] dt: &DeltaTime, velocity: &mut Velocity) {
|
||||||
|
const GRAVITY: f32 = 6.0;
|
||||||
|
velocity.linear.y -= GRAVITY * dt.dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[system(for_each)]
|
||||||
|
fn move_particles(#[resource] dt: &DeltaTime, particle: &mut Particle, velocity: &Velocity) {
|
||||||
|
particle.position += velocity.linear * (dt.dt / particle.mass);
|
||||||
|
// TODO angular velocity
|
||||||
|
}
|
||||||
|
|
||||||
|
#[system(for_each)]
|
||||||
|
fn respawn_particles(
|
||||||
|
#[resource] distributions: &SpawnDistributions,
|
||||||
|
particle: &mut Particle,
|
||||||
|
velocity: &mut Velocity,
|
||||||
|
) {
|
||||||
|
if particle.position.y < -10.0 {
|
||||||
|
particle.position = glam::Vec3A::ZERO;
|
||||||
|
let rng = &mut rand::thread_rng();
|
||||||
|
velocity.linear.y = distributions.up.sample(rng);
|
||||||
|
|
||||||
|
let theta = distributions.theta.sample(rng);
|
||||||
|
let radius = distributions.radius.sample(rng);
|
||||||
|
velocity.linear.x = theta.sin() * radius;
|
||||||
|
velocity.linear.z = theta.cos() * radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[system(for_each)]
|
||||||
|
fn update_transforms(transform: &mut cyborg::scene::Transform, particle: &Particle) {
|
||||||
|
transform.transform = glam::Mat4::from_translation(particle.position.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[system(for_each)]
|
||||||
|
fn update_debug(
|
||||||
|
draw_list: &mut cyborg::scene::DebugDrawList,
|
||||||
|
velocity: &Velocity,
|
||||||
|
) {
|
||||||
|
draw_list.clear();
|
||||||
|
draw_list.indices.extend_from_slice(&[0, 1]);
|
||||||
|
|
||||||
|
let color = [1.0, 1.0, 1.0];
|
||||||
|
|
||||||
|
draw_list.vertices.push(cyborg::scene::DebugVertex {
|
||||||
|
position: [0.0, 0.0, 0.0],
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
|
||||||
|
draw_list.vertices.push(cyborg::scene::DebugVertex {
|
||||||
|
position: velocity.linear.to_array(),
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_update_schedule() -> Schedule {
|
||||||
|
let mut builder = Schedule::builder();
|
||||||
|
builder.add_system(update_dt_system());
|
||||||
|
builder.add_system(apply_gravity_system());
|
||||||
|
builder.add_system(move_particles_system());
|
||||||
|
builder.add_system(respawn_particles_system());
|
||||||
|
builder.add_system(update_transforms_system());
|
||||||
|
builder.add_system(update_debug_system());
|
||||||
|
builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
|
@ -20,6 +133,10 @@ fn main() {
|
||||||
let mut world = World::new(Default::default());
|
let mut world = World::new(Default::default());
|
||||||
let mut resources = Resources::default();
|
let mut resources = Resources::default();
|
||||||
|
|
||||||
|
resources.insert::<DeltaTime>(Default::default());
|
||||||
|
resources.insert::<SpawnDistributions>(Default::default());
|
||||||
|
let mut update_schedule = build_update_schedule();
|
||||||
|
|
||||||
let renderer = Renderer::new(viewport.device.clone(), viewport.queue.clone());
|
let renderer = Renderer::new(viewport.device.clone(), viewport.queue.clone());
|
||||||
resources.insert(renderer);
|
resources.insert(renderer);
|
||||||
|
|
||||||
|
@ -76,7 +193,7 @@ fn main() {
|
||||||
data: bytemuck::cast_slice(&example_vertices).to_vec(),
|
data: bytemuck::cast_slice(&example_vertices).to_vec(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let example_indices: Vec<mesh::Index> = vec![0, 1, 2, 1, 2, 3, 2, 3, 0, 0, 2, 3];
|
let example_indices: Vec<mesh::Index> = vec![0, 1, 2, 1, 2, 3, 2, 3, 0, 0, 1, 3];
|
||||||
let example_indices = AttrBuffer {
|
let example_indices = AttrBuffer {
|
||||||
id: attributes.index,
|
id: attributes.index,
|
||||||
count: example_indices.len(),
|
count: example_indices.len(),
|
||||||
|
@ -90,21 +207,7 @@ fn main() {
|
||||||
|
|
||||||
drop(mesh_pass);
|
drop(mesh_pass);
|
||||||
|
|
||||||
let example_debug_draw = cyborg::scene::DebugDrawList {
|
let r = 6;
|
||||||
vertices: vec![
|
|
||||||
cyborg::scene::DebugVertex {
|
|
||||||
position: [0.0, 0.0, -0.5],
|
|
||||||
color: [1.0, 0.0, 0.0],
|
|
||||||
},
|
|
||||||
cyborg::scene::DebugVertex {
|
|
||||||
position: [0.0, 0.0, 0.5],
|
|
||||||
color: [0.0, 0.0, 1.0],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
indices: vec![0, 1],
|
|
||||||
};
|
|
||||||
|
|
||||||
let r = 4;
|
|
||||||
for x in -r..r {
|
for x in -r..r {
|
||||||
for y in -r..r {
|
for y in -r..r {
|
||||||
for z in -r..r {
|
for z in -r..r {
|
||||||
|
@ -115,7 +218,14 @@ fn main() {
|
||||||
mesh: example_mesh.clone(),
|
mesh: example_mesh.clone(),
|
||||||
},
|
},
|
||||||
cyborg::scene::Transform { transform },
|
cyborg::scene::Transform { transform },
|
||||||
example_debug_draw.clone(),
|
cyborg::scene::DebugDrawList::default(),
|
||||||
|
Particle {
|
||||||
|
position: translation.into(),
|
||||||
|
mass: 1.0,
|
||||||
|
},
|
||||||
|
Velocity {
|
||||||
|
linear: glam::Vec3A::ZERO,
|
||||||
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +247,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::MainEventsCleared => {
|
Event::MainEventsCleared => {
|
||||||
|
update_schedule.execute(&mut world, &mut resources);
|
||||||
shader_watcher.watch();
|
shader_watcher.watch();
|
||||||
flycam.update();
|
flycam.update();
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
|
|
|
@ -44,6 +44,11 @@ pub struct DebugDrawList {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugDrawList {
|
impl DebugDrawList {
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.vertices.clear();
|
||||||
|
self.indices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn merge(&mut self, other: &Self) {
|
pub fn merge(&mut self, other: &Self) {
|
||||||
self.vertices.extend_from_slice(&other.vertices);
|
self.vertices.extend_from_slice(&other.vertices);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ impl WinitViewport {
|
||||||
format: surface.get_preferred_format(&adapter).unwrap(),
|
format: surface.get_preferred_format(&adapter).unwrap(),
|
||||||
width: size.width,
|
width: size.width,
|
||||||
height: size.height,
|
height: size.height,
|
||||||
present_mode: wgpu::PresentMode::Fifo,
|
present_mode: wgpu::PresentMode::Mailbox,
|
||||||
};
|
};
|
||||||
surface.configure(&device, &config);
|
surface.configure(&device, &config);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue