Skip to content

Commit

Permalink
Try with simple water as well
Browse files Browse the repository at this point in the history
  • Loading branch information
hakolao committed Apr 13, 2024
1 parent 5781fe1 commit 1c20389
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 13 deletions.
44 changes: 37 additions & 7 deletions examples/sand/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,28 +97,58 @@ impl Grid {
if !curr_sand.is_empty() && y as i32 - 1 >= 0 {
let below_index = self.index(x as i32, y as i32 - 1);
let below_sand = self.data[below_index].sand;
let swap_below = below_sand.is_empty();
let empty = Sand::empty();
let below = self.data[below_index];
let swap_below =
below_sand.is_empty() || (!curr_sand.is_water() && below_sand.is_water());
if swap_below {
self.draw_sand(x as i32, y as i32, empty);
self.draw_sand(x as i32, y as i32, below);
self.draw_sand(x as i32, y as i32 - 1, curr);
} else {
let p = rand::random::<f32>();
let mut is_swap = false;
if p > 0.5 && x as i32 - 1 >= 0 {
let left_diag_index = self.index(x as i32 - 1, y as i32 - 1);
let left_diag_sand = self.data[left_diag_index].sand;
let swap_left_diag = left_diag_sand.is_empty();
let left = self.data[left_diag_index];
let swap_left_diag = left_diag_sand.is_empty()
|| (!curr_sand.is_water() && left_diag_sand.is_water());
if swap_left_diag {
self.draw_sand(x as i32, y as i32, empty);
self.draw_sand(x as i32, y as i32, left);
self.draw_sand(x as i32 - 1, y as i32 - 1, curr);
is_swap = true;
}
} else if x as i32 + 1 < self.width as i32 {
let right_diag_index = self.index(x as i32 + 1, y as i32 - 1);
let right_diag_sand = self.data[right_diag_index].sand;
let swap_right_diag = right_diag_sand.is_empty();
let swap_right_diag = right_diag_sand.is_empty()
|| (!curr_sand.is_water() && right_diag_sand.is_water());
let right = self.data[right_diag_index];
if swap_right_diag {
self.draw_sand(x as i32, y as i32, empty);
self.draw_sand(x as i32, y as i32, right);
self.draw_sand(x as i32 + 1, y as i32 - 1, curr);
is_swap = true;
}
}
if !is_swap && curr_sand.is_water() {
let p = rand::random::<f32>();
if p > 0.5 && x as i32 - 1 >= 0 {
let left_index = self.index(x as i32 - 1, y as i32);
let left_sand = self.data[left_index].sand;
let left = self.data[left_index];
let swap_left = left_sand.is_empty();
if swap_left {
self.draw_sand(x as i32, y as i32, left);
self.draw_sand(x as i32 - 1, y as i32, curr);
}
} else if x as i32 + 1 < self.width as i32 {
let right_index = self.index(x as i32 + 1, y as i32);
let right_sand = self.data[right_index].sand;
let right = self.data[right_index];
let swap_right = right_sand.is_empty();
if swap_right {
self.draw_sand(x as i32, y as i32, right);
self.draw_sand(x as i32 + 1, y as i32, curr);
}
}
}
}
Expand Down
35 changes: 29 additions & 6 deletions examples/sand/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

mod grid;
mod sand;
mod timer;

use glam::Vec2;
use glass::{
Expand All @@ -11,18 +12,18 @@ use glass::{
Glass, GlassApp, GlassConfig, GlassContext, GlassError, RenderData,
};
use wgpu::{
Color, Limits, LoadOp, Operations, RenderPassColorAttachment, RenderPassDescriptor, StoreOp,
TextureViewDescriptor,
Color, Limits, LoadOp, Operations, PresentMode, RenderPassColorAttachment,
RenderPassDescriptor, StoreOp, TextureViewDescriptor,
};
use winit::{
event::{ElementState, Event, MouseButton, WindowEvent},
event_loop::EventLoopWindowTarget,
};

use crate::{grid::Grid, sand::SandType};
use crate::{grid::Grid, sand::SandType, timer::Timer};

const CANVAS_SIZE: u32 = 256;
const CANVAS_SCALE: u32 = 4;
const CANVAS_SIZE: u32 = 512;
const CANVAS_SCALE: u32 = 2;

fn main() -> Result<(), GlassError> {
Glass::new_and_run(config(), |_e, context| {
Expand All @@ -35,7 +36,9 @@ struct SandSim {
quad_pipeline: QuadPipeline,
cursor_pos: Vec2,
draw_sand: bool,
draw_water: bool,
draw_empty: bool,
timer: Timer,
}

impl SandSim {
Expand All @@ -54,7 +57,9 @@ impl SandSim {
quad_pipeline,
cursor_pos: Vec2::ZERO,
draw_sand: false,
draw_water: false,
draw_empty: false,
timer: Timer::new(),
}
}
}
Expand Down Expand Up @@ -90,13 +95,20 @@ impl GlassApp for SandSim {
} => {
self.draw_empty = state == &ElementState::Pressed;
}
WindowEvent::MouseInput {
button: MouseButton::Middle,
state,
..
} => {
self.draw_water = state == &ElementState::Pressed;
}
_ => (),
}
}
}

fn update(&mut self, context: &mut GlassContext) {
if self.draw_sand || self.draw_empty {
if self.draw_sand || self.draw_empty || self.draw_water {
let screen_size = context.primary_render_window().surface_size();
let scale_factor = context.primary_render_window().window().scale_factor() as f32;
let pos = cursor_to_canvas(
Expand All @@ -110,6 +122,8 @@ impl GlassApp for SandSim {
rounded.y,
if self.draw_sand {
SandType::Sand
} else if self.draw_water {
SandType::Water
} else {
SandType::Empty
},
Expand Down Expand Up @@ -171,6 +185,14 @@ impl GlassApp for SandSim {
);
}
}

fn end_of_frame(&mut self, context: &mut GlassContext) {
self.timer.update();
if let Some(w) = context.primary_render_window_maybe() {
w.window()
.set_title(&format!("Sand Grid - FPS: {:.2}", self.timer.avg_fps()));
}
}
}

fn cursor_to_canvas(cursor: Vec2, screen_width: f32, screen_height: f32) -> Vec2 {
Expand Down Expand Up @@ -213,6 +235,7 @@ fn config() -> GlassConfig {
window_configs: vec![WindowConfig {
width: CANVAS_SIZE * CANVAS_SCALE,
height: CANVAS_SIZE * CANVAS_SCALE,
present_mode: PresentMode::Immediate,
exit_on_esc: true,
..WindowConfig::default()
}],
Expand Down
14 changes: 14 additions & 0 deletions examples/sand/sand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ use glam::Vec2;
pub enum SandType {
Empty,
Sand,
Water,
}

impl SandType {
pub fn is_empty(&self) -> bool {
*self == SandType::Empty
}

pub fn is_water(&self) -> bool {
*self == SandType::Water
}
}

#[derive(Copy, Clone)]
Expand All @@ -24,6 +29,7 @@ impl Sand {
match sand {
SandType::Sand => Self::sand(pos),
SandType::Empty => Self::empty(),
SandType::Water => Self::water(),
}
}

Expand All @@ -36,6 +42,14 @@ impl Sand {
}
}

pub fn water() -> Sand {
let color = Color32::from_rgb(0x23, 0x89, 0xda);
Sand {
sand: SandType::Water,
color: Rgba::from(color),
}
}

pub fn empty() -> Sand {
Sand {
sand: SandType::Empty,
Expand Down
83 changes: 83 additions & 0 deletions examples/sand/timer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use std::time::Instant;

const NUM_TIME_SAMPLES: usize = 100;

/// A simple performance timer
#[derive(Debug, Copy, Clone)]
pub struct Timer {
time: Instant,
time_sum: f64,
avg_ms: f64,
num_updates: usize,
delta: f64,
}

impl Timer {
pub fn new() -> Self {
Self {
time: Instant::now(),
time_sum: 0.0,
avg_ms: 0.0,
num_updates: 0,
delta: 0.0,
}
}

#[allow(unused)]
pub fn start(&mut self) {
self.time = Instant::now()
}

#[allow(unused)]
pub fn end(&self) -> f64 {
self.time.elapsed().as_nanos() as f64 * 1.0e-6
}

#[allow(unused)]
pub fn time_since_last_update_sec(&self) -> f64 {
self.end() / 1000.0
}

pub fn update_with_diff(&mut self, diff: f64) {
self.delta = diff;
if self.num_updates >= NUM_TIME_SAMPLES {
self.avg_ms = self.time_sum / self.num_updates as f64;
// reset
self.time_sum = 0.0;
self.num_updates = 0;
}
self.time_sum += diff;
self.num_updates += 1;
}

pub fn update(&mut self) {
let diff = self.time.elapsed().as_nanos() as f64 * 1.0e-6;
self.update_with_diff(diff);
self.time = Instant::now();
}

#[allow(unused)]
pub fn dt(&self) -> f64 {
self.delta
}

#[allow(unused)]
pub fn dt_sec(&self) -> f64 {
self.delta / 1000.0
}

#[allow(unused)]
pub fn avg_ms(&self) -> f64 {
self.avg_ms
}

pub fn avg_fps(&self) -> f64 {
1000.0 / self.avg_ms
}
}

impl Default for Timer {
fn default() -> Self {
Timer::new()
}
}

0 comments on commit 1c20389

Please sign in to comment.