1extern crate nalgebra as na;
2
3use na::{Vector2, Matrix3xX};
4use std::collections::HashMap;
5use crate::triangle::Triangle;
6use crate::rasterizer;
7
8
9pub enum FilterType {
10 Depth,
11 Rasterizer
12}
13
14pub fn filter_visible_screen_points_by_depth(screen_points_with_index: &Vec<(usize,Vector2<f32>)>, points_cam: &Matrix3xX<f32>,) -> Vec<(usize,Vector2<usize>)> {
15 let mut closest_point_map = HashMap::<(usize,usize), usize>::with_capacity(screen_points_with_index.len());
16 for (i,&(global_id,screen_p)) in screen_points_with_index.iter().filter(|(_,p)| p.x > 0.0 && p.y >= 0.0).enumerate() {
17 let key = (screen_p.x.floor() as usize,screen_p.y.floor() as usize);
18 match closest_point_map.contains_key(&key) {
19 true => {
20 let current_point_index = closest_point_map.get(&key).unwrap();
21 let current_point_depth = points_cam[*current_point_index];
22 let depth = points_cam[(2,global_id)];
23 if depth > current_point_depth {
25 closest_point_map.insert(key, i);
26 }
27 },
28 false => {closest_point_map.insert(key, i);()}
29 }
30 }
31 closest_point_map.into_values().map(|i| screen_points_with_index[i]).map(|(i,v)| (i, Vector2::new(v.x.floor() as usize, v.y.floor() as usize))).collect()
32}
33
34pub fn filter_visible_screen_points_by_rasterizer(screen_cam_triangles: &Vec<(Triangle<2>,Triangle<3>)>, screen_width: f32, screen_height: f32) -> Vec<(usize,Vector2<usize>)> {
35 assert!(screen_height.fract() <= f32::EPSILON);
36 assert!(screen_width.fract() <= f32::EPSILON);
37 let mut depth_buffer = HashMap::<(usize,usize),(f32,Option<(usize,Vector2<usize>)>)>::with_capacity((screen_height*screen_width) as usize);
38 for (tri_2d,tri_3d) in screen_cam_triangles.iter() {
39 let barycentric_coordiantes_with_pixel = rasterizer::calc_all_pixels_within_triangle(tri_2d);
40 let barycentric_coordiantes = barycentric_coordiantes_with_pixel.iter().map(|(w0,w1,w2,_)| (*w0,*w1,*w2)).collect::<Vec<_>>();
41 let pixel_depths = rasterizer::calc_inv_z_for_all_pixels(&barycentric_coordiantes,tri_3d);
42 let mut triangle_association_map = HashMap::<(usize,usize),usize>::with_capacity(3);
43 triangle_association_map.insert((tri_2d.get_v0().x.floor() as usize,tri_2d.get_v0().y.floor() as usize), tri_2d.get_id0().expect("Expected id for v0!"));
44 triangle_association_map.insert((tri_2d.get_v1().x.floor() as usize,tri_2d.get_v1().y.floor() as usize), tri_2d.get_id1().expect("Expected id for v1!"));
45 triangle_association_map.insert((tri_2d.get_v2().x.floor() as usize,tri_2d.get_v2().y.floor() as usize), tri_2d.get_id2().expect("Expected id for v2!"));
46 for i in 0..pixel_depths.len() {
47 let depth = pixel_depths[i];
48 assert!(depth < 0.0);
49 let pixel = barycentric_coordiantes_with_pixel[i].3;
50 let key = (pixel.x.floor() as usize,pixel.y.floor() as usize);
51 let pixel_u = Vector2::new(key.0,key.1);
52 let pixel_is_vertex = triangle_association_map.contains_key(&key);
53 match (depth_buffer.contains_key(&key), pixel_is_vertex) {
54 (false,false) => {
55 depth_buffer.insert(key.clone(), (depth,None));
56 ()
57 },
58 (false,true) => {
59 depth_buffer.insert(key.clone(), (depth,Some((*triangle_association_map.get(&key).unwrap(),pixel_u))));
60 ()
61 },
62 (true,false) => {
63 let &(current_depth,_v) = depth_buffer.get(&key).unwrap();
64 assert!(current_depth < 0.0);
65 if depth > current_depth {
67 depth_buffer.insert(key.clone(), (depth,None));
68 }
69 },
70 (true,true) => {
71 let &(current_depth,_v) = depth_buffer.get(&key).unwrap();
72 assert!(current_depth < 0.0);
73 if depth > current_depth {
75 depth_buffer.insert(key.clone(), (depth,Some((*triangle_association_map.get(&key).unwrap(),pixel_u))));
76 }
77 }
78 }
79 }
80 }
81 depth_buffer.values().into_iter().filter(|(_, some_v)| some_v.is_some()).map(|(_,some_v)|some_v.unwrap()).collect()
82}