4sides quad

This commit is contained in:
zomseffen 2024-12-16 20:01:39 +01:00
parent 534f1a109a
commit 7fe7015774
13 changed files with 784 additions and 52 deletions

View file

@ -5,3 +5,6 @@ C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.geom -o shaders/geo_cube.spv
C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.vert -o shaders/vert_cuboid.spv
C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.frag -o shaders/frag_cuboid.spv
C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.geom -o shaders/geo_cuboid.spv
C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.vert -o shaders/vert_rt_quad.spv
C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.frag -o shaders/frag_rt_quad.spv

BIN
shaders/frag_rt_quad.spv Normal file

Binary file not shown.

10
shaders/rt_quad.frag Normal file
View file

@ -0,0 +1,10 @@
#version 450
layout(location = 0) flat in uvec2 fragRasterPos;
layout(location = 1) flat in uint fragVolumeStart;
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(1, 0, 0, 1);
}

27
shaders/rt_quad.vert Normal file
View file

@ -0,0 +1,27 @@
#version 450
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 geom_rot;
mat4 view;
mat4 proj;
bool[16] use_geom_shader;
} ubo;
layout(location = 0) in vec3 inPosition;
layout(location = 1) in uvec2 inRasterPos;
layout(location = 2) in uint inVolumeStart;
layout(location = 0) out uvec2 rasterPos;
layout(location = 1) out uint volumeStart;
void main() {
if (ubo.use_geom_shader[0]) {
gl_Position = ubo.geom_rot * ubo.model * vec4(inPosition, 1.0);
} else {
gl_Position = ubo.proj * ubo.view * ubo.geom_rot * ubo.model * vec4(inPosition, 1.0);
}
rasterPos = inRasterPos;
volumeStart = inVolumeStart;
}

BIN
shaders/vert_rt_quad.spv Normal file

Binary file not shown.

View file

@ -21,6 +21,7 @@ pub struct AppData {
pub render_pass: vk::RenderPass,
pub pipeline_cube: vk::Pipeline,
pub pipeline_cuboid: vk::Pipeline,
pub pipeline_quad: vk::Pipeline,
pub framebuffers: Vec<vk::Framebuffer>,
pub command_pool: vk::CommandPool,
pub command_buffers: Vec<vk::CommandBuffer>,

View file

@ -107,6 +107,26 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
device.cmd_draw_indexed(*command_buffer, scene_handler.indices_cuboid.len() as u32, 1, 0, 0, 0);
}
if scene_handler.rt_vertices.len() != 0 {
device.cmd_bind_pipeline(
*command_buffer, vk::PipelineBindPoint::GRAPHICS, data.pipeline_quad); //todo build own pipeline
device.cmd_bind_vertex_buffers(*command_buffer, 0, &[scene_handler.vertex_buffer_quad], &[0]);
device.cmd_bind_index_buffer(*command_buffer, scene_handler.index_buffer_quad, 0, vk::IndexType::UINT32);
device.cmd_bind_descriptor_sets(
*command_buffer,
vk::PipelineBindPoint::GRAPHICS,
data.pipeline_layout,
0,
&[data.descriptor_sets[i]],
&[],
);
device.cmd_draw_indexed(*command_buffer, scene_handler.indices_rt.len() as u32, 1, 0, 0, 0);
}
device.cmd_end_render_pass(*command_buffer);
device.end_command_buffer(*command_buffer)?;

View file

@ -365,6 +365,7 @@ impl App {
self.device.free_command_buffers(self.data.command_pool, &self.data.command_buffers);
self.device.destroy_pipeline(self.data.pipeline_cube, None);
self.device.destroy_pipeline(self.data.pipeline_cuboid, None);
self.device.destroy_pipeline(self.data.pipeline_quad, None);
self.device.destroy_pipeline_layout(self.data.pipeline_layout, None);
self.device.destroy_render_pass(self.data.render_pass, None);
self.data.swapchain_image_views
@ -668,64 +669,93 @@ unsafe fn create_logical_device(
}
unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Result<()> {
// set up shaders for cubes
// load the byte data
let vert_cube = include_bytes!("../shaders/vert_cube.spv");
let geo_cube = include_bytes!("../shaders/geo_cube.spv");
let frag_cube = include_bytes!("../shaders/frag_cube.spv");
// create the shaders
let vert_shader_module_cube = create_shader_module(device, &vert_cube[..])?;
let geo_shader_module_cube = create_shader_module(device, &geo_cube[..])?;
let frag_shader_module_cube = create_shader_module(device, &frag_cube[..])?;
//create the shader stage for the vertex shader
let vert_stage_cube = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::VERTEX)
.module(vert_shader_module_cube)
.name(b"main\0");
//create the shader stage for the geometry shader
let geo_stage_cube = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::GEOMETRY)
.module(geo_shader_module_cube)
.name(b"main\0");
//create the shader stage for the fragment shader
let frag_stage_cube = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::FRAGMENT)
.module(frag_shader_module_cube)
.name(b"main\0");
// create the binding description for the cube vertex
let binding_descriptions_cube = &[vertex::Vertex::binding_description()];
let attribute_descriptions_cube = vertex::Vertex::attribute_descriptions();
let vertex_input_state_cube = vk::PipelineVertexInputStateCreateInfo::builder()
.vertex_binding_descriptions(binding_descriptions_cube)
.vertex_attribute_descriptions(&attribute_descriptions_cube);
// set up shaders for cuboids
// load the byte data
let vert_cuboid = include_bytes!("../shaders/vert_cuboid.spv");
let geo_cuboid = include_bytes!("../shaders/geo_cuboid.spv");
let frag_cuboid = include_bytes!("../shaders/frag_cuboid.spv");
// create the shaders
let vert_shader_module_cuboid = create_shader_module(device, &vert_cuboid[..])?;
let geo_shader_module_cuboid = create_shader_module(device, &geo_cuboid[..])?;
let frag_shader_module_cuboid = create_shader_module(device, &frag_cuboid[..])?;
//create the shader stage for the vertex shader
let vert_stage_cuboid = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::VERTEX)
.module(vert_shader_module_cuboid)
.name(b"main\0");
//create the shader stage for the geometry shader
let geo_stage_cuboid = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::GEOMETRY)
.module(geo_shader_module_cuboid)
.name(b"main\0");
//create the shader stage for the fragment shader
let frag_stage_cuboid = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::FRAGMENT)
.module(frag_shader_module_cuboid)
.name(b"main\0");
// create the binding description for the sized vertex
let binding_descriptions_cuboid = &[vertex::SizedVertex::binding_description()];
let attribute_descriptions_cuboid = vertex::SizedVertex::attribute_descriptions();
let vertex_input_state_cuboid = vk::PipelineVertexInputStateCreateInfo::builder()
.vertex_binding_descriptions(binding_descriptions_cuboid)
.vertex_attribute_descriptions(&attribute_descriptions_cuboid);
// set up shaders for quads/raytracing
// load the byte data
let vert_quad = include_bytes!("../shaders/vert_rt_quad.spv");
let frag_quad = include_bytes!("../shaders/frag_rt_quad.spv");
// create the shaders
let vert_shader_module_quad = create_shader_module(device, &vert_quad[..])?;
let frag_shader_module_quad = create_shader_module(device, &frag_quad[..])?;
//create the shader stage for the vertex shader
let vert_stage_quad = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::VERTEX)
.module(vert_shader_module_quad)
.name(b"main\0");
//create the shader stage for the fragment shader
let frag_stage_quad = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::FRAGMENT)
.module(frag_shader_module_quad)
.name(b"main\0");
// create the binding description for the quad vertex
let binding_descriptions_quad = &[vertex::RTVertex::binding_description()];
let attribute_descriptions_quad = vertex::RTVertex::attribute_descriptions();
let vertex_input_state_quad = vk::PipelineVertexInputStateCreateInfo::builder()
.vertex_binding_descriptions(binding_descriptions_quad)
.vertex_attribute_descriptions(&attribute_descriptions_quad);
// define input assembly and object type. This is altered when using geometry shader
let mut topology = vk::PrimitiveTopology::TRIANGLE_LIST;
if data.use_geometry_shader {
topology = vk::PrimitiveTopology::POINT_LIST;
@ -736,6 +766,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
.topology(topology)
.primitive_restart_enable(false);
// define viewport and other transformations when projecting onto the screen
let viewport = vk::Viewport::builder()
.x(0.0)
.y(0.0)
@ -793,12 +824,13 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
.attachments(attachments)
.blend_constants([0.0, 0.0, 0.0, 0.0]);
// define the work pipeline
let set_layouts = &[data.descriptor_set_layout];
let layout_info = vk::PipelineLayoutCreateInfo::builder()
.set_layouts(set_layouts);
data.pipeline_layout = device.create_pipeline_layout(&layout_info, None)?;
// define stages for the cubes pipeline
let stages_cube = &[vert_stage_cube, frag_stage_cube];
let stages_geom_cube = &[vert_stage_cube, geo_stage_cube,frag_stage_cube];
@ -820,7 +852,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
else {
info_cube = info_cube.stages(stages_cube);
}
// define stages for the cuboid pipeline
let stages_cuboid = &[vert_stage_cuboid, frag_stage_cuboid];
let stages_geom_cuboid = &[vert_stage_cuboid, geo_stage_cuboid,frag_stage_cuboid];
@ -842,11 +874,30 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
else {
info_cuboid = info_cuboid.stages(stages_cuboid);
}
// define stages for the quad/rt pipeline
let stages_quad = &[vert_stage_quad, frag_stage_quad];
let pipelines = device.create_graphics_pipelines(vk::PipelineCache::null(), &[info_cube, info_cuboid], None)?.0;
let mut info_quad = vk::GraphicsPipelineCreateInfo::builder()
.vertex_input_state(&vertex_input_state_quad)
.input_assembly_state(&input_assembly_state)
.viewport_state(&viewport_state)
.rasterization_state(&rasterization_state)
.multisample_state(&multisample_state)
.depth_stencil_state(&depth_stencil_state)
.color_blend_state(&color_blend_state)
.layout(data.pipeline_layout)
.render_pass(data.render_pass)
.subpass(0);
info_quad = info_quad.stages(stages_quad);
// create the pipeline
let pipelines = device.create_graphics_pipelines(vk::PipelineCache::null(), &[info_cube, info_cuboid, info_quad], None)?.0;
data.pipeline_cube = pipelines[0];
data.pipeline_cuboid = pipelines[1];
data.pipeline_quad = pipelines[2];
device.destroy_shader_module(vert_shader_module_cube, None);
device.destroy_shader_module(geo_shader_module_cube, None);
@ -856,6 +907,9 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
device.destroy_shader_module(geo_shader_module_cuboid, None);
device.destroy_shader_module(frag_shader_module_cuboid, None);
device.destroy_shader_module(vert_shader_module_quad, None);
device.destroy_shader_module(frag_shader_module_quad, None);
Ok(())
}

View file

@ -11,55 +11,57 @@ pub struct Cube{
pub tex_coord: vertex::Vec2
}
const cube_size: f32 = 0.48;
impl Drawable for Cube {
fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) {
if *topology == vk::PrimitiveTopology::TRIANGLE_LIST {
// 0 top left far
scene.vertices.push(vertex::Vertex::new(
vec3(self.pos.x as f32 - 0.5, self.pos.y as f32 + 0.5, self.pos.z as f32 + 0.5),
vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 + cube_size),
self.color,
self.tex_coord
));
// 1 top right far
scene.vertices.push(vertex::Vertex::new(
vec3(self.pos.x as f32 + 0.5, self.pos.y as f32 + 0.5, self.pos.z as f32 + 0.5),
vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 + cube_size),
self.color,
self.tex_coord
));
// 2 top left near
scene.vertices.push(vertex::Vertex::new(
vec3(self.pos.x as f32 - 0.5, self.pos.y as f32 - 0.5, self.pos.z as f32 + 0.5),
vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 + cube_size),
self.color,
self.tex_coord
));
// 3 top right near
scene.vertices.push(vertex::Vertex::new(
vec3(self.pos.x as f32 + 0.5, self.pos.y as f32 - 0.5, self.pos.z as f32 + 0.5),
vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 + cube_size),
self.color,
self.tex_coord
));
// 4 bottom left far
scene.vertices.push(vertex::Vertex::new(
vec3(self.pos.x as f32 - 0.5, self.pos.y as f32 + 0.5, self.pos.z as f32 - 0.5),
vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 - cube_size),
self.color,
self.tex_coord
));
// 5 bottom right far
scene.vertices.push(vertex::Vertex::new(
vec3(self.pos.x as f32 + 0.5, self.pos.y as f32 + 0.5, self.pos.z as f32 - 0.5),
vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 - cube_size),
self.color,
self.tex_coord
));
// 6 bottom left near
scene.vertices.push(vertex::Vertex::new(
vec3(self.pos.x as f32 - 0.5, self.pos.y as f32 - 0.5, self.pos.z as f32 - 0.5),
vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 - cube_size),
self.color,
self.tex_coord
));
// 7 bottom right near
scene.vertices.push(vertex::Vertex::new(
vec3(self.pos.x as f32 + 0.5, self.pos.y as f32 - 0.5, self.pos.z as f32 - 0.5),
vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 - cube_size),
self.color,
self.tex_coord
));

View file

@ -1,3 +1,4 @@
pub mod cube;
pub mod rec_cuboid;
pub mod quad;
pub mod drawable;

55
src/primitives/quad.rs Normal file
View file

@ -0,0 +1,55 @@
use vulkanalia::prelude::v1_0::*;
use cgmath::vec3;
use crate::vertex;
use crate::scene::Scene;
use crate::primitives::drawable::Drawable;
#[derive(Clone, Debug, PartialEq)]
pub struct Quad{
pub pos1: vertex::Vec3,
pub pos2: vertex::Vec3,
pub pos3: vertex::Vec3,
pub pos4: vertex::Vec3,
pub raster_pos: cgmath::Vector2<u32>,
pub volume_index: u32,
}
impl Drawable for Quad {
fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) {
if *topology == vk::PrimitiveTopology::TRIANGLE_LIST {
// 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.volume_index
));
// 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.volume_index
));
// 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.volume_index
));
// 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.volume_index
));
// 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);
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);
}
}
}

View file

@ -7,27 +7,32 @@ use cgmath::{vec2, vec3, Vector3};
use std::cell::RefCell;
use std::rc::Rc;
use std::time::Instant;
use crate::app_data::AppData;
use crate::buffer;
use crate::primitives::rec_cuboid::Cuboid;
use crate::vertex;
use crate::primitives::cube::Cube;
use crate::primitives::quad::Quad;
use crate::primitives::drawable::Drawable;
extern crate rand;
use rand::Rng;
const CHUNK_SIZE_EXPONENT: u32 = 9;
const CHUNK_SIZE_EXPONENT: u32 = 6;
const CHUNK_SIZE: usize = (2 as usize).pow(CHUNK_SIZE_EXPONENT);
const MAX_TREE_DEPTH: usize = 7;
const MAX_TREE_DEPTH: usize = 4;
const MIN_CHUNK_SIZE: usize = CHUNK_SIZE / (2 as usize).pow(MAX_TREE_DEPTH as u32);
#[derive(Clone, Debug, Default)]
pub struct Scene {
pub vertices: Vec<vertex::Vertex>,
pub sized_vertices: Vec<vertex::SizedVertex>,
pub rt_vertices: Vec<vertex::RTVertex>,
pub indices_cube: Vec<u32>,
pub indices_cuboid: Vec<u32>,
pub indices_rt: Vec<u32>,
pub vertex_buffer_cube: vk::Buffer,
pub vertex_buffer_memory_cube: vk::DeviceMemory,
@ -40,18 +45,22 @@ pub struct Scene {
pub index_buffer_cuboid: vk::Buffer,
pub index_buffer_memory_cuboid: vk::DeviceMemory,
pub vertex_buffer_quad: vk::Buffer,
pub vertex_buffer_memory_quad: vk::DeviceMemory,
pub index_buffer_quad: vk::Buffer,
pub index_buffer_memory_quad: vk::DeviceMemory,
}
impl Scene {
pub unsafe fn prepare_data(&mut self, instance: &vulkanalia::Instance, device: &vulkanalia::Device, data: &AppData) -> Result<()> {
let mut rng = rand::thread_rng();
let grid_size = 512; //CHUNK_SIZE as i32;
let grid_size = CHUNK_SIZE as i32;
// todo store the chunks somewhere (or only use them as intermediary for neighbouthood calculation idc)
let mut oct_tree: OctTree<Cube> = OctTree::create(CHUNK_SIZE)?;
//todo use the 14 vertice box method. Not using geometry shaders seems to be faster... make this a setting?
// have cube elements with a method asking for vertices, while giving a primitive type -> method for preferred primitive type as well as one collecting all primitives
for x_index in 0..grid_size {
for y_index in 0..grid_size {
let shade = (rng.gen_range(0..25) as f32) / 100.0;
@ -65,8 +74,18 @@ impl Scene {
}
}
let mut test = EmptyVolume::from_oct_tree(&oct_tree);
println!("number of empty volumes is {}", test.len());
let shade = (rng.gen_range(0..25) as f32) / 100.0;
let cube = Cube {
pos: vec3(10.0, 10.0, 10.0),
color: vec3(shade, 1.0, shade),
tex_coord: vec2(0.0, 0.0)
};
oct_tree.set_cube(cube.clone());
let mut empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>;
(empty_volumes, _) = EmptyVolume::from_oct_tree(&oct_tree);
println!("number of empty volumes is {}", empty_volumes.len());
let oct_tree_iter = OctTreeIter::create(&oct_tree)?;
for item in oct_tree_iter {
@ -74,7 +93,7 @@ impl Scene {
let index = self.vertices.len();
match item {
Some(cube) => {
if (cube.pos.x + cube.pos.y) as usize % 2 == 0{
/*if (cube.pos.x + cube.pos.y) as usize % 2 == 0{
/**/
let cuboid = Cuboid {
pos: cube.pos,
@ -86,12 +105,20 @@ impl Scene {
}
else {
cube.draw(&data.topology, index, self);
}
}*/
cube.draw(&data.topology, index, self);
}
None => {}
}
}
for volume in empty_volumes {
let quads = volume.borrow().to_quads();
for quad in quads {
quad.draw(&data.topology, self.rt_vertices.len(), self);
}
}
if self.vertices.len() != 0 {
(self.vertex_buffer_cube, self.vertex_buffer_memory_cube) = buffer::create_vertex_buffer(instance, device, &data, &self.vertices)?;
(self.index_buffer_cube, self.index_buffer_memory_cube) = buffer::create_index_buffer(&instance, &device, &data, &self.indices_cube)?;
@ -102,6 +129,11 @@ impl Scene {
(self.index_buffer_cuboid, self.index_buffer_memory_cuboid) = buffer::create_index_buffer(&instance, &device, &data, &self.indices_cuboid)?;
}
if self.rt_vertices.len() != 0 {
(self.vertex_buffer_quad, self.vertex_buffer_memory_quad) = buffer::create_vertex_buffer(instance, device, &data, &self.rt_vertices)?;
(self.index_buffer_quad, self.index_buffer_memory_quad) = buffer::create_index_buffer(&instance, &device, &data, &self.indices_rt)?;
}
Ok(())
}
@ -118,6 +150,12 @@ impl Scene {
device.destroy_buffer(self.vertex_buffer_cuboid, None);
device.free_memory(self.vertex_buffer_memory_cuboid, None);
device.destroy_buffer(self.index_buffer_quad, None);
device.free_memory(self.index_buffer_memory_quad, None);
device.destroy_buffer(self.vertex_buffer_quad, None);
device.free_memory(self.vertex_buffer_memory_quad, None);
}
}
@ -617,22 +655,22 @@ struct EmptyVolume {
pub color_back: Vec<Vector3<u8>>,
pub color_top: Vec<Vector3<u8>>,
pub color_bottom: Vec<Vector3<u8>>,
pub color_left: Vec<Vector3<u8>>,
pub color_right: Vec<Vector3<u8>>,
pub color_back_rn: Vec<Vector3<u8>>,
pub color_front_rn: Vec<Vector3<u8>>,
pub roughness_front: Vec<Vector3<u8>>,
pub roughness_back: Vec<Vector3<u8>>,
pub roughness_top: Vec<Vector3<u8>>,
pub roughness_bottom: Vec<Vector3<u8>>,
pub roughness_left: Vec<Vector3<u8>>,
pub roughness_right: Vec<Vector3<u8>>,
pub roughness_back_rn: Vec<Vector3<u8>>,
pub roughness_front_rn: Vec<Vector3<u8>>,
pub neighbor_front: Vec<Rc<RefCell<Self>>>,
pub neighbor_back: Vec<Rc<RefCell<Self>>>,
pub neighbor_top: Vec<Rc<RefCell<Self>>>,
pub neighbor_bottom: Vec<Rc<RefCell<Self>>>,
pub neighbor_left: Vec<Rc<RefCell<Self>>>,
pub neighbor_right: Vec<Rc<RefCell<Self>>>,
pub neighbor_front: Vec<Option<Rc<RefCell<Self>>>>,
pub neighbor_back: Vec<Option<Rc<RefCell<Self>>>>,
pub neighbor_top: Vec<Option<Rc<RefCell<Self>>>>,
pub neighbor_bottom: Vec<Option<Rc<RefCell<Self>>>>,
pub neighbor_back_rn: Vec<Option<Rc<RefCell<Self>>>>,
pub neighbor_front_rn: Vec<Option<Rc<RefCell<Self>>>>,
}
impl EmptyVolume {
@ -642,11 +680,12 @@ impl EmptyVolume {
self.position[2] + self.size_z > pos[2] && pos[2] >= self.position[2]
}
pub fn from_oct_tree(tree: &OctTree<Cube>) -> Vec<Rc<RefCell<EmptyVolume>>> {
pub fn from_oct_tree(tree: &OctTree<Cube>) -> (Vec<Rc<RefCell<EmptyVolume>>>, OctTree<Rc<RefCell<EmptyVolume>>>) {
// todo: ppotentially use a child exist check while going through the oct tree to find some obvios starting empty volumes. Will still need to check for possible expansions though
let mut volumes: Vec<Rc<RefCell<EmptyVolume>>> = vec![];
let mut neighbors: OctTree<Rc<RefCell<EmptyVolume>>> = OctTree::create(tree.size).unwrap();
let start_time = Instant::now();
// iterate over all block positions in the oct tree
for x_index in 0..tree.size {
for y_index in 0..tree.size {
@ -664,6 +703,7 @@ impl EmptyVolume {
for volume in &volumes {
if volume.borrow().contains(&Vector3{x: x_index, y: y_index, z: z_index}) {
contained = true;
break;
}
}
if contained {
@ -736,20 +776,20 @@ impl EmptyVolume {
color_back: vec![],
color_top: vec![],
color_bottom: vec![],
color_left: vec![],
color_right: vec![],
color_back_rn: vec![],
color_front_rn: vec![],
roughness_front: vec![],
roughness_back: vec![],
roughness_top: vec![],
roughness_bottom: vec![],
roughness_left: vec![],
roughness_right: vec![],
roughness_back_rn: vec![],
roughness_front_rn: vec![],
neighbor_front: vec![],
neighbor_back: vec![],
neighbor_top: vec![],
neighbor_bottom: vec![],
neighbor_left: vec![],
neighbor_right: vec![],
neighbor_back_rn: vec![],
neighbor_front_rn: vec![],
};
println!("adding neighbor references");
//fill in info in the neighbor octtree
@ -757,12 +797,202 @@ impl EmptyVolume {
for x in 0..x_size+1 {
for y in 0..y_size+1 {
for z in 0..z_size+1 {
// fill only the edges
if x == 0 || x == x_size || y == 0 || y == y_size || z==0 || z == z_size {
neighbors.set_element(reference.clone(), reference.borrow().position.x + x, reference.borrow().position.y + y, reference.borrow().position.z + z)
}
}
}
}
println!("add the border information for color and roughness");
let x_min_pos;
if reference.borrow().position.x == 0 {
// will result in an empty color and roughness map.
x_min_pos = 0;
}
else {
x_min_pos = reference.borrow().position.x -1;
}
let y_min_pos;
if reference.borrow().position.y == 0 {
// will result in an empty color and roughness map.
y_min_pos = 0;
}
else {
y_min_pos = reference.borrow().position.y -1;
}
let z_min_pos;
if reference.borrow().position.z == 0 {
// will result in an empty color and roughness map.
z_min_pos = 0;
}
else {
z_min_pos = reference.borrow().position.z -1;
}
let x_max_pos = reference.borrow().position.x + reference.borrow().size_x;
let y_max_pos = reference.borrow().position.y + reference.borrow().size_y;
let z_max_pos = reference.borrow().position.z + reference.borrow().size_z;
// bottom face of the volume
let mut bottom_colors = vec![];
let mut bottom_roughness = vec![];
let mut bottom_elements_num = 0;
for x in 0..x_size+1 {
for y in 0..y_size+1 {
if let Some(c) = tree.get_element(reference.borrow().position.x + x, reference.borrow().position.y + y, z_min_pos) {
bottom_elements_num += 1;
let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
bottom_colors.push(u8_color);
bottom_roughness.push(Vector3 {x: 128, y: 128, z: 128});
}
else {
bottom_colors.push(Vector3 { x: 255, y: 255, z: 255 });
bottom_roughness.push(Vector3 {x: 255, y: 255, z: 255});
}
}
}
if bottom_elements_num > 0 {
reference.borrow_mut().color_bottom = bottom_colors;
reference.borrow_mut().roughness_bottom = bottom_roughness;
}
else {
reference.borrow_mut().color_bottom= vec![];
reference.borrow_mut().roughness_bottom= vec![];
}
// top face of the volume
let mut top_colors = vec![];
let mut top_roughness = vec![];
let mut top_elements_num = 0;
for x in 0..x_size+1 {
for y in 0..y_size+1 {
if let Some(c) = tree.get_element(reference.borrow().position.x + x, reference.borrow().position.y + y, z_max_pos) {
top_elements_num += 1;
let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
top_colors.push(u8_color);
top_roughness.push(Vector3 {x: 128, y: 128, z: 128});
}
else {
top_colors.push(Vector3 { x: 255, y: 255, z: 255 });
top_roughness.push(Vector3 {x: 255, y: 255, z: 255});
}
}
}
if top_elements_num > 0 {
reference.borrow_mut().color_top = top_colors;
reference.borrow_mut().roughness_top = top_roughness;
}
else {
reference.borrow_mut().color_top= vec![];
reference.borrow_mut().roughness_top= vec![];
}
// back face of the volume
let mut back_colors_rn = vec![];
let mut back_roughness_rn = vec![];
let mut back_elements_num_rn = 0;
for x in 0..x_size+1 {
for z in 0..z_size+1 {
if let Some(c) = tree.get_element(reference.borrow().position.x + x, y_max_pos, reference.borrow().position.z + z) {
back_elements_num_rn += 1;
let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
back_colors_rn.push(u8_color);
back_roughness_rn.push(Vector3 {x: 128, y: 128, z: 128});
}
else {
back_colors_rn.push(Vector3 { x: 255, y: 255, z: 255 });
back_roughness_rn.push(Vector3 {x: 255, y: 255, z: 255});
}
}
}
if back_elements_num_rn > 0 {
reference.borrow_mut().color_back_rn = back_colors_rn;
reference.borrow_mut().roughness_back_rn = back_roughness_rn;
}
else {
reference.borrow_mut().color_back_rn= vec![];
reference.borrow_mut().roughness_back_rn= vec![];
}
// front face of the volume
let mut front_colors_rn = vec![];
let mut front_roughness_rn = vec![];
let mut front_elements_num_rn = 0;
for x in 0..x_size+1 {
for z in 0..z_size+1 {
if let Some(c) = tree.get_element(reference.borrow().position.x + x, y_min_pos, reference.borrow().position.z + z) {
front_elements_num_rn += 1;
let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
front_colors_rn.push(u8_color);
front_roughness_rn.push(Vector3 {x: 128, y: 128, z: 128});
}
else {
front_colors_rn.push(Vector3 { x: 255, y: 255, z: 255 });
front_roughness_rn.push(Vector3 {x: 255, y: 255, z: 255});
}
}
}
if front_elements_num_rn > 0 {
reference.borrow_mut().color_front_rn = front_colors_rn;
reference.borrow_mut().roughness_front_rn = front_roughness_rn;
}
else {
reference.borrow_mut().color_front_rn= vec![];
reference.borrow_mut().roughness_front_rn= vec![];
}
// front face of the volume
let mut front_colors = vec![];
let mut front_roughness = vec![];
let mut front_elements_num = 0;
for y in 0..y_size+1 {
for z in 0..z_size+1 {
if let Some(c) = tree.get_element(x_min_pos, reference.borrow().position.y + y, reference.borrow().position.z + z) {
front_elements_num += 1;
let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
front_colors.push(u8_color);
front_roughness.push(Vector3 {x: 128, y: 128, z: 128});
}
else {
front_colors.push(Vector3 { x: 255, y: 255, z: 255 });
front_roughness.push(Vector3 {x: 255, y: 255, z: 255});
}
}
}
if front_elements_num > 0 {
reference.borrow_mut().color_front = front_colors;
reference.borrow_mut().roughness_front = front_roughness;
}
else {
reference.borrow_mut().color_front= vec![];
reference.borrow_mut().roughness_front= vec![];
}
// back face of the volume
let mut back_colors = vec![];
let mut back_roughness = vec![];
let mut back_elements_num = 0;
for y in 0..y_size+1 {
for z in 0..z_size+1 {
if let Some(c) = tree.get_element(x_max_pos, reference.borrow().position.y + y, reference.borrow().position.z + z) {
back_elements_num += 1;
let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
back_colors.push(u8_color);
back_roughness.push(Vector3 {x: 128, y: 128, z: 128});
}
else {
back_colors.push(Vector3 { x: 255, y: 255, z: 255 });
back_roughness.push(Vector3 {x: 255, y: 255, z: 255});
}
}
}
if back_elements_num > 0 {
reference.borrow_mut().color_back = back_colors;
reference.borrow_mut().roughness_back = back_roughness;
}
else {
reference.borrow_mut().color_back= vec![];
reference.borrow_mut().roughness_back= vec![];
}
println!("new volume done");
//push to the list
volumes.push(reference);
@ -771,8 +1001,268 @@ impl EmptyVolume {
}
}
}
println!("add the neighbor linkage for all the volumes of the oct tree");
for reference in volumes.iter_mut() {
let x_min_pos;
if reference.borrow().position.x == 0 {
// will result in an empty color and roughness map.
x_min_pos = 0;
}
else {
x_min_pos = reference.borrow().position.x -1;
}
let y_min_pos;
if reference.borrow().position.y == 0 {
// will result in an empty color and roughness map.
y_min_pos = 0;
}
else {
y_min_pos = reference.borrow().position.y -1;
}
let z_min_pos;
if reference.borrow().position.z == 0 {
// will result in an empty color and roughness map.
z_min_pos = 0;
}
else {
z_min_pos = reference.borrow().position.z -1;
}
let x_max_pos = reference.borrow().position.x + reference.borrow().size_x;
let y_max_pos = reference.borrow().position.y + reference.borrow().size_y;
let z_max_pos = reference.borrow().position.z + reference.borrow().size_z;
// bottom face of the volume
let mut bottom_neighbors = vec![];
let mut bottom_elements_num = 0;
if z_min_pos != 0 {
for x in 0..reference.borrow().size_x {
for y in 0..reference.borrow().size_y {
if let Some(c) = neighbors.get_element(reference.borrow().position.x + x, reference.borrow().position.y + y, z_min_pos) {
bottom_elements_num += 1;
bottom_neighbors.push(Some(c.clone()));
}
else {
bottom_neighbors.push(None);
}
}
}
}
if bottom_elements_num > 0 {
reference.borrow_mut().neighbor_bottom = bottom_neighbors;
}
else {
reference.borrow_mut().neighbor_bottom = vec![None];
}
// top face of the volume
let mut top_neighbors = vec![];
let mut top_elements_num = 0;
for x in 0..reference.borrow().size_x {
for y in 0..reference.borrow().size_y {
if let Some(c) = neighbors.get_element(reference.borrow().position.x + x, reference.borrow().position.y + y, z_max_pos) {
top_elements_num += 1;
top_neighbors.push(Some(c.clone()));
}
else {
top_neighbors.push(None);
}
}
}
if top_elements_num > 0 {
reference.borrow_mut().neighbor_top = top_neighbors;
}
else {
reference.borrow_mut().neighbor_top = vec![None];
}
volumes
// left face of the volume
let mut back_neighbors_rn = vec![];
let mut back_elements_num_rn = 0;
for x in 0..reference.borrow().size_x {
for z in 0..reference.borrow().size_z {
if let Some(c) = neighbors.get_element(reference.borrow().position.x + x, y_max_pos, reference.borrow().position.z + z) {
back_elements_num_rn += 1;
back_neighbors_rn.push(Some(c.clone()));
}
else {
back_neighbors_rn.push(None);
}
}
}
if back_elements_num_rn > 0 {
reference.borrow_mut().neighbor_back_rn = back_neighbors_rn;
}
else {
reference.borrow_mut().neighbor_back_rn = vec![None];
}
// right face of the volume
let mut front_neighbors_rn = vec![];
let mut front_elements_num_rn = 0;
if y_min_pos != 0{
for x in 0..reference.borrow().size_x {
for z in 0..reference.borrow().size_z {
if let Some(c) = neighbors.get_element(reference.borrow().position.x + x, y_min_pos, reference.borrow().position.z + z) {
front_elements_num_rn += 1;
front_neighbors_rn.push(Some(c.clone()));
}
else {
front_neighbors_rn.push(None);
}
}
}
}
if front_elements_num_rn > 0 {
reference.borrow_mut().neighbor_front_rn = front_neighbors_rn;
}
else {
reference.borrow_mut().neighbor_front_rn = vec![None];
}
// front face of the volume
let mut front_neighbors = vec![];
let mut front_elements_num = 0;
if x_min_pos != 0 {
for y in 0..reference.borrow().size_y {
for z in 0..reference.borrow().size_z {
if let Some(c) = neighbors.get_element(x_min_pos, reference.borrow().position.y + y, reference.borrow().position.z + z) {
front_elements_num += 1;
front_neighbors.push(Some(c.clone()));
}
else {
front_neighbors.push(None);
}
}
}
}
if front_elements_num > 0 {
reference.borrow_mut().neighbor_front = front_neighbors;
}
else {
reference.borrow_mut().neighbor_front = vec![None];
}
// back face of the volume
let mut back_neighbors = vec![];
let mut back_elements_num = 0;
for y in 0..reference.borrow().size_y {
for z in 0..reference.borrow().size_z {
if let Some(c) = neighbors.get_element(x_max_pos, reference.borrow().position.y + y, reference.borrow().position.z + z) {
back_elements_num += 1;
back_neighbors.push(Some(c.clone()));
}
else {
back_neighbors.push(None);
}
}
}
if back_elements_num > 0 {
reference.borrow_mut().neighbor_back = back_neighbors;
}
else {
reference.borrow_mut().neighbor_back = vec![None];
}
}
println!("volume creation took {} s", start_time.elapsed().as_millis() as f32 / 1000.0);
(volumes, neighbors)
}
fn to_quads(&self) -> Vec<Quad> {
let mut quads = vec![];
let float_pos = Vector3 {x: self.position.x as f32, y: self.position.y as f32, z: self.position.z as f32};
//bottom sides of the volumes, top side of the block
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() == 0 {
continue;
}
if self.neighbor_bottom.len() > index {
if let Some(_) = self.neighbor_bottom[index] {
continue;
}
}
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 },
raster_pos: cgmath::Vector2 { x: x as u32, y: y as u32 },
volume_index: 0
};
quads.push(quad);
}
}
//top sides of the volumes, bottom side of the block
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 {
continue;
}
if self.neighbor_top.len() > index {
if let Some(_) = self.neighbor_top[index] {
continue;
}
}
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 },
raster_pos: cgmath::Vector2 { x: x as u32, y: y as u32 },
volume_index: 0
};
quads.push(quad);
}
}
//front sides of the volumes, back side of the block
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_rn.len() == 0 {
continue;
}
if self.neighbor_front_rn.len() > index {
if let Some(_) = self.neighbor_front_rn[index] {
continue;
}
}
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 },
raster_pos: cgmath::Vector2 { x: x as u32, y: z as u32 },
volume_index: 0
};
quads.push(quad);
}
}
//back sides of the volumes, front side of the block
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_rn.len() == 0 {
continue;
}
if self.neighbor_back_rn.len() > index {
if let Some(_) = self.neighbor_back_rn[index] {
continue;
}
}
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 },
raster_pos: cgmath::Vector2 { x: x as u32, y: z as u32 },
volume_index: 0
};
quads.push(quad);
}
}
quads
}
}

View file

@ -162,3 +162,72 @@ impl Hash for SizedVertex {
self.tex_coord[1].to_bits().hash(state);
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct RTVertex {
pub pos: Vec3,
pub raster_pos: cgmath::Vector2<u32>,
pub volume_start: u32,
}
impl RTVertex {
pub const fn new(pos: Vec3, raster_pos: cgmath::Vector2<u32>, volume_start: u32) -> Self {
Self { pos, raster_pos, volume_start }
}
}
impl VertexContainer<3> for RTVertex {
fn binding_description() -> vk::VertexInputBindingDescription {
vk::VertexInputBindingDescription::builder()
.binding(0)
.stride(size_of::<RTVertex>() as u32)
.input_rate(vk::VertexInputRate::VERTEX)
.build()
}
fn attribute_descriptions() -> [vk::VertexInputAttributeDescription; 3] {
let pos = vk::VertexInputAttributeDescription::builder()
.binding(0)
.location(0)
.format(vk::Format::R32G32B32_SFLOAT)
.offset(0)
.build();
let raster_pos = vk::VertexInputAttributeDescription::builder()
.binding(0)
.location(1)
.format(vk::Format::R32G32_UINT)
.offset(size_of::<Vec3>() as u32)
.build();
let volume_start = vk::VertexInputAttributeDescription::builder()
.binding(0)
.location(2)
.format(vk::Format::R32_UINT)
.offset((size_of::<Vec3>() + size_of::<cgmath::Vector2<u32>>()) as u32)
.build();
[pos, raster_pos, volume_start]
}
}
impl PartialEq for RTVertex {
fn eq(&self, other: &Self) -> bool {
self.pos == other.pos
&& self.raster_pos == other.raster_pos
&& self.volume_start == other.volume_start
}
}
impl Eq for RTVertex {}
impl Hash for RTVertex {
fn hash<H: Hasher>(&self, state: &mut H) {
self.pos[0].to_bits().hash(state);
self.pos[1].to_bits().hash(state);
self.pos[2].to_bits().hash(state);
self.raster_pos[0].hash(state);
self.raster_pos[1].hash(state);
self.volume_start.hash(state);
}
}