From 96ba5aa2135cb62514002ccab68aff92e45d2cb2 Mon Sep 17 00:00:00 2001 From: Tada Teruki Date: Wed, 28 Aug 2024 20:34:44 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=E3=83=86=E3=82=AF=E3=82=B9=E3=83=81?= =?UTF-8?q?=E3=83=A3=E3=81=AE=E3=82=B9=E3=82=B1=E3=83=BC=E3=83=AA=E3=83=B3?= =?UTF-8?q?=E3=82=B0=20(#586)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nusamai/src/sink/cesiumtiles/mod.rs | 64 +++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/nusamai/src/sink/cesiumtiles/mod.rs b/nusamai/src/sink/cesiumtiles/mod.rs index c733b6d0..eb7579ed 100644 --- a/nusamai/src/sink/cesiumtiles/mod.rs +++ b/nusamai/src/sink/cesiumtiles/mod.rs @@ -46,6 +46,21 @@ use crate::{ }; use utils::calculate_normal; +const MAX_PIXEL_PER_DISTANCE: f64 = 15.0; + +// WARN: This function has an equivalent in `atlas-packer/src/texture.rs`. +fn uv_to_pixel_coords(uv_coords: &[(f64, f64)], width: u32, height: u32) -> Vec<(u32, u32)> { + uv_coords + .iter() + .map(|(u, v)| { + ( + (u.clamp(0.0, 1.0) * width as f64).min(width as f64 - 1.0) as u32, + ((1.0 - v.clamp(0.0, 1.0)) * height as f64).min(height as f64 - 1.0) as u32, + ) + }) + .collect() +} + pub struct CesiumTilesSinkProvider {} impl DataSinkProvider for CesiumTilesSinkProvider { @@ -502,6 +517,7 @@ fn tile_writing_stage( .iter() .map(|[x, y, z, u, v]| (*x, *y, *z, *u, *v)) .collect::>(); + let uv_coords = original_vertices .iter() .map(|(_, _, _, u, v)| (*u, *v)) @@ -509,7 +525,46 @@ fn tile_writing_stage( let texture_uri = base_texture.uri.to_file_path().unwrap(); let texture_size = texture_size_cache.get_or_insert(&texture_uri); - let factor = apply_downsample_factor(tile_zoom); + + let pixel_coords = + uv_to_pixel_coords(&uv_coords, texture_size.0, texture_size.1); + + let pixel_per_distance = (0..original_vertices.len()) + .map(|i| { + let j = (i + 1) % original_vertices.len(); + let (euc0, txl0) = ( + ( + original_vertices[i].0, + original_vertices[i].1, + original_vertices[i].2, + ), + pixel_coords[i], + ); + let (euc1, txl1) = ( + ( + original_vertices[j].0, + original_vertices[j].1, + original_vertices[j].2, + ), + pixel_coords[j], + ); + let euc_dist = ((euc0.0 - euc1.0).powi(2) + + (euc0.1 - euc1.1).powi(2) + + (euc0.2 - euc1.2).powi(2)) + .sqrt(); + let txl_dist = ((txl0.0 as f64 - txl1.0 as f64).powi(2) + + (txl0.1 as f64 - txl1.1 as f64).powi(2)) + .sqrt(); + txl_dist / euc_dist + }) + .min_by(|a, b| a.total_cmp(b)) + .unwrap_or(1.0); + + let max_pixel_per_distance = MAX_PIXEL_PER_DISTANCE; + let downsample_scale = + (1.0_f64).min(max_pixel_per_distance / pixel_per_distance); + let factor = apply_downsample_factor(tile_zoom, downsample_scale as f32); + let downsample_factor = DownsampleFactor::new(&factor); let cropped_texture = CroppedTexture::new( &texture_uri, @@ -675,11 +730,12 @@ fn tile_writing_stage( Ok(()) } -fn apply_downsample_factor(z: u8) -> f32 { - match z { +fn apply_downsample_factor(z: u8, downsample_scale: f32) -> f32 { + let f = match z { 0..=14 => 0.0, 15..=16 => 0.25, 17 => 0.5, _ => 1.0, - } + }; + f * downsample_scale } From 55f67fcdc274b75654b424c4cfb7e874aad51f90 Mon Sep 17 00:00:00 2001 From: nokonoko1203 Date: Thu, 29 Aug 2024 00:46:16 +0900 Subject: [PATCH 2/2] fix MaxPD --- nusamai/src/sink/cesiumtiles/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nusamai/src/sink/cesiumtiles/mod.rs b/nusamai/src/sink/cesiumtiles/mod.rs index eb7579ed..32222509 100644 --- a/nusamai/src/sink/cesiumtiles/mod.rs +++ b/nusamai/src/sink/cesiumtiles/mod.rs @@ -46,7 +46,7 @@ use crate::{ }; use utils::calculate_normal; -const MAX_PIXEL_PER_DISTANCE: f64 = 15.0; +const MAX_PIXEL_PER_DISTANCE: f64 = 30.0; // WARN: This function has an equivalent in `atlas-packer/src/texture.rs`. fn uv_to_pixel_coords(uv_coords: &[(f64, f64)], width: u32, height: u32) -> Vec<(u32, u32)> {