From 78a6cbf031d9e3cbd87f2c7d49c8f27b7e447bb6 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Thu, 27 Nov 2025 23:26:23 +0100 Subject: [PATCH] Vertex drawing --- examples/cube.rs | 49 ++++++++++------------- src/renderer.rs | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 28 deletions(-) diff --git a/examples/cube.rs b/examples/cube.rs index 7d7bba1..d83c9f5 100644 --- a/examples/cube.rs +++ b/examples/cube.rs @@ -3,37 +3,30 @@ pub mod components; use osmium::{renderer::Point, terminal}; fn main() { - let (term_width, term_height) = crossterm::terminal::size().unwrap(); - let a = term_height - 3; - let engine = osmium::init(); - let my_rect = engine.entity(|r| { - r.draw_rect(0, 0, 1, 2, 0xff0000); - r.draw_rect(1, 0, 1, 2, 0x00ff00); - r.draw_rect(2, 0, 1, 2, 0x0000ff); - }); + engine.entity(|r| { + r.draw_vertex( + 0, + 0, + &[ + Point { x: 0, y: 0 }, + Point { x: 30, y: 0 }, + Point { x: 15, y: 8 }, + ], + 0x0000ff, + ); - my_rect.component(components::Velocity(Point { x: 0, y: 0 })); - my_rect.component(components::ZigZag(term_width - 3)); - - my_rect.set_position(0, term_height - 3); - - components::threads::tick(&engine); - components::threads::key(&engine); - - engine.on_event({ - let my_rect = my_rect.clone(); - move |e: &crossterm::event::Event| { - if let Some(key_event) = e.as_key_event() { - match key_event.code { - crossterm::event::KeyCode::Char(' ') => { - my_rect.component(components::Jumping(0, a)); - } - _ => {} - } - } - } + r.draw_vertex_outline( + 0, + 0, + &[ + Point { x: 0, y: 0 }, + Point { x: 30, y: 0 }, + Point { x: 15, y: 8 }, + ], + 0xff0000, + ); }); terminal::hide_cursor().unwrap(); diff --git a/src/renderer.rs b/src/renderer.rs index f485a98..d02d78c 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -23,6 +23,108 @@ impl Renderer { print_liner(self.pos.x + x, self.pos.y + y, &hex_bg(color), &rect); } + pub fn draw_pixel(&self, x: u16, y: u16, color: u32) { + print_liner(self.pos.x + x, self.pos.y + y, &hex_bg(color), &" \x1b[0m"); + } + + pub fn draw_line(&self, x0: i16, y0: i16, x1: i16, y1: i16, color: u32) { + let dx = (x1 - x0).abs(); + let sx = if x0 < x1 { 1 } else { -1 }; + let dy = -(y1 - y0).abs(); + let sy = if y0 < y1 { 1 } else { -1 }; + let mut err = dx + dy; + + let (mut x, mut y) = (x0, y0); + + loop { + self.draw_pixel(x as u16, y as u16, color); + + if x == x1 && y == y1 { + break; + } + + let e2 = 2 * err; + if e2 >= dy { + err += dy; + x += sx; + } + if e2 <= dx { + err += dx; + y += sy; + } + } + } + + pub fn draw_vertex_outline(&self, x: u16, y: u16, vertices: &[Point], color: u32) { + if vertices.len() < 2 { + return; + } + + for i in 0..vertices.len() { + let p0 = &vertices[i]; + let p1 = &vertices[(i + 1) % vertices.len()]; + + self.draw_line( + x as i16 + p0.x as i16, + y as i16 + p0.y as i16, + x as i16 + p1.x as i16, + y as i16 + p1.y as i16, + color, + ); + } + } + + pub fn draw_vertex(&self, x: u16, y: u16, vertices: &[Point], color: u32) { + if vertices.len() < 3 { + return; + } + + self.draw_vertex_outline(x, y, vertices, color); + + let pts: Vec<(i32, i32)> = vertices + .iter() + .map(|p| ((p.x + x) as i32, (p.y + y) as i32)) + .collect(); + + let min_y = pts.iter().map(|(_, y)| *y).min().unwrap(); + let max_y = pts.iter().map(|(_, y)| *y).max().unwrap(); + + for y in min_y..=max_y { + let mut intersections = Vec::::new(); + + for i in 0..pts.len() { + let (x1, y1) = pts[i]; + let (x2, y2) = pts[(i + 1) % pts.len()]; + + // same edge test as your original + if (y1 <= y && y2 > y) || (y2 <= y && y1 > y) { + let dy = y2 - y1; + let dx = x2 - x1; + + let t = (y - y1) as f32 / dy as f32; + let x = (x1 as f32 + t * dx as f32).round() as i32; + intersections.push(x); + } + } + + if intersections.len() < 2 { + continue; + } + + intersections.sort_unstable(); + + // fill between pairs + for pair in intersections.chunks(2) { + if pair.len() < 2 { + continue; + } + for x in pair[0]..=pair[1] { + self.draw_pixel(x as u16, y as u16, color); + } + } + } + } + pub fn set_position(&mut self, x: u16, y: u16) { self.pos.x = x; self.pos.y = y;