Advertisement
443eb9

Untitled

Mar 19th, 2024 (edited)
350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.50 KB | None | 0 0
  1. pub fn jfa_preprocess(target: &mut Rgba32FImage) {
  2.     let (width, height) = target.dimensions();
  3.     target.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
  4.         let uv = Vec2::new(x as f32 / width as f32, y as f32 / height as f32);
  5.         pixel[2] = 0.;
  6.         pixel[3] = 0.;
  7.         if pixel[3] > 0.5 {
  8.             // Inside
  9.             pixel[0] = uv.x;
  10.             pixel[1] = uv.y;
  11.             pixel[3] = 1.;
  12.         } else {
  13.             // Outside
  14.             pixel[0] = -uv.x;
  15.             pixel[1] = -uv.y;
  16.             pixel[3] = 1.;
  17.         }
  18.     });
  19. }
  20.  
  21. pub fn jfa(src: &Rgba32FImage, dest: &mut Rgba32FImage, iteration: u32, width: u32, height: u32) {
  22.     let step = (width.max(height) >> (iteration + 1)).max(1);
  23.     let tex_fsize = Vec2::new(width as f32, height as f32);
  24.     let tex_isize = IVec2::new(width as i32, height as i32);
  25.  
  26.     dest.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
  27.         let px = IVec2::new(x as i32, y as i32);
  28.         let mut best_distance_sqr = f32::INFINITY;
  29.         let mut best_uv = Vec2::ZERO;
  30.         let is_inside = src.get_pixel(px.x as u32, px.y as u32)[0] > 0.;
  31.  
  32.         for mut dx in -1..=1 {
  33.             dx *= step as i32;
  34.             for mut dy in -1..=1 {
  35.                 dy *= step as i32;
  36.                 let neighbor_px = px + IVec2::new(dx, dy);
  37.                 if neighbor_px.x < 0
  38.                     || neighbor_px.x >= tex_isize.x
  39.                     || neighbor_px.y < 0
  40.                     || neighbor_px.y >= tex_isize.y
  41.                 {
  42.                     continue;
  43.                 }
  44.  
  45.                 let neighbor_saved_px = src.get_pixel(neighbor_px.x as u32, neighbor_px.y as u32);
  46.                 if neighbor_saved_px[3] < 0.5 {
  47.                     continue;
  48.                 }
  49.                 let mut neighbor_saved_px =
  50.                     Vec2::new(neighbor_saved_px[0], neighbor_saved_px[1]) * tex_fsize;
  51.                 if !is_inside {
  52.                     neighbor_saved_px = -neighbor_saved_px;
  53.                 }
  54.                 let distance = neighbor_saved_px.distance_squared(px.as_vec2());
  55.                 if distance < best_distance_sqr {
  56.                     best_distance_sqr = distance;
  57.                     best_uv = neighbor_saved_px / tex_fsize;
  58.                 }
  59.             }
  60.         }
  61.  
  62.         if is_inside {
  63.             pixel[0] = best_uv.x;
  64.             pixel[1] = best_uv.y;
  65.         } else {
  66.             pixel[0] = -best_uv.x;
  67.             pixel[1] = -best_uv.y;
  68.         }
  69.     });
  70. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement