use super::Scene; use super::oct_tree::{CHUNK_SIZE, OctTree}; use crate::primitives::cube::Cube; use crate::primitives::rec_cuboid::Cuboid; use crate::primitives::drawable::Drawable; use crate::app_data::AppData; use super::volumetrics::{Cone, Rect, ShapeComposition, Sphere}; extern crate rand; use rand::Rng; use anyhow::{Ok, Result}; use cgmath::{vec2, vec3, Vector3, Point3}; use std::cell::RefCell; use std::rc::Rc; use super::light::{DirectionalLight, PointLight}; pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Point3<f32>)> { let mut rng = rand::thread_rng(); let grid_size = CHUNK_SIZE as i32; let scale = 1.0; let mut oct_tree1: OctTree<Cube> = OctTree::create(CHUNK_SIZE, scale)?; let mut oct_tree2: OctTree<Cube> = OctTree::create(CHUNK_SIZE, scale)?; for x_index in 0..grid_size { for y_index in 0..grid_size { let shade = (rng.gen_range(0..50) as f32) / 100.0; let cube = Cube { pos: vec3(x_index as f32, y_index as f32, 5.0), color: vec3(shade, 1.0, shade), tex_coord: vec2(0.0, 0.0), transparent: false, roughness: 255, }; oct_tree1.set_cube(cube.clone()); let shade = (rng.gen_range(0..50) as f32) / 100.0; let cube = Cube { pos: vec3(x_index as f32, y_index as f32, 6.0), color: vec3(shade, 1.0, shade), tex_coord: vec2(0.0, 0.0), transparent: false, roughness: 255, }; oct_tree2.set_cube(cube.clone()); } } let shade = (rng.gen_range(0..25) as f32) / 100.0; let cube = Cube { pos: vec3(10.0, 10.0, 10.0), color: vec3(0.0, 0.0, 0.9), tex_coord: vec2(0.0, 0.0), transparent: true, roughness: 32, }; oct_tree1.set_cube(cube.clone()); let cube = Cube { pos: vec3(10.0, 10.0, 9.0), color: vec3(0.0, 0.0, 0.9), tex_coord: vec2(0.0, 0.0), transparent: true, roughness: 32, }; oct_tree1.set_cube(cube.clone()); let cube = Cube { pos: vec3(10.0, 10.0, 10.0), color: vec3(0.9, 0.0, 0.0), tex_coord: vec2(0.0, 0.0), transparent: true, roughness: 32, }; oct_tree2.set_cube(cube.clone()); let cube = Cube { pos: vec3(10.0, 10.0, 9.0), color: vec3(0.9, 0.0, 0.0), tex_coord: vec2(0.0, 0.0), transparent: true, roughness: 32, }; oct_tree2.set_cube(cube.clone()); scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(11.0 + grid_size as f32, 11.0 + grid_size as f32, 11.0) * scale, vec3(2.0, 2.0, 2.0))))); scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(9.0 + grid_size as f32, 9.0 + grid_size as f32, 11.0) * scale, vec3(0.5, 0.5, 0.5))))); scene.directional_lights.push(Rc::new(RefCell::new(DirectionalLight::init(vec3(1.0, 1.0, -1.0), vec3(0.1, 0.1, 0.1))))); let cube = Cuboid { pos: vec3(11.0 + grid_size as f32, 11.0 + grid_size as f32, 11.0) * scale, color: vec3(1.0, 1.0, 1.0), tex_coord: vec2(0.0, 0.0), size: Vector3 {x: 0.5, y: 0.5, z: 0.5} * scale }; let index = scene.sized_vertices.len(); cube.draw(&data.topology, index, scene); let cube = Cuboid { pos: vec3(9.0 + grid_size as f32, 9.0 + grid_size as f32, 11.0) * scale, color: vec3(1.0, 1.0, 1.0), tex_coord: vec2(0.0, 0.0), size: Vector3 {x: 0.5, y: 0.5, z: 0.5} * scale }; let index = scene.sized_vertices.len(); cube.draw(&data.topology, index, scene); 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_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()]]]; let mut comp = ShapeComposition::new(64); comp.included_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 2.0, Vector3 { x: 0, y: 255, z: 0 }, 64, false)))); comp.included_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 2.5, Vector3 { x: 255, y: 0, z: 0 }, 64, false)))); comp.excluded_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 11.5 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 1.5, Vector3 { x: 0, y: 255, z: 0 }, 64, false)))); scene.volumetrics.push(Rc::new(RefCell::new(comp))); let mut comp = ShapeComposition::new(64); comp.included_shapes.push(Rc::new(RefCell::new(Cone::new(Vector3 { x: 20.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 0.0, 2.5, Vector3 { x: 0.0, y: 10.0, z: 0.0 },Vector3 { x: 0, y: 255, z: 0 }, 64, false)))); comp.excluded_shapes.push(Rc::new(RefCell::new(Cone::new(Vector3 { x: 20.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 0.0, 1.5, Vector3 { x: 0.0, y: 10.0, z: 0.0 },Vector3 { x: 0, y: 255, z: 0 }, 64, false)))); scene.volumetrics.push(Rc::new(RefCell::new(comp))); let mut comp = ShapeComposition::new(64); comp.included_shapes.push(Rc::new(RefCell::new(Rect::new(Vector3 { x: -5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, Vector3 { x: 5.0, y: 10.0, z: 2.0 },Vector3 { x: 0, y: 0, z: 255 }, 64, false)))); comp.excluded_shapes.push(Rc::new(RefCell::new(Rect::new(Vector3 { x: -5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, Vector3 { x: 3.0, y: 8.0, z: 2.0 },Vector3 { x: 0, y: 0, z: 255 }, 64, false)))); scene.volumetrics.push(Rc::new(RefCell::new(comp))); Ok((cgmath::point3(5.0, 5.0, 10.0))) } pub fn generate_test_scene2(scene: &mut Scene, data: &mut AppData, chunk_num_x: usize, chunk_num_y: usize, chunk_num_z: usize, num_gaussians: usize) -> Result<(Point3<f32>)> { let mut rng = rand::thread_rng(); let scale = 1.0; let grid_size = CHUNK_SIZE as i32; let max_x = chunk_num_x * grid_size as usize; let max_y = chunk_num_y * grid_size as usize; let max_z = chunk_num_z * grid_size as usize; let mut height_map = vec![vec![0.0; max_y]; max_x]; for i in 0..num_gaussians { 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; let spread_x = rng.gen_range(0..max_x/2) as f32; let spread_y = rng.gen_range(0..max_y/2) as f32; for x in 0..max_x { for y in 0..max_y { height_map[x][y] += height * (-((x as f32 - center_x).powf(2.0)/(2.0 * spread_x.powf(2.0)) + (y as f32 - center_y).powf(2.0)/(2.0 * spread_y.powf(2.0)))).exp(); } } } let mut oct_trees = vec![]; for z in 0..chunk_num_z { oct_trees.push(vec![]); for y in 0..chunk_num_y { oct_trees[z].push(vec![]); for x in 0..chunk_num_x { oct_trees[z][y].push(Rc::new(RefCell::new(OctTree::<Cube>::create(CHUNK_SIZE, scale)?))); } } } for x in 0..max_x { for y in 0..max_y { let height = height_map[x][y].floor() as usize; let mut pillar_height; if height < max_z { let shade = (rng.gen_range(0..50) as f32) / 100.0; let cube = Cube { pos: vec3((x % grid_size as usize) as f32, (y % grid_size as usize) as f32, (height % grid_size as usize) as f32), color: vec3(shade, 1.0, shade), tex_coord: vec2(0.0, 0.0), transparent: false, roughness: 255, }; oct_trees[((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()); pillar_height = height; } else { pillar_height = max_z; } while pillar_height > 0 { pillar_height -= 1; let shade = (rng.gen_range(1..50) as f32) / 100.0; let cube = Cube { pos: vec3((x % grid_size as usize) as f32, (y % grid_size as usize) as f32, (pillar_height % grid_size as usize) as f32), color: vec3(shade, shade / 2.0, 0.0), tex_coord: vec2(0.0, 0.0), transparent: false, 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()); } } } for i in 0..num_gaussians { let height = rng.gen_range(1..8) as f32; let center_x = rng.gen_range(0..max_x) as f32; let center_y = rng.gen_range(0..max_y) as f32; let final_height = height_map[center_x.floor() as usize][center_y.floor() as usize] + height; scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(center_x, center_y, final_height), vec3(1.0, 1.0, 1.0))))); let cube = Cuboid { pos: vec3(center_x, center_y, final_height), color: vec3(1.0, 1.0, 1.0), tex_coord: vec2(0.0, 0.0), size: Vector3 {x: 0.5, y: 0.5, z: 0.5} }; let index = scene.sized_vertices.len(); cube.draw(&data.topology, index, scene); } //scene.directional_lights.push(Rc::new(RefCell::new(DirectionalLight { direction: vec3(0.5, 0.0, -1.0), color: vec3(0.1, 0.1, 0.1), memory_start: 0 }))); scene.oct_trees = oct_trees; Ok(cgmath::point3((max_x as f32 / 2.0) as f32, (max_y as f32 / 2.0) as f32, height_map[(max_x as f32 / 2.0).floor() as usize][(max_y as f32 / 2.0).floor() as usize] + 2000.0)) }