Last active
January 25, 2020 23:45
-
-
Save mooman219/9fd0373238604490fda8e28c6d714f85 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use crate::math::Polygons; | |
use alloc::vec; | |
use alloc::vec::*; | |
pub struct Raster { | |
w: usize, | |
h: usize, | |
a: Vec<f32>, | |
} | |
impl Raster { | |
pub fn new(w: usize, h: usize) -> Raster { | |
Raster { | |
w, | |
h, | |
a: vec![0.0; w * h + 1], | |
} | |
} | |
pub fn draw(&mut self, polygons: &Polygons, scale: f32) { | |
let scale = wide::f32x4::from(scale); | |
for line in &polygons.lines { | |
let abcd = line.abcd * scale; | |
// This looks bad. | |
self.line(abcd[0], abcd[1], abcd[2], abcd[3], line.x_mod, line.y_mod); | |
// self.line(abcd[0], abcd[1], abcd[2], abcd[3], efgh[0], efgh[1], efgh[2], efgh[3]); | |
} | |
} | |
#[inline(always)] | |
fn add(&mut self, index: usize, value: f32) { | |
unsafe { | |
*self.a.get_unchecked_mut(index) += value; | |
} | |
} | |
#[inline(always)] | |
fn add_smooth(&mut self, index: usize, height: f32, mid_x: f32) { | |
unsafe { | |
let mid_x = wide::f32x4::from(mid_x).fract()[0]; | |
*self.a.get_unchecked_mut(index) += height * (1.0 - mid_x); | |
*self.a.get_unchecked_mut(index + 1) += height * mid_x; | |
} | |
} | |
#[inline(always)] | |
pub fn line(&mut self, x0: f32, y0: f32, x1: f32, y1: f32, x_mod: f32, y_mod: f32) { | |
let dx = x1 - x0; | |
let dy = y1 - y0; | |
let sx = (1f32).copysign(dx); | |
let sy = (1f32).copysign(dy); | |
let mut x = x0.floor() + x_mod; | |
let mut y = y0.floor() + y_mod; | |
let tdx = if dx == 0.0 { | |
1048576.0 | |
} else { | |
1.0 / dx | |
}; | |
let tdy = 1.0 / dy; | |
let mut tmx = tdx * (x - x0); | |
let mut tmy = tdy * (y - y0); | |
let tdx = tdx.abs(); | |
let tdy = tdy.abs(); | |
let mut x_prev = x0; | |
let mut y_prev = y0; | |
let mut x_next: f32; | |
let mut y_next: f32; | |
let mut index = (x0 as usize + y0 as usize * self.w) as isize; | |
let index_x_inc = sx as isize; | |
let index_y_inc = (sy * self.w as f32) as isize; | |
while tmx < 1.0 || tmy < 1.0 { | |
let prev_index = index; | |
if tmx < tmy { | |
y_next = tmx * dy + y0; | |
x_next = x; | |
tmx += tdx; | |
x += sx; | |
index += index_x_inc; | |
} else { | |
y_next = y; | |
x_next = tmy * dx + x0; | |
tmy += tdy; | |
y += sy; | |
index += index_y_inc; | |
} | |
self.add_smooth(prev_index as usize, y_prev - y_next, (x_prev + x_next) / 2.0); | |
x_prev = x_next; | |
y_prev = y_next; | |
} | |
self.add_smooth(index as usize, y_prev - y1, (x_prev + x1) / 2.0); | |
} | |
pub fn get_bitmap(&self) -> Vec<u8> { | |
let length = self.w * self.h; | |
let mut height = 0.0; | |
let mut output = Vec::with_capacity(length); | |
unsafe { output.set_len(length) }; | |
let mut width = 0; | |
self.print(); | |
for i in 0..length { | |
if width == self.w { | |
println!(""); | |
width = 0; | |
} | |
width += 1; | |
unsafe { | |
height += self.a.get_unchecked(i); | |
// 500.99997f32 | |
// print!(" {:>4}", ((self.a.get_unchecked(i).height) * 255.99998) as i16); | |
print!(" {:>4}", (height * 255.0) as i16); | |
*(output.get_unchecked_mut(i)) = ((height) * 255.0) as u8; | |
} | |
} | |
println!(""); | |
output | |
} | |
pub fn print(&self) { | |
let mut width = 0; | |
for i in 0..(self.w * self.h) { | |
if width == self.w { | |
println!(""); | |
width = 0; | |
} | |
width += 1; | |
unsafe { | |
print!(" {:>4}", (self.a.get_unchecked(i) * 255.0) as i16); | |
} | |
} | |
println!(""); | |
println!(""); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment