From 87be7205a45c128dc4f9de10bda6433b603a25b3 Mon Sep 17 00:00:00 2001 From: Markus Moenig Date: Tue, 17 Sep 2024 15:06:07 +0700 Subject: [PATCH] Take material from FT, cleanup --- creator/src/minimap.rs | 30 +- creator/src/terraineditor.rs | 1 + creator/src/tools/terrain/height.rs | 2 +- shared/src/bsdf.rs | 3 +- shared/src/geofxnode.rs | 65 +-- shared/src/geofxobject.rs | 14 +- shared/src/lib.rs | 4 +- shared/src/materialfxobject.rs | 417 ---------------- shared/src/renderer.rs | 741 +--------------------------- 9 files changed, 37 insertions(+), 1240 deletions(-) diff --git a/creator/src/minimap.rs b/creator/src/minimap.rs index b6818a64..88a12d8c 100644 --- a/creator/src/minimap.rs +++ b/creator/src/minimap.rs @@ -44,7 +44,7 @@ pub fn draw_minimap(region: &Region, buffer: &mut TheRGBABuffer, palette: &ThePa material_params.insert(*id, params); } - let grid_size = region.grid_size as f32; + //let grid_size = region.grid_size as f32; let pixels = buffer.pixels_mut(); pixels @@ -157,6 +157,8 @@ pub fn draw_minimap(region: &Region, buffer: &mut TheRGBABuffer, palette: &ThePa } } + /* TODO + let p = vec2f(x as f32, y as f32); let mut hit = Hit { global_uv: vec2f( @@ -196,7 +198,7 @@ pub fn draw_minimap(region: &Region, buffer: &mut TheRGBABuffer, palette: &ThePa } } if is_legit { - let mut c = WHITE; + let c; // = WHITE; hit.mat.base_color = vec3f(0.5, 0.5, 0.5); hit.value = 1.0; @@ -226,22 +228,16 @@ pub fn draw_minimap(region: &Region, buffer: &mut TheRGBABuffer, palette: &ThePa &mat_obj_params, ); - if material.test_height_profile( + material.compute( &mut hit, - geo_obj, + palette, + &tile_drawer.tiles, &mat_obj_params, - ) { - material.compute( - &mut hit, - palette, - &tile_drawer.tiles, - &mat_obj_params, - ); - - let col = - TheColor::from_vec3f(hit.mat.base_color).to_u8_array(); - c = col; - } + ); + + let col = + TheColor::from_vec3f(hit.mat.base_color).to_u8_array(); + c = col; } else { let col = TheColor::from_vec3f(hit.mat.base_color).to_u8_array(); @@ -253,7 +249,7 @@ pub fn draw_minimap(region: &Region, buffer: &mut TheRGBABuffer, palette: &ThePa } } } - } + }*/ pixel.copy_from_slice(&color); } diff --git a/creator/src/terraineditor.rs b/creator/src/terraineditor.rs index d2765b67..0c221c04 100644 --- a/creator/src/terraineditor.rs +++ b/creator/src/terraineditor.rs @@ -51,6 +51,7 @@ impl TerrainEditor { _server_ctx: &mut ServerContext, ) -> bool { let redraw = false; + #[allow(clippy::match_single_binding)] match event { // TheEvent::TileEditorHoverChanged(id, coord) => { // if id.name == "TerrainMap View" { diff --git a/creator/src/tools/terrain/height.rs b/creator/src/tools/terrain/height.rs index e37780d7..e13bd1ae 100644 --- a/creator/src/tools/terrain/height.rs +++ b/creator/src/tools/terrain/height.rs @@ -3,7 +3,7 @@ use rayon::prelude::*; use ToolEvent::*; use crate::editor::{ - BRUSHLIST, MODELFXEDITOR, PANELS, PRERENDERTHREAD, TERRAINEDITOR, TILEDRAWER, UNDOMANAGER, + BRUSHLIST, MODELFXEDITOR, PANELS, PRERENDERTHREAD, TERRAINEDITOR, UNDOMANAGER, }; pub struct TerrainHeightTool { diff --git a/shared/src/bsdf.rs b/shared/src/bsdf.rs index 4fad6baa..3c912b75 100644 --- a/shared/src/bsdf.rs +++ b/shared/src/bsdf.rs @@ -1,6 +1,7 @@ use crate::prelude::*; use theframework::prelude::*; +/* #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub struct BSDFMedium { pub type_: i32, @@ -97,7 +98,7 @@ impl BSDFMaterial { self.ior = lerp(mat1.ior, mat2.ior, t); } } - +*/ pub struct BSDFLight { pub position: Vec3f, pub emission: Vec3f, diff --git a/shared/src/geofxnode.rs b/shared/src/geofxnode.rs index 1e3675a1..2e2dd488 100644 --- a/shared/src/geofxnode.rs +++ b/shared/src/geofxnode.rs @@ -105,7 +105,7 @@ impl GeoFXNode { coll.set("Pos Y", TheValue::Float(0.5)); coll.set("Length", TheValue::FloatRange(1.0, 0.001..=1.0)); coll.set("Height", TheValue::FloatRange(1.0, 0.001..=3.0)); - coll.set("Thickness", TheValue::FloatRange(0.2, 0.001..=1.0)); + coll.set("Thickness", TheValue::FloatRange(0.1, 0.001..=1.0)); // coll.set( // "2D Mode", // TheValue::TextList(0, vec![str!("Normal"), str!("Full Thickness")]), @@ -354,40 +354,6 @@ impl GeoFXNode { // } } - /// Loads the parameters of the nodes into memory for faster access. - pub fn load_parameters(&self, time: &TheTime) -> Vec { - let mut params = vec![]; - - if let Some(coll) = self.timeline.get_collection_at(time, str!("Geo")) { - params.push(coll.get_f32_default("Pos X", 0.0)); - params.push(coll.get_f32_default("Pos Y", 0.0)); - match self.role { - Column => { - params.push(coll.get_f32_default("Radius", 0.4)); - params.push(coll.get_f32_default("Height", 1.0)); - params.push(coll.get_f32_default("Hole", 0.0)); - } - LeftWall | TopWall | RightWall | BottomWall | MiddleWallH | MiddleWallV => { - params.push(coll.get_f32_default("Length", 1.0) / 2.0 + 0.1); - params.push(coll.get_f32_default("Height", 1.0)); - params.push(coll.get_f32_default("Thickness", 0.2)); - } - // BendWallNW | BendWallNE | BendWallSW | BendWallSE => { - // params.push(coll.get_f32_default("Thickness", 0.2)); - // params.push(coll.get_f32_default("Rounding", 0.3)); - // params.push(coll.get_f32_default("Height", 1.0)); - // } - Gate => { - params.push(coll.get_i32_default("Align", 0) as f32); - params.push(coll.get_f32_default("Height", 1.0)); - } - _ => {} - } - } - - params - } - pub fn build( &self, palette: &ThePalette, @@ -535,30 +501,6 @@ impl GeoFXNode { } } } - /* - /// Generates the source code of the face. - pub fn build(&self) -> Option { - if let Some(coll) = self - .timeline - .get_collection_at(&TheTime::default(), str!("Geo")) - { - match self.role { - MiddleWallH => Some(format!( - r#" - let pattern = Pattern; - let box = Shape; - let face = Face : length = {length}, height = {height}, thickness = {thickness}, content = box; - "#, - length = coll.get_f32_default("Length", 1.0), - height = coll.get_f32_default("Height", 1.0), - thickness = coll.get_f32_default("Thickness", 0.2), - )), - _ => None, - } - } else { - None - } - }*/ /// The 2D distance from the node to a point. pub fn distance( @@ -811,11 +753,6 @@ impl GeoFXNode { // return min(max(w.x,w.y),0.0) + length(max(w,0.0)); // } - fn op_extrusion_y(p: Vec3f, d: f32, h: f32) -> f32 { - let w = Vec2f::new(d, abs(p.y) - h); - min(max(w.x, w.y), 0.0) + length(max(w, Vec2f::zero())) - } - match self.role { LeftWall => { let thick = params[2] / 2.0; diff --git a/shared/src/geofxobject.rs b/shared/src/geofxobject.rs index 35ebe5af..3fcb3bfe 100644 --- a/shared/src/geofxobject.rs +++ b/shared/src/geofxobject.rs @@ -66,16 +66,6 @@ impl GeoFXObject { } } - /// Loads the parameters of the nodes into memory for faster access. - pub fn load_parameters(&self, time: &TheTime) -> Vec> { - let mut data = vec![]; - - for n in &self.nodes { - data.push(n.load_parameters(time)); - } - data - } - /// Generates the source code of the face. pub fn build(&self, palette: &ThePalette, textures: &FxHashMap) -> String { let mut ctx = FTBuilderContext { @@ -87,7 +77,7 @@ impl GeoFXObject { self.build_trail(0, palette, textures, &mut ctx); - println!("{}", ctx.out); + //println!("{}", ctx.out); ctx.out } @@ -100,7 +90,7 @@ impl GeoFXObject { textures: &FxHashMap, ctx: &mut FTBuilderContext, ) { - println!("build_trail: {:?}", self.nodes[node].role); + //println!("build_trail: {:?}", self.nodes[node].role); // Check for the material of a shape if self.nodes[node].is_shape() { diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 7fb77f38..01a6635e 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -82,10 +82,10 @@ pub mod prelude { pub use crate::{do_intersect, Hit, HitFace, HitMode, Ray, RenderTile, AABB2D}; pub use forgedtiles::prelude::*; pub use indexmap::IndexMap; - // pub use rand::prelude::*; } -use bsdf::BSDFMaterial; +pub use forgedtiles::prelude::BSDFMaterial; + use geofxnode::{GeoFXNodeExtrusion, GeoFXNodeFacing}; use theframework::prelude::*; diff --git a/shared/src/materialfxobject.rs b/shared/src/materialfxobject.rs index 828929c7..90aaa6c5 100644 --- a/shared/src/materialfxobject.rs +++ b/shared/src/materialfxobject.rs @@ -103,323 +103,6 @@ impl MaterialFXObject { d } - pub fn test_height_profile( - &self, - hit: &mut Hit, - geo_obj: &GeoFXObject, - mat_obj_params: &[Vec], - ) -> bool { - /* - if !mat_obj_params.is_empty() - && mat_obj_params[0][2] as i32 == 1 - && geo_obj.nodes[0].role == GeoFXNodeRole::Gate - { - fn half_circle_profile(x: f32, min_height: f32, max_height: f32) -> f32 { - min_height - + (max_height - min_height) * (1.0 + (x * std::f32::consts::PI).cos()) / 2.0 - } - - let height = hit.extrusion_length; - let step_size = mat_obj_params[0][3]; - - let min_height = height - 0.3; - let max_height = height; - - let x = if step_size > 0.0 { - (((hit.uv.x / step_size).floor()) * step_size) * 2.0 - 1.0 - } else { - hit.uv.x * 2.0 - 1.0 - }; - let h = half_circle_profile(x, min_height, max_height); - - if 1.0 - hit.uv.y > h { - return false; - } - }*/ - - true - } - - /// Get the distance for the given position from the geometry & material objects. - #[allow(clippy::too_many_arguments)] - pub fn get_distance_3d( - &self, - time: &TheTime, - p: Vec3f, - hit: &mut Hit, - palette: &ThePalette, - textures: &FxHashMap, - geo_obj: &GeoFXObject, - geo_obj_params: &[Vec], - mat_obj_params: &[Vec], - ) -> (f32, usize) { - hit.noise = None; - hit.noise_scale = 1.0; - - if let Some(noise_index) = self.find_connected_output_node(0, 0) { - if self.nodes[noise_index].role == MaterialFXNodeRole::Noise2D - || self.nodes[noise_index].role == MaterialFXNodeRole::Noise3D - { - _ = self.nodes[noise_index].compute( - hit, - &ThePalette::default(), - &FxHashMap::default(), - vec![], - &mat_obj_params[noise_index], - ); - } - } - - let noise_buffer = hit.noise; - let noise_buffer_scale = hit.noise_scale; - - let mut d = geo_obj.distance_3d(time, p, &mut Some(hit), geo_obj_params); - // let has_geo_trail = self.follow_geo_trail(time, hit, mat_obj_params); - - let geo_noise = hit.noise; - let geo_noise_scale = hit.noise_scale; - - // hit.noise = None; - // hit.noise_scale = 1.0; - - hit.noise = noise_buffer; - hit.noise_scale = noise_buffer_scale; - - if self.has_bump() { - hit.mode = HitMode::Bump; - self.follow_trail(0, 0, hit, palette, textures, mat_obj_params); - //d.0 -= hit.bump; - } - - d.0 = self.extrude_material(hit, mat_obj_params, false); - - hit.noise = geo_noise; - hit.noise_scale = geo_noise_scale; - - d - } - - /// Get the distance for the given position from the heightmap & material objects. - pub fn get_heightmap_distance_3d( - &self, - time: &TheTime, - p: Vec3f, - hit: &mut Hit, - mat_obj_params: &[Vec], - ) -> f32 { - hit.noise = None; - hit.noise_scale = 1.0; - - if let Some(noise_index) = self.find_connected_output_node(0, 0) { - if self.nodes[noise_index].role == MaterialFXNodeRole::Noise2D - || self.nodes[noise_index].role == MaterialFXNodeRole::Noise3D - { - _ = self.nodes[noise_index].compute( - hit, - &ThePalette::default(), - &FxHashMap::default(), - vec![], - &mat_obj_params[noise_index], - ); - } - } - - let noise_buffer = hit.noise; - let noise_buffer_scale = hit.noise_scale; - - hit.pattern_pos = vec2f(p.x, p.z); - hit.extrusion = GeoFXNodeExtrusion::Y; - hit.extrusion_length = 0.0; - hit.interior_distance = -0.1; - hit.hit_point = p; - - let has_geo_trail = self.follow_geo_trail(time, hit, mat_obj_params); - - let geo_noise = hit.noise; - let geo_noise_scale = hit.noise_scale; - - // hit.noise = None; - // hit.noise_scale = 1.0; - - hit.noise = noise_buffer; - hit.noise_scale = noise_buffer_scale; - - let mut d = self.extrude_material(hit, mat_obj_params, false); - - hit.noise = geo_noise; - hit.noise_scale = geo_noise_scale; - - if has_geo_trail { - let bump = hit.value; - d -= bump / 30.0; - } - - d - } - - /// Extrude the geometry from the hit. - pub fn extrude_material( - &self, - hit: &mut Hit, - mat_obj_params: &[Vec], - has_geo_trail: bool, - ) -> f32 { - let mut d = 0.0; - - // Set extrusion parameters to zero - let mut extrude_add_tile_only = 0.0; - let mut extrude_add = 0.0; - let mut extrude_rounding = 0.0; - let mut extrude_mortar = false; - let mut extrude_mortar_sub = 0.0; - let mut extrude_hash_weight = 0.0; - - if has_geo_trail && !mat_obj_params.is_empty() { - // When we have a material fill in the params - extrude_add = mat_obj_params[0][0]; - extrude_rounding = mat_obj_params[0][1]; - extrude_mortar = mat_obj_params[0][4] as i32 == 1; - extrude_mortar_sub = mat_obj_params[0][5]; - extrude_hash_weight = mat_obj_params[0][6]; - } - - if let Some(noise) = hit.noise { - extrude_add += ((noise * 2.) - 1.0) * hit.noise_scale; - } - - if has_geo_trail && hit.interior_distance < PATTERN2D_DISTANCE_BORDER { - extrude_add_tile_only += hit.hash * extrude_hash_weight; - } - - match hit.extrusion { - GeoFXNodeExtrusion::X => { - fn op_extrusion_x(p: Vec3f, d: f32, h: f32) -> f32 { - let w = Vec2f::new(d, abs(p.x) - h); - min(max(w.x, w.y), 0.0) + length(max(w, Vec2f::zero())) - } - - if !mat_obj_params.is_empty() { - d = op_extrusion_x( - hit.hit_point, - hit.interior_distance, - hit.extrusion_length + extrude_add + extrude_add_tile_only - - extrude_rounding - + hit.bump, - ) - extrude_rounding; - - // if extrude_mortar { - // if let Some(mortar) = hit.interior_distance_mortar { - // let mortar_distance = op_extrusion_x( - // hit.hit_point, - // mortar, - // hit.extrusion_length + extrude_add - extrude_mortar_sub, - // ); - // d = min(distance, mortar_distance); - - // if hit.interior_distance <= PATTERN2D_DISTANCE_BORDER { - // hit.value = 0.0; - // } else { - // hit.value = 1.0; - // } - // } - // } else { - // d = distance; - // hit.value = 0.0; - // } - } else { - d = op_extrusion_x(hit.hit_point, hit.interior_distance, hit.extrusion_length); - } - } - GeoFXNodeExtrusion::Y => { - fn op_extrusion_y(p: Vec3f, d: f32, h: f32) -> f32 { - let w = Vec2f::new(d, abs(p.y) - h); - min(max(w.x, w.y), 0.0) + length(max(w, Vec2f::zero())) - } - - if !mat_obj_params.is_empty() { - d = op_extrusion_y( - hit.hit_point, - hit.interior_distance, - hit.extrusion_length + extrude_add + extrude_add_tile_only - - extrude_rounding - + hit.bump, - ) - extrude_rounding; - - // if extrude_mortar { - // if let Some(mortar) = hit.interior_distance_mortar { - // let mortar_distance = op_extrusion_y( - // hit.hit_point, - // mortar, - // hit.extrusion_length + extrude_add - extrude_mortar_sub, - // ); - // d = min(distance, mortar_distance); - // if hit.interior_distance <= PATTERN2D_DISTANCE_BORDER { - // hit.value = 0.0; - // } else { - // hit.value = 1.0; - // } - // } - // } else { - //hit.value = 0.0; - // if hit.interior_distance <= PATTERN2D_DISTANCE_BORDER { - // hit.value = 0.0; - // } else { - // hit.value = 1.0; - // } - } else { - d = op_extrusion_y(hit.hit_point, hit.interior_distance, hit.extrusion_length); - } - } - GeoFXNodeExtrusion::Z => { - fn op_extrusion_z(p: Vec3f, d: f32, h: f32) -> f32 { - let w = Vec2f::new(d, abs(p.z) - h); - min(max(w.x, w.y), 0.0) + length(max(w, Vec2f::zero())) - } - - if !mat_obj_params.is_empty() { - d = op_extrusion_z( - hit.hit_point, - hit.interior_distance, - hit.extrusion_length + extrude_add + extrude_add_tile_only - - extrude_rounding - + hit.bump, - ) - extrude_rounding; - - if hit.interior_distance <= PATTERN2D_DISTANCE_BORDER { - hit.value = 0.0; - } else { - hit.value = 1.0; - } - // if extrude_mortar { - // if let Some(mortar) = hit.interior_distance_mortar { - // let mortar_distance = op_extrusion_z( - // hit.hit_point, - // mortar, - // hit.extrusion_length + extrude_add - extrude_mortar_sub, - // ); - // d = min(distance, mortar_distance); - - // if hit.interior_distance <= PATTERN2D_DISTANCE_BORDER { - // hit.value = 0.0; - // } else { - // hit.value = 1.0; - // } - // } - // } else { - // d = distance; - // hit.value = 0.0; - // } - } else { - d = op_extrusion_z(hit.hit_point, hit.interior_distance, hit.extrusion_length); - } - } - - _ => {} - } - - d - } - /// Compute the materials geometry extrusion. pub fn follow_geo_trail( &self, @@ -442,106 +125,6 @@ impl MaterialFXObject { false } - /// Calculate normal - #[allow(clippy::too_many_arguments)] - pub fn normal( - &self, - time: &TheTime, - p: Vec3f, - hit: &mut Hit, - palette: &ThePalette, - textures: &FxHashMap, - geo_obj: &GeoFXObject, - geo_obj_params: &[Vec], - mat_obj_params: &[Vec], - ) -> Vec3f { - let scale = 0.5773 * 0.0005; - let e = vec2f(1.0 * scale, -1.0 * scale); - - // IQs normal function - - let e1 = vec3f(e.x, e.y, e.y); - let e2 = vec3f(e.y, e.y, e.x); - let e3 = vec3f(e.y, e.x, e.y); - let e4 = vec3f(e.x, e.x, e.x); - - let n = e1 - * self - .get_distance_3d( - time, - p + e1, - hit, - palette, - textures, - geo_obj, - geo_obj_params, - mat_obj_params, - ) - .0 - + e2 * self - .get_distance_3d( - time, - p + e2, - hit, - palette, - textures, - geo_obj, - geo_obj_params, - mat_obj_params, - ) - .0 - + e3 * self - .get_distance_3d( - time, - p + e3, - hit, - palette, - textures, - geo_obj, - geo_obj_params, - mat_obj_params, - ) - .0 - + e4 * self - .get_distance_3d( - time, - p + e4, - hit, - palette, - textures, - geo_obj, - geo_obj_params, - mat_obj_params, - ) - .0; - normalize(n) - } - - /// Calculate normal - pub fn heightmap_normal( - &self, - time: &TheTime, - p: Vec3f, - hit: &mut Hit, - mat_obj_params: &[Vec], - ) -> Vec3f { - let scale = 0.5773 * 0.0005; - let e = vec2f(1.0 * scale, -1.0 * scale); - - // IQs normal function - - let e1 = vec3f(e.x, e.y, e.y); - let e2 = vec3f(e.y, e.y, e.x); - let e3 = vec3f(e.y, e.x, e.y); - let e4 = vec3f(e.x, e.x, e.x); - - let n = e1 * self.get_heightmap_distance_3d(time, p + e1, hit, mat_obj_params) - + e2 * self.get_heightmap_distance_3d(time, p + e2, hit, mat_obj_params) - + e3 * self.get_heightmap_distance_3d(time, p + e3, hit, mat_obj_params) - + e4 * self.get_heightmap_distance_3d(time, p + e4, hit, mat_obj_params); - normalize(n) - } - /// Returns the connected input node and terminal for the given output node and terminal. pub fn find_connected_input_node( &self, diff --git a/shared/src/renderer.rs b/shared/src/renderer.rs index aaf154fb..b375ca3d 100644 --- a/shared/src/renderer.rs +++ b/shared/src/renderer.rs @@ -111,13 +111,6 @@ impl Renderer { material_params.insert(*id, params); } - // Collect the geo_object params - let mut geo_params: FxHashMap>> = FxHashMap::default(); - for (id, geo_obj) in ®ion.geometry { - let params = geo_obj.load_parameters(&settings.time); - geo_params.insert(*id, params); - } - // Collect the render settings params let render_settings_params: Vec> = region.regionfx.load_parameters(&settings.time); @@ -206,7 +199,6 @@ impl Renderer { max_render_distance, palette, &material_params, - &geo_params, &mut rng, ) { if depth == 0 { @@ -295,7 +287,6 @@ impl Renderer { settings, palette, &material_params, - &geo_params, ) { scatter_sample.f = disney_eval( &state, @@ -425,7 +416,6 @@ impl Renderer { max_render_distance: i32, palette: &ThePalette, material_params: &FxHashMap>>, - geo_params: &FxHashMap>>, _rng: &mut ThreadRng, ) -> Option { let mut hit = Hit::default(); @@ -439,7 +429,7 @@ impl Renderer { ) } - let mut has_hit = false; + let mut has_hit; let dist = 0.0; if let Some(terrain_dist) = region.heightmap.compute_hit( @@ -650,7 +640,7 @@ impl Renderer { let mut t = 0.0; - for _ in 0..50 { + for _ in 0..30 { // Max distance a ray can travel in a unit cube // if t > 1.732 { // break; @@ -667,48 +657,6 @@ impl Renderer { // The start position of the object / face. let pos = geo_obj.get_position(); let ft_hit = ftctx.distance_to_face(p, 0, pos); - /* - let d; // = (f32::INFINITY, 0); - if let Some(material) = material { - if material.has_bump() { - let normal = material.normal( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - - let f = self.get_uv_face(normal, p); - h.uv = f.0; - h.global_uv = vec2f(p.x.floor(), p.z.floor()) + h.uv; - h.pattern_pos = h.global_uv; - } - d = material.get_distance_3d( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - } else { - d = MaterialFXObject::default().get_distance_3d( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - }*/ if ft_hit.distance < 0.001 && t < hit.distance { h.hit_point = p; @@ -716,57 +664,9 @@ impl Renderer { hit.clone_from(&h); hit.normal = ftctx.face_normal(p, 0, pos); - /* - if let Some(material) = material { - hit.normal = material.normal( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - } else { - hit.normal = MaterialFXObject::default().normal( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - }*/ - hit.distance = dist + t; - hit.mat.base_color = vec3f(0.5, 0.5, 0.5); - if let Some(index) = ft_hit.node { - if let Some(material) = ftctx.nodes[index].material { - let c = ftctx.nodes[material as usize] - .values - .get(FTValueRole::Color, vec![0.5, 0.5, 0.5]); - - hit.mat.base_color[0] = - c[0] + ((ft_hit.pattern_hash) - 0.5) * 0.5; - hit.mat.base_color[1] = - c[1] + ((ft_hit.pattern_hash) - 0.5) * 0.5; - hit.mat.base_color[2] = - c[2] + ((ft_hit.pattern_hash) - 0.5) * 0.5; - } - } - // if h.extrusion == GeoFXNodeExtrusion::None { - // hit.value = 1.0; - // geo_obj.nodes[d.1].distance_3d( - // &settings.time, - // p, - // &mut Some(&mut hit), - // &geo_obj_params[d.1], - // ); - // } + hit.mat = BSDFMaterial::from_hit(ftctx, &ft_hit); if let Some(material) = material { let f = self.get_uv_face(hit.normal, hit.hit_point); @@ -796,609 +696,6 @@ impl Renderer { return None; } - if false { - if let Some(terrain_dist) = region.heightmap.raymarch(&ray) { - let mut terrain_hit = ray.at(terrain_dist); - let tile_id = vec2i(terrain_hit.x.floor() as i32, terrain_hit.z.floor() as i32); - let key = Vec3i::new(tile_id.x, terrain_hit.y as i32, tile_id.y); - - let terrain_normal = - region - .heightmap - .calculate_normal(terrain_hit.x, terrain_hit.z, 0.001); - hit.normal = terrain_normal; - hit.hit_point = terrain_hit; - - let mut geo_ids: Vec = vec![]; - { - let ro = ray.o; - let rd = ray.d; - - let mut i = floor(ro); - let mut dist = 0.0; - - let mut normal = vec3f(0.0, 0.0, 0.0); - let srd = signum(rd); - - let rdi = 1.0 / (2.0 * rd); - - let mut key: Vec3; - - for _ii in 0..max_render_distance { - key = Vec3i::from(i); - - if key.y < -1 { - break; - } - - if dist > hit.distance { - break; - } - - // Collect the hit geo ids which we will process later. - if let Some(ids) = region.geometry_areas.get(&vec3i(key.x, 0, key.z)) { - for id in ids { - if !geo_ids.contains(id) { - geo_ids.push(*id); - } - } - } - - // Raymarch (extruded) materials to see if they intersect. - if let Some(mask) = region.heightmap.get_material_mask(key.x, key.z) { - //has_heightmap_material = true; - let mut h = Hit::default(); //hit.clone(); - - let mut t = dist; - for _ in 0..20 { - // Max distance a ray can travel in a unit cube - if t - dist > 1.732 { - break; - } - - let mut p = ray.at(t); - let t_dist = region.heightmap.interpolate_height(p.x, p.z); - p.y -= t_dist; - - if let Some(material_mask) = - mask.at_f(vec2f(p.x.fract(), p.z.fract())) - { - let index = (material_mask[0] - 1) as usize; - if let Some((_id, material)) = self.materials.get_index(index) { - let mut mat_obj_params: Vec> = vec![]; - - if let Some(m_params) = material_params.get(&material.id) { - mat_obj_params.clone_from(m_params); - } - - h.global_uv = vec2f(p.x, p.z); - h.pattern_pos = h.global_uv; - - // let dist = material.get_heightmap_distance_3d( - // &settings.time, - // p, - // &mut h, - // &mat_obj_params, - // ); - //if material.has_bump() { - let dist = p.y - + material.get_material_distance( - 0, - &mut h, - palette, - &self.textures, - &mat_obj_params, - ); - - if dist < h.eps && dist < h.distance && dist <= terrain_dist - { - h.hit_point = p; - h.distance = t; - //h.global_uv = vec2f(p.x.floor(), p.z.floor()) + h.uv; - // h.pattern_pos = hit.global_uv; - hit.clone_from(&h); - - hit.normal = material.get_material_normal( - 0, - p, - &mut h, - palette, - &self.textures, - &mat_obj_params, - ); - - hit.normal = terrain_normal; - - let f = self.get_uv_face(hit.normal, hit.hit_point); - hit.uv = f.0; - - // hit.global_uv = match f.1 { - // 0 => f.0 + vec2f(p.z, p.y), - // 1 => f.0 + vec2f(p.x, p.z), - // _ => f.0 + vec2f(p.x, p.y), - // }; - //hit.pattern_pos = hit.global_uv; - //h.clone_from(&hit); - material.compute( - &mut hit, - palette, - &self.textures, - &mat_obj_params, - ); - - // Overlay material - let index = (material_mask[1] - 1) as usize; - if let Some((_id, material)) = - self.materials.get_index(index) - { - hit.value = 1.0; - - let mut mat_obj_params: Vec> = vec![]; - - if let Some(m_params) = - material_params.get(&material.id) - { - mat_obj_params.clone_from(m_params); - } - - material.compute( - &mut hit, - palette, - &self.textures, - &mat_obj_params, - ); - } - - has_hit = true; - break; - } - - t += dist; - //} - } - } - } - } - - if let Some(tile) = self.tiles.get((key.x, key.y, key.z)) { - if dist > hit.distance { - continue; - } - - //let mut uv = vec2f(terrain_hit.x.fract(), terrain_hit.z.fract()); - let mut uv = self.get_uv_face(normal, ray.at(dist)).0; - //pixel = [(uv.x * 255.0) as u8, (uv.y * 255.0) as u8, 0, 255]; - if let Some(data) = self.textures.get(tile) { - let index = settings.anim_counter % data.buffer.len(); - - // TODO apply alpha correctly for WallFX blends - let mut alpha: f32 = 1.0; - - //if key.y == 0 { - if let Some(wallfx) = update.wallfx.get(&(tile_id.x, tile_id.y)) { - let mut valid = true; - let mut xx = 0; - let mut yy = 0; - let d = (update.server_tick - wallfx.at_tick) as f32 - + settings.delta_in_tick - - 1.0; - if d < 1.0 { - let t = (d * region.grid_size as f32) as i32; - if wallfx.prev_fx != WallFX::Normal { - wallfx.prev_fx.apply( - &mut xx, - &mut yy, - &mut alpha, - &(region.grid_size - t), - &(1.0 - d), - ); - } else { - wallfx.fx.apply(&mut xx, &mut yy, &mut alpha, &t, &d); - } - } else if wallfx.fx != WallFX::Normal { - valid = false; - } - - if valid { - uv.x += xx as f32 / region.grid_size as f32; - uv.y += yy as f32 / region.grid_size as f32; - } else { - uv = vec2f(-1.0, -1.0); - } - } - //} - - if !data.billboard { - if let Some(p) = data.buffer[index].at_f_vec4f(uv) { - hit.mat.base_color = vec3f(p.x, p.y, p.z); - hit.normal = -hit.normal; - hit.distance = dist; - hit.hit_point = ray.at(dist); - has_hit = true; - } - } else { - let xx = i.x + 0.5; - let zz = i.z + 0.5; - - let plane_pos = vec3f(xx, 0.5, zz); - - let mut plane_normal = normalize(plane_pos - ray.o); - plane_normal.y = 0.0; - let denom = dot(plane_normal, ray.d); - - if denom > 0.0001 { - let t = dot(plane_pos - ray.o, plane_normal) / denom; - if t >= 0.0 { - let hit_pos = ray.at(t); - if (xx - hit_pos.x).abs() <= 0.5 - && (zz - hit_pos.z).abs() <= 0.5 - && hit_pos.y >= 0.0 - && hit_pos.y <= 1.0 - { - #[inline(always)] - fn compute_primary(normal: Vec3f) -> Vec3f { - let a = cross(normal, vec3f(1.0, 0.0, 0.0)); - let b = cross(normal, vec3f(0.0, 1.0, 0.0)); - - let max_ab = - if dot(a, a) < dot(b, b) { b } else { a }; - - let c = cross(normal, vec3f(0.0, 0.0, 1.0)); - - normalize(if dot(max_ab, max_ab) < dot(c, c) { - c - } else { - max_ab - }) - } - let index = - settings.anim_counter % data.buffer.len(); - - let plane_vector_u = compute_primary(plane_normal); - let plane_vector_v = cross(plane_vector_u, ray.d); - - let relative = hit_pos - plane_pos; - let u_dot = dot(relative, plane_vector_u); - let v_dot = dot(relative, plane_vector_v); - - let u = 0.5 + u_dot; - let v = 0.5 + v_dot; - - //println!("{}, {}", u, v); - - let x = (u * data.buffer[index].dim().width as f32) - as i32; - let y = ((1.0 - v) - * data.buffer[index].dim().height as f32) - as i32; - if let Some(c) = data.buffer[index].at(vec2i(x, y)) - { - if c[3] == 255 { - let col = - TheColor::from_u8_array(c).to_vec4f(); - hit.mat.base_color = - vec3f(col.x, col.y, col.z); - hit.distance = t; - hit.normal = -hit.normal; - hit.hit_point = ray.at(t); - has_hit = true; - } - } - } - } - } - } - } - } - - // if has_hit { - // break; - // } - - let plain = (1.0 + srd - 2.0 * (ro - i)) * rdi; - dist = min(plain.x, min(plain.y, plain.z)); - normal = equal(dist, plain) * srd; - i += normal; - } - } - - hit.key = Vec3f::from(key); - for geo_id in geo_ids { - let mut h = Hit::default(); - if let Some(geo_obj) = region.geometry.get(&geo_id) { - if let Some(geo_obj_params) = geo_params.get(&geo_obj.id) { - let material = self.materials.get(&geo_obj.material_id); - let mut mat_obj_params: Vec> = vec![]; - - if let Some(m_params) = material_params.get(&geo_obj.material_id) { - mat_obj_params.clone_from(m_params); - } - - let mut t = 0.0; - - for _ in 0..20 { - // Max distance a ray can travel in a unit cube - // if t > 1.732 { - // break; - // } - - let mut p = ray.at(t); - let t_dist = region.heightmap.interpolate_height(p.x, p.z); - p.y -= t_dist; - - let d; // = (f32::INFINITY, 0); - if let Some(material) = material { - if material.has_bump() { - let normal = material.normal( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - - let f = self.get_uv_face(normal, p); - h.uv = f.0; - h.global_uv = vec2f(p.x.floor(), p.z.floor()) + h.uv; - h.pattern_pos = h.global_uv; - } - d = material.get_distance_3d( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - } else { - d = MaterialFXObject::default().get_distance_3d( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - } - - if d.0 < h.eps && t < hit.distance { - h.hit_point = p; - - hit.clone_from(&h); - if let Some(material) = material { - hit.normal = material.normal( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - } else { - hit.normal = MaterialFXObject::default().normal( - &settings.time, - p, - &mut h, - palette, - &self.textures, - geo_obj, - geo_obj_params, - &mat_obj_params, - ); - } - - hit.distance = dist + t; - hit.mat.base_color = vec3f(0.5, 0.5, 0.5); - - // if h.extrusion == GeoFXNodeExtrusion::None { - // hit.value = 1.0; - // geo_obj.nodes[d.1].distance_3d( - // &settings.time, - // p, - // &mut Some(&mut hit), - // &geo_obj_params[d.1], - // ); - // } - - if let Some(material) = material { - let f = self.get_uv_face(hit.normal, hit.hit_point); - hit.uv = f.0; - hit.global_uv = vec2f(p.x.floor(), p.z.floor()) + hit.uv; - //match f.1 { - //0 => f.0 + vec2f(hit.hit_point.z, hit.hit_point.y), - //1 => f.0 + vec2f(hit.hit_point.x, hit.hit_point.z), - //_ => f.0 + vec2f(hit.hit_point.x, hit.hit_point.y), - //}; - material.compute( - &mut hit, - palette, - &self.textures, - &mat_obj_params, - ); - } - - has_hit = true; - } - t += d.0; - } - } - } - } - - // If no hit, we draw the material at index #0 - // if !has_hit && has_heightmap_material { - // hit.hit_point = terrain_hit; - // hit.normal = terrain_normal; - // hit.distance = terrain_dist; - - // if let Some((id, material)) = self.materials.get_index(0) { - // let mut mat_obj_params: Vec> = vec![]; - - // if let Some(m_params) = material_params.get(id) { - // mat_obj_params.clone_from(m_params); - // } - - // let f = self.get_uv_face(hit.normal, hit.hit_point); - // hit.uv = f.0; - // hit.global_uv = vec2f(terrain_hit.x.floor(), terrain_hit.z.floor()) + hit.uv; - // hit.pattern_pos = hit.global_uv; - // hit.two_d = true; - // material.compute(&mut hit, palette, &self.textures, &mat_obj_params); - - // has_hit = true; - // } - // } - // If no hit, we render the heightmap with its painted materials. - // ! has_hit { - // - // Not in use - /* - if let Some(mask) = region.heightmap.get_material_mask(tile_id.x, tile_id.y) { - let terrain_uv = vec2f(terrain_hit.x.fract(), terrain_hit.z.fract()); - - if let Some(material_mask) = mask.at_f(terrain_uv) { - let index = (material_mask[0] - 1) as usize; - if let Some((_id, material)) = self.materials.get_index(index) { - let mut mat_obj_params: Vec> = vec![]; - - if let Some(m_params) = material_params.get(&material.id) { - mat_obj_params.clone_from(m_params); - } - - hit.hit_point = terrain_hit; - hit.normal = terrain_normal; - - if material.has_geometry_trail() { - let d = material.get_heightmap_distance_3d( - &settings.time, - vec3f(terrain_hit.x, 0.0, terrain_hit.z), //terrain_hit, - &mut hit, - &mat_obj_params, - ); - - let t = terrain_dist + d - 20.8; - hit.hit_point = ray.at(t); - hit.distance = t; - terrain_hit = hit.hit_point; - - hit.normal = material.heightmap_normal( - &settings.time, - ray.at(d), - &mut hit, - &mat_obj_params, - ); - } - - //if !material.has_geometry_trail() { - - let f = self.get_uv_face(hit.normal, hit.hit_point); - hit.uv = f.0; - hit.global_uv = match f.1 { - 0 => f.0 + vec2f(terrain_hit.z, terrain_hit.y), - 1 => f.0 + vec2f(terrain_hit.x, terrain_hit.z), - _ => f.0 + vec2f(terrain_hit.x, terrain_hit.y), - }; - hit.pattern_pos = hit.global_uv; - material.compute(&mut hit, palette, &self.textures, &mat_obj_params); - - has_hit = true; - //} - /*else { - //let mut h = hit.clone(); - let mut t = 0.001; - let mut h = Hit::default(); - - for _ in 0..40 { - let mut p = ray.at(t); - p.y -= region.heightmap.interpolate_height(p.x, p.z); - - let d = material.get_heightmap_distance_3d( - &settings.time, - p, - &mut h, - ®ion.heightmap, - &mat_obj_params, - ); - - if d < h.eps { - hit.clone_from(&h); - - hit.hit_point = p; - - let mut h = hit.clone(); - hit.normal = material.heightmap_normal( - &settings.time, - p, - &mut h, - ®ion.heightmap, - &mat_obj_params, - ); - - hit.distance = t; - hit.mat.base_color = vec3f(0.5, 0.5, 0.5); - - let f = self.get_uv_face(hit.normal, hit.hit_point); - hit.uv = f.0; - hit.global_uv = match f.1 { - 0 => f.0 + vec2f(p.z, p.y), - 1 => f.0 + vec2f(p.x, p.z), - _ => f.0 + vec2f(p.x, p.y), - }; - material.compute( - &mut hit, - palette, - &self.textures, - &mat_obj_params, - ); - - has_hit = true; - break; - } - t += d; - } - }*/ - } - - // Overlay the 2nd material - /* - if has_hit { - let index = (material_mask[1] - 1) as usize; - if let Some((_id, material)) = self.materials.get_index(index) { - let mut mat_obj_params: Vec> = vec![]; - - if let Some(m_params) = material_params.get(&material.id) { - mat_obj_params.clone_from(m_params); - } - - //let mut h = hit.clone(); - material.compute( - &mut hit, - palette, - &self.textures, - &mat_obj_params, - ); - } - }*/ - } - }*/ - } - - //println!("{}", hit.normal); - } - // else { - // hit.mat.base_color = vec3f(1.0, 1.0, 1.0); - // return Some(hit); - // } - if has_hit { Some(hit) } else { @@ -1774,13 +1071,6 @@ impl Renderer { // Collect the render settings params let render_settings_params: Vec> = region.regionfx.load_parameters(&settings.time); - // Collect the geo_object params - let mut geo_params: FxHashMap>> = FxHashMap::default(); - for (id, geo_obj) in ®ion.geometry { - let params = geo_obj.load_parameters(&settings.time); - geo_params.insert(*id, params); - } - pixels .par_rchunks_exact_mut(width * 4) .enumerate() @@ -1814,7 +1104,6 @@ impl Renderer { max_render_distance, palette, &material_params, - &geo_params, )); } }); @@ -1835,9 +1124,8 @@ impl Renderer { max_render_distance: i32, palette: &ThePalette, material_params: &FxHashMap>>, - geo_params: &FxHashMap>>, ) -> RGBA { - let mut hit = Hit::default(); + //let hit = Hit::default(); let mut color = vec4f(0.0, 0.0, 0.0, 1.0); let hit_props = Hit::default(); @@ -1879,6 +1167,7 @@ impl Renderer { break; } + /* if let Some(geo_ids) = region.geometry_areas.get(&key) { hit.key = Vec3f::from(key); for geo_id in geo_ids { @@ -2001,7 +1290,8 @@ impl Renderer { } } } - } + }*/ + // Test against world tiles if let Some(tile) = self.tiles.get((key.x, key.y, key.z)) { let mut uv = self.get_uv_face(normal, ray.at(dist)).0; @@ -2272,7 +1562,6 @@ impl Renderer { settings, palette, material_params, - geo_params, ) { let c = if settings.pbr { let mut light_color = Vec3f::from(1.5 * light_strength); @@ -2365,12 +1654,11 @@ impl Renderer { ray: Ray, light_pos: Vec3i, light: &Light, - region: &Region, + _region: &Region, _update: &RegionUpdate, - settings: &RegionDrawSettings, - palette: &ThePalette, - material_params: &FxHashMap>>, - geo_params: &FxHashMap>>, + _settings: &RegionDrawSettings, + _palette: &ThePalette, + _material_params: &FxHashMap>>, ) -> bool { #[inline(always)] fn equal(l: f32, r: Vec3f) -> Vec3f { @@ -2390,7 +1678,7 @@ impl Renderer { return true; } - let mut dist = 0.0; + let mut dist; // = 0.0; let mut normal; let srd = signum(rd); @@ -2423,7 +1711,8 @@ impl Renderer { } } - // Test against geometry + // TODO Test against geometry + /* if let Some(geo_ids) = region.geometry_areas.get(&key) { for geo_id in geo_ids { let mut h = Hit::default(); @@ -2482,7 +1771,7 @@ impl Renderer { } } } - } + }*/ let plain = (1.0 + srd - 2.0 * (ro - i)) * rdi; dist = min(plain.x, min(plain.y, plain.z));