From 5bd181adc9057791d63143ba47116d9a61647604 Mon Sep 17 00:00:00 2001 From: zomseffen <steffen@tom.bi> Date: Thu, 27 Feb 2025 13:34:08 +0100 Subject: [PATCH] combine quads --- shaders/compiled/frag_rt_quad.spv | Bin 44360 -> 46376 bytes shaders/compiled/vert_rt_quad.spv | Bin 2872 -> 2892 bytes shaders/rt_quad.frag | 17 ++- shaders/rt_quad.vert | 2 +- src/main.rs | 2 +- src/primitives/quad.rs | 35 +++-- src/scene/empty_volume.rs | 235 ++++++++++++++++++------------ src/scene/generators.rs | 6 +- 8 files changed, 181 insertions(+), 116 deletions(-) diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv index 8bba5d6966405ff9e36e0baea864df3bf264924b..18213c1a8337e560ddc049edd5ff12fdc4a09b2d 100644 GIT binary patch literal 46376 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 Hd)@gz#OcPf literal 44360 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 EKf?d;Z2$lO diff --git a/shaders/compiled/vert_rt_quad.spv b/shaders/compiled/vert_rt_quad.spv index f89cebab28a8c4fce1b823a9904031e00bbc5a1d..64d060ce38083553631a6f3cb5cd06594268ba69 100644 GIT binary patch delta 589 zcmYL_%}&Bl6ok)h3ym7w2|HurLh%VqjBbhlNd2kqh(XdssX}qfGZ>zPuyNzUy*r<W z=zL8ZAd}lUbIzH$_p|;}ule3~Xy$CqYWDC^i#E>8tSxke8{tlfXX9VjL`epn?kMXG z+v&(E`qTNIK965|QPv%1s#L8ree)VkX47HPS7(wX=|EI!knelyJ|=@cykhZu=6$<K zV8?3Mq)We+8nJ`Bocp=edZA&v)Pg)L+$(g<m)y@y%ULdj<`=y&e7*?&oU2Y3)tyO0 z<|ity3M||bKh;SP>IVfUAT{($oh)Pq9ZpDU=vO-FEp<3AT+UzXo8A?(y?g-$Zb7kJ zNb-`iAfA7Pp+6zhxj>#*d9`$26tyD_@UZYhY4}G1-e_cmqsiNDg<Sy+dw4l_uWud; NjVSPixr*)U8vh}IJu3hJ delta 531 zcmYLG%}T>S82olOZLpGF#P%kF2kjdOQm>`{rj16gL26mB38ty<A$gLLi`U-0`5Yd6 z0Ku6xp@d<-+4;Vm+0AF~qZb%`<clcTl|UZfgJ}O!L~ei(h=6+_Ua!8?fQn70$+DQ` zVYZYOK6bukFRR5YDw4dwPFuqARrd#+&2l?Or!8!jf<pD&dC$p{P3Pn-iL15VDBs8! z4c&6#^(~DK00oT1IFqicJy&lv&&4FywNBeDH_on^<yEMex;L)AJ)>2p{AnML50UKx z!oR7=S<M-Sd(^M7a<~IfC+7=rkNPcERZjf9VKXtU)g7#yAZJ8QG$$}t!+AnnZG7Jp xBa~MF1DvCQ??XPsF$^#P_>-tH1UWTY-2o>6HQJFka}TKFTB9}jFRpkB`~gw*I%WU> diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag index 091b247..d5747b9 100644 --- a/shaders/rt_quad.frag +++ b/shaders/rt_quad.frag @@ -1,6 +1,6 @@ #version 450 -layout(location = 0) flat in uvec2 fragRasterPos; +layout(location = 0) in vec2 fragRasterPos; layout(location = 1) flat in uint fragVolumeStart; layout(location = 2) in vec3 origPosition; layout(location = 3) flat in uint facing; @@ -109,6 +109,10 @@ uint sample_neighbor_from_scene_info(uint volume_start, uvec2 raster_pos, uint f return value; } +uint sample_neighbor_from_scene_info(uint volume_start, vec2 raster_pos, uint f) { + return sample_neighbor_from_scene_info(volume_start, uvec2(uint(floor(raster_pos.x)), uint(floor(raster_pos.y))), f); +} + uvec4 sample_color_from_scene_info(uint volume_start, uvec2 raster_pos, uint f) { uint array_descr_start = volume_start + 6 + max_num_lights; uint color_array_start = array_descr_start + 24; @@ -148,6 +152,10 @@ uvec4 sample_color_from_scene_info(uint volume_start, uvec2 raster_pos, uint f) return unpack_color(value); } +uvec4 sample_color_from_scene_info(uint volume_start, vec2 raster_pos, uint f) { + return sample_color_from_scene_info(volume_start, uvec2(uint(floor(raster_pos.x)), uint(floor(raster_pos.y))), f); +} + vec3 get_light_position(uint light_index) { return vec3(uintBitsToFloat(scene_info.infos[light_index + 1]), uintBitsToFloat(scene_info.infos[light_index + 2]), uintBitsToFloat(scene_info.infos[light_index + 3])); } @@ -333,7 +341,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl vec3 visibility_after_reflection = refltective_color_mul * reflectivity; //break; //max(visibility_after_reflection.x, max(visibility_after_reflection.y, visibility_after_reflection.z)) >= 0.1 && - if (allow_reflect) { + if (max(visibility_after_reflection.x, max(visibility_after_reflection.y, visibility_after_reflection.z)) >= 0.1 && allow_reflect) { // do reflect direction = reflect_vector(direction, hit_facing); pos = intersection_pos; @@ -440,6 +448,10 @@ vec3 diffuse_tracing(uint volume_start, uvec2 raster_pos, vec3 pos, uint f) { return color_sum; } +vec3 diffuse_tracing(uint volume_start, vec2 raster_pos, vec3 pos, uint f) { + return diffuse_tracing(volume_start, uvec2(uint(floor(raster_pos.x)), uint(floor(raster_pos.y))), pos, f); +} + vec3 clamp_to_volume(uint volume_start, vec3 position) { uint volume_pos_x = scene_info.infos[volume_start + 0]; uint volume_pos_y = scene_info.infos[volume_start + 1]; @@ -501,4 +513,5 @@ void main() { } outColor = vec4(color_sum, 1.0); + //outColor = vec4(orig_color_sample, 1.0); } \ No newline at end of file diff --git a/shaders/rt_quad.vert b/shaders/rt_quad.vert index 47b98b0..d43d6e1 100644 --- a/shaders/rt_quad.vert +++ b/shaders/rt_quad.vert @@ -15,7 +15,7 @@ layout(location = 1) in uvec2 inRasterPos; layout(location = 2) in uint inVolumeStart; layout(location = 3) in uint inFacing; -layout(location = 0) flat out uvec2 rasterPos; +layout(location = 0) out vec2 rasterPos; layout(location = 1) flat out uint volumeStart; layout(location = 2) out vec3 origPosition; layout(location = 3) flat out uint facing; diff --git a/src/main.rs b/src/main.rs index 9f7d013..db7c7a7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -224,7 +224,7 @@ impl App { image::create_texture_sampler(&device, &mut data)?; //let cur_pos = generators::generate_test_scene(&mut scene_handler, &mut data)?; - let cur_pos = generators::generate_test_scene2(&mut scene_handler, &mut data, 3, 3,1, 2)?; + let cur_pos = generators::generate_test_scene2(&mut scene_handler, &mut data, 21, 21,1, 5)?; scene_handler.prepare_data(&instance, &device, &mut data)?; buffer::create_uniform_buffers(&instance, &device, &mut data)?; diff --git a/src/primitives/quad.rs b/src/primitives/quad.rs index 5be1b03..b055edb 100644 --- a/src/primitives/quad.rs +++ b/src/primitives/quad.rs @@ -1,5 +1,5 @@ use vulkanalia::prelude::v1_0::*; -use cgmath::vec3; +use cgmath::{vec3, ElementWise, Vector2}; use crate::vertex::{self, Facing}; use crate::scene::Scene; use crate::primitives::drawable::Drawable; @@ -11,6 +11,7 @@ pub struct Quad{ pub pos3: vertex::Vec3, pub pos4: vertex::Vec3, pub raster_pos: cgmath::Vector2<u32>, + pub size: cgmath::Vector2<u32>, pub volume_index: u32, pub facing: Facing, } @@ -21,40 +22,50 @@ impl Drawable for Quad { // 0 top left far scene.rt_vertices.push(vertex::RTVertex::new( vec3(self.pos1.x as f32, self.pos1.y as f32, self.pos1.z as f32), - self.raster_pos, + self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 0, y: 0}), self.volume_index, self.facing )); // 1 top right far scene.rt_vertices.push(vertex::RTVertex::new( vec3(self.pos2.x as f32, self.pos2.y as f32, self.pos2.z as f32), - self.raster_pos, + self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 0, y: 1}), self.volume_index, self.facing )); // 2 top left near scene.rt_vertices.push(vertex::RTVertex::new( vec3(self.pos3.x as f32, self.pos3.y as f32, self.pos3.z as f32), - self.raster_pos, + self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 1, y: 1}), self.volume_index, self.facing )); // 3 top right near scene.rt_vertices.push(vertex::RTVertex::new( vec3(self.pos4.x as f32, self.pos4.y as f32, self.pos4.z as f32), - self.raster_pos, + self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 1, y: 0}), self.volume_index, self.facing )); - // top - scene.indices_rt.push(start_index as u32 + 2); - scene.indices_rt.push(start_index as u32 + 1); - scene.indices_rt.push(start_index as u32 + 0); + // change node order while preserving texture coordinates + if [Facing::Top].contains(&self.facing) { + scene.indices_rt.push(start_index as u32 + 0); + scene.indices_rt.push(start_index as u32 + 1); + scene.indices_rt.push(start_index as u32 + 2); - scene.indices_rt.push(start_index as u32 + 0); - scene.indices_rt.push(start_index as u32 + 3); - scene.indices_rt.push(start_index as u32 + 2); + scene.indices_rt.push(start_index as u32 + 2); + scene.indices_rt.push(start_index as u32 + 3); + scene.indices_rt.push(start_index as u32 + 0); + } else { + scene.indices_rt.push(start_index as u32 + 2); + scene.indices_rt.push(start_index as u32 + 1); + scene.indices_rt.push(start_index as u32 + 0); + + scene.indices_rt.push(start_index as u32 + 0); + scene.indices_rt.push(start_index as u32 + 3); + scene.indices_rt.push(start_index as u32 + 2); + } } } } \ No newline at end of file diff --git a/src/scene/empty_volume.rs b/src/scene/empty_volume.rs index bde0226..cf265b7 100644 --- a/src/scene/empty_volume.rs +++ b/src/scene/empty_volume.rs @@ -718,37 +718,79 @@ impl EmptyVolume { println!("volume creation took {} s", start_time.elapsed().as_millis() as f32 / 1000.0); (volumes, neighbors) } + + fn check_quad_index(u: usize, v: usize, vsize: usize, size1: usize, size2: usize, colors: &Vec<Vector3<u8>>, neighbors: &Vec<Option<Rc<RefCell<EmptyVolume>>>>) -> bool { + let index = (u + size1) * vsize + (v + size2); + if colors.len() <= index { + return false; + + } + if neighbors.len() > index || neighbors.len() == 1 { + if let Some(_) = neighbors[index.min(neighbors.len() - 1)] { + if colors[index] == (Vector3 {x: 0, y: 0, z: 0}) { + return false; + } + } + } + return true + } + + fn grow_quad(u: usize, v: usize, size_u: usize, size_v: usize, colors: &Vec<Vector3<u8>>, neighbors: &Vec<Option<Rc<RefCell<EmptyVolume>>>>) -> (usize, usize) { + let mut size_1 = 0; + let mut size_2 = 0; + let mut grow = true; + let mut v_size_check = 0; + while grow { + for u_size_check in 0..size_u - u { + if EmptyVolume::check_quad_index(u, v, size_v, u_size_check, v_size_check, colors, neighbors) { + size_1 = size_1.max(u_size_check); + } else { + grow = false; + break; + } + } + if grow { + size_2 = v_size_check; + } + v_size_check += 1; + } + + (size_1, size_2) + } + // MARK: To Quads pub fn to_quads(&self) -> Vec<Quad> { let mut quads = vec![]; let float_pos = Vector3 {x: (self.tree_offset.x * self.tree_size + self.position.x) as f32, y: (self.tree_offset.y * self.tree_size + self.position.y) as f32, z: (self.tree_offset.z * self.tree_size + self.position.z) as f32}; //bottom sides of the volumes, top side of the block + let mut done = vec![]; for x in 0..self.size_x { for y in 0..self.size_y { - let index = x * self.size_y + y; - if self.color_bottom.len() <= index { + if done.contains(&(x, y)) { continue; } - if self.neighbor_bottom.len() > index || self.neighbor_bottom.len() == 1 { - if let Some(_) = self.neighbor_bottom[index.min(self.neighbor_bottom.len() - 1)] { - if self.color_bottom[index] == (Vector3 {x: 0, y: 0, z: 0}) { - continue; - } - } - } - if self.color_bottom[index] == (Vector3 {x: 0, y: 0, z: 0}) { - println!("No neighbor reference, but no color! x: {}, y: {}, z: {}", self.position.x + x, self.position.y + y, self.position.z); - if self.neighbor_bottom.len() == 1 { - println!("neighbor length is one!"); + + if !EmptyVolume::check_quad_index(x, y, self.size_y, 0, 0, &self.color_bottom, &self.neighbor_bottom) { + continue; + } + + let (size_1, size_2) = EmptyVolume::grow_quad(x, y, self.size_x, self.size_y, &self.color_bottom, &self.neighbor_bottom); + + done.push((x, y)); + for done_x in 0..size_1 + 1 { + for done_y in 0..size_2 + 1 { + done.push((x + done_x, y + done_y)); } } + let quad = Quad { pos1: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + y as f32, z: -0.5 }, - pos4: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + y as f32, z: -0.5 }, - pos3: float_pos + Vector3 { x: 0.5 + x as f32, y: 0.5 + y as f32, z: -0.5 }, - pos2: float_pos + Vector3 { x: -0.5 + x as f32, y: 0.5 + y as f32, z: -0.5 }, + pos4: float_pos + Vector3 { x: 0.5 + (x + size_1) as f32, y: -0.5 + y as f32, z: -0.5 }, + pos3: float_pos + Vector3 { x: 0.5 + (x + size_1) as f32, y: 0.5 + (y + size_2) as f32, z: -0.5 }, + pos2: float_pos + Vector3 { x: -0.5 + x as f32, y: 0.5 + (y + size_2) as f32, z: -0.5 }, raster_pos: cgmath::Vector2 { x: x as u32, y: y as u32 }, + size: cgmath::Vector2 { x: (size_1 + 1) as u32, y: (size_2 + 1) as u32 }, volume_index: self.memory_start as u32, facing: vertex::Facing::Bottom }; @@ -756,33 +798,32 @@ impl EmptyVolume { } } //top sides of the volumes, bottom side of the block + let mut done = vec![]; for x in 0..self.size_x { for y in 0..self.size_y { - let index = x * self.size_y + y; - if self.color_top.len() <= 0 { + if done.contains(&(x, y)) { continue; } - if self.neighbor_top.len() > index || self.neighbor_top.len() == 1 { - if let Some(_) = self.neighbor_top[index.min(self.neighbor_top.len() - 1)] { - if self.color_top[index] == (Vector3 {x: 0, y: 0, z: 0}) { - continue; - } - } + + if !EmptyVolume::check_quad_index(x, y, self.size_y, 0, 0, &self.color_top, &self.neighbor_top) { + continue; } + + let (size_1, size_2) = EmptyVolume::grow_quad(x, y, self.size_x, self.size_y, &self.color_top, &self.neighbor_top); - if self.color_top[index] == (Vector3 {x: 0, y: 0, z: 0}) { - println!("No neighbor reference, but no color! x: {}, y: {}, z: {}", self.position.x + x, self.position.y + y, self.position.z + self.size_z); - - if self.neighbor_top.len() == 1 { - println!("neighbor length is one!"); + done.push((x, y)); + for done_x in 0..size_1 + 1 { + for done_y in 0..size_2 + 1 { + done.push((x + done_x, y + done_y)); } } let quad = Quad { - pos4: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + y as f32, z: self.size_z as f32 - 0.5 }, - pos1: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + y as f32, z: self.size_z as f32 - 0.5 }, - pos2: float_pos + Vector3 { x: 0.5 + x as f32, y: 0.5 + y as f32, z: self.size_z as f32 - 0.5 }, - pos3: float_pos + Vector3 { x: -0.5 + x as f32, y: 0.5 + y as f32, z: self.size_z as f32 - 0.5 }, + pos1: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + y as f32, z: self.size_z as f32 - 0.5 }, + pos4: float_pos + Vector3 { x: 0.5 + (x + size_1) as f32, y: -0.5 + y as f32, z: self.size_z as f32 - 0.5 }, + pos3: float_pos + Vector3 { x: 0.5 + (x + size_1) as f32, y: 0.5 + (y + size_2) as f32, z: self.size_z as f32 - 0.5 }, + pos2: float_pos + Vector3 { x: -0.5 + x as f32, y: 0.5 + (y + size_2) as f32, z: self.size_z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: x as u32, y: y as u32 }, + size: cgmath::Vector2 { x: (size_1 + 1) as u32, y: (size_2 + 1) as u32 }, volume_index: self.memory_start as u32, facing: vertex::Facing::Top }; @@ -791,32 +832,32 @@ impl EmptyVolume { } //front sides of the volumes, back side of the block + let mut done = vec![]; for x in 0..self.size_x { for z in 0..self.size_z { - let index = x * self.size_z + z; - if self.color_front.len() <= 0 { + if done.contains(&(x, z)) { continue; } - if self.neighbor_front.len() > index || self.neighbor_front.len() == 1 { - if let Some(_) = self.neighbor_front[index.min(self.neighbor_front.len() - 1)] { - if self.color_front[index] == (Vector3 {x: 0, y: 0, z: 0}) { - continue; - } - } + + if !EmptyVolume::check_quad_index(x, z, self.size_z, 0, 0, &self.color_front, &self.neighbor_front) { + continue; } + + let (size_1, size_2) = EmptyVolume::grow_quad(x, z, self.size_x, self.size_z, &self.color_front, &self.neighbor_front); - if self.color_front[index] == (Vector3 {x: 0, y: 0, z: 0}) { - println!("No neighbor reference, but no color! x: {}, y: {}, z: {}", self.position.x + x, self.position.y, self.position.z + z); - if self.neighbor_front.len() == 1 { - println!("neighbor length is one!"); + done.push((x, z)); + for done_x in 0..size_1 + 1 { + for done_z in 0..size_2 + 1 { + done.push((x + done_x, z + done_z)); } } let quad = Quad { - pos1: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 - 0.5 }, - pos4: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 + 0.5 }, - pos3: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 + 0.5 }, - pos2: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 - 0.5 }, + pos2: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 - 0.5 }, + pos1: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + 0 as f32, z: (z + size_2) as f32 + 0.5 }, + pos4: float_pos + Vector3 { x: 0.5 + (x + size_1) as f32, y: -0.5 + 0 as f32, z: (z + size_2) as f32 + 0.5 }, + pos3: float_pos + Vector3 { x: 0.5 + (x + size_1) as f32, y: -0.5 + 0 as f32, z: z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: x as u32, y: z as u32 }, + size: cgmath::Vector2 { x: (size_1 + 1) as u32, y: (size_2 + 1) as u32 }, volume_index: self.memory_start as u32, facing: vertex::Facing::Front }; @@ -825,32 +866,32 @@ impl EmptyVolume { } //back sides of the volumes, front side of the block + let mut done = vec![]; for x in 0..self.size_x { for z in 0..self.size_z { - let index = x * self.size_z + z; - if self.color_back.len() <= 0 { + if done.contains(&(x, z)) { continue; } - if self.neighbor_back.len() > index || self.neighbor_back.len() == 1 { - if let Some(_) = self.neighbor_back[index.min(self.neighbor_back.len() - 1)] { - if self.color_back[index] == (Vector3 {x: 0, y: 0, z: 0}) { - continue; - } - } + + if !EmptyVolume::check_quad_index(x, z, self.size_z, 0, 0, &self.color_back, &self.neighbor_back) { + continue; } + + let (size_1, size_2) = EmptyVolume::grow_quad(x, z, self.size_x, self.size_z, &self.color_back, &self.neighbor_back); - if self.color_back[index] == (Vector3 {x: 0, y: 0, z: 0}) { - println!("No neighbor reference, but no color! x: {}, y: {}, z: {}", self.position.x + x, self.position.y + self.size_y, self.position.z + z); - if self.neighbor_back.len() == 1 { - println!("neighbor length is one!"); + done.push((x, z)); + for done_x in 0..size_1 + 1 { + for done_z in 0..size_2 + 1 { + done.push((x + done_x, z + done_z)); } } let quad = Quad { - pos4: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 - 0.5 }, - pos1: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 + 0.5 }, - pos2: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 + 0.5 }, - pos3: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 - 0.5 }, + pos1: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 - 0.5 }, + pos2: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + self.size_y as f32, z: (z + size_2) as f32 + 0.5 }, + pos3: float_pos + Vector3 { x: 0.5 + (x + size_1) as f32, y: -0.5 + self.size_y as f32, z: (z + size_2) as f32 + 0.5 }, + pos4: float_pos + Vector3 { x: 0.5 + (x + size_1) as f32, y: -0.5 + self.size_y as f32, z: z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: x as u32, y: z as u32 }, + size: cgmath::Vector2 { x: (size_1 + 1) as u32, y: (size_2 + 1) as u32 }, volume_index: self.memory_start as u32, facing: vertex::Facing::Back }; @@ -859,32 +900,32 @@ impl EmptyVolume { } //left sides of the volumes, right side of the block + let mut done = vec![]; for y in 0..self.size_y { for z in 0..self.size_z { - let index = y * self.size_z + z; - if self.color_left.len() <= 0 { + if done.contains(&(y, z)) { continue; } - if self.neighbor_left.len() > index || self.neighbor_left.len() == 1 { - if let Some(_) = self.neighbor_left[index.min(self.neighbor_left.len() - 1)] { - if self.color_left[index] == (Vector3 {x: 0, y: 0, z: 0}) { - continue; - } - } + + if !EmptyVolume::check_quad_index(y, z, self.size_z, 0, 0, &self.color_left, &self.neighbor_left) { + continue; } + + let (size_1, size_2) = EmptyVolume::grow_quad(y, z, self.size_y, self.size_z, &self.color_left, &self.neighbor_left); - if self.color_left[index] == (Vector3 {x: 0, y: 0, z: 0}) { - println!("No neighbor reference, but no color! x: {}, y: {}, z: {}", self.position.x, self.position.y + y, self.position.z + z); - if self.neighbor_left.len() == 1 { - println!("neighbor length is one!"); + done.push((y, z)); + for done_y in 0..size_1 + 1 { + for done_z in 0..size_2 + 1 { + done.push((y + done_y, z + done_z)); } } let quad = Quad { - pos4: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: y as f32 - 0.5, z: z as f32 - 0.5 }, - pos1: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: y as f32 - 0.5, z: z as f32 + 0.5 }, - pos2: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: y as f32 + 0.5, z: z as f32 + 0.5 }, - pos3: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: y as f32 + 0.5, z: z as f32 - 0.5 }, + pos1: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: y as f32 - 0.5, z: z as f32 - 0.5 }, + pos2: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: y as f32 - 0.5, z: (z + size_2) as f32 + 0.5 }, + pos3: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: (y + size_1) as f32 + 0.5, z: (z + size_2) as f32 + 0.5 }, + pos4: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: (y + size_1) as f32 + 0.5, z: z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: y as u32, y: z as u32 }, + size: cgmath::Vector2 { x: (size_1 + 1) as u32, y: (size_2 + 1) as u32 }, volume_index: self.memory_start as u32, facing: vertex::Facing::Left }; @@ -893,32 +934,32 @@ impl EmptyVolume { } //right sides of the volumes, left side of the block + let mut done = vec![]; for y in 0..self.size_y { for z in 0..self.size_z { - let index = y * self.size_z + z; - if self.color_right.len() <= 0 { + if done.contains(&(y, z)) { continue; } - if self.neighbor_right.len() > index || self.neighbor_right.len() == 1 { - if let Some(_) = self.neighbor_right[index.min(self.neighbor_right.len() - 1)] { - if self.color_right[index] == (Vector3 {x: 0, y: 0, z: 0}) { - continue; - } - } + + if !EmptyVolume::check_quad_index(y, z, self.size_z, 0, 0, &self.color_right, &self.neighbor_right) { + continue; } + + let (size_1, size_2) = EmptyVolume::grow_quad(y, z, self.size_y, self.size_z, &self.color_right, &self.neighbor_right); - if self.color_right[index] == (Vector3 {x: 0, y: 0, z: 0}) { - println!("No neighbor reference, but no color! x: {}, y: {}, z: {}", self.position.x + self.size_x, self.position.y + y, self.position.z + z); - if self.neighbor_right.len() == 1 { - println!("neighbor length is one!"); + done.push((y, z)); + for done_y in 0..size_1 + 1 { + for done_z in 0..size_2 + 1 { + done.push((y + done_y, z + done_z)); } } let quad = Quad { - pos1: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: y as f32 - 0.5, z: z as f32 - 0.5 }, - pos4: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: y as f32 - 0.5, z: z as f32 + 0.5 }, - pos3: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: y as f32 + 0.5, z: z as f32 + 0.5 }, - pos2: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: y as f32 + 0.5, z: z as f32 - 0.5 }, + pos2: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: y as f32 - 0.5, z: z as f32 - 0.5 }, + pos1: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: y as f32 - 0.5, z: (z + size_2) as f32 + 0.5 }, + pos4: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: (y + size_1) as f32 + 0.5, z: (z + size_2) as f32 + 0.5 }, + pos3: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: (y + size_1) as f32 + 0.5, z: z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: y as u32, y: z as u32 }, + size: cgmath::Vector2 { x: (size_1 + 1) as u32, y: (size_2 + 1) as u32 }, volume_index: self.memory_start as u32, facing: vertex::Facing::Right }; diff --git a/src/scene/generators.rs b/src/scene/generators.rs index 1919378..78c629e 100644 --- a/src/scene/generators.rs +++ b/src/scene/generators.rs @@ -113,7 +113,7 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi let tree_ref_one = Rc::new(RefCell::new(oct_tree1.clone())); let tree_ref_two = Rc::new(RefCell::new(oct_tree2.clone())); - scene.oct_trees = vec![vec![vec![tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone()]], vec![vec![tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone()]]]; + scene.oct_trees = vec![vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]], vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]]]; Ok((cgmath::point3(5.0, 5.0, 10.0))) } @@ -131,7 +131,7 @@ pub fn generate_test_scene2(scene: &mut Scene, data: &mut AppData, chunk_num_x: let mut height_map = vec![vec![0.0; max_y]; max_x]; for i in 0..num_gaussians { - let height = rng.gen_range(16..max_z / 2) as f32; + let height = rng.gen_range(1..max_z / 2) as f32; let center_x = rng.gen_range(0..max_x) as f32; let center_y = rng.gen_range(0..max_y) as f32; @@ -189,7 +189,7 @@ pub fn generate_test_scene2(scene: &mut Scene, data: &mut AppData, chunk_num_x: roughness: 255, }; - //oct_trees[((pillar_height as f32) / (grid_size as f32)).floor() as usize][((y as f32) / (grid_size as f32)).floor() as usize][((x as f32) / (grid_size as f32)).floor() as usize].borrow_mut().set_cube(cube.clone()); + oct_trees[((pillar_height as f32) / (grid_size as f32)).floor() as usize][((y as f32) / (grid_size as f32)).floor() as usize][((x as f32) / (grid_size as f32)).floor() as usize].borrow_mut().set_cube(cube.clone()); } }