From 81eaaae3981559a50e77777f689129dac5cb1ba4 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Tue, 19 Nov 2019 16:20:20 +0300 Subject: [PATCH 1/8] Reimplement #210 --- assets/voxygen/shaders/terrain-frag.glsl | 2 +- voxygen/src/mesh/terrain.rs | 10 +++++++++- voxygen/src/render/pipelines/terrain.rs | 14 +++----------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/voxygen/shaders/terrain-frag.glsl b/assets/voxygen/shaders/terrain-frag.glsl index 0fb2811441..b148b6da4f 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -27,7 +27,7 @@ void main() { // Increase array access by 3 to access positive values uint norm_dir = ((f_pos_norm >> 29) & 0x1u) * 3u; // Use an array to avoid conditional branching - vec3 f_norm = normals[norm_axis + norm_dir]; + vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u]; vec3 light, diffuse_light, ambient_light; get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0); diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index fc557a5ffd..5154c20617 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -236,7 +236,15 @@ impl + ReadVol + Debug> Meshable, norm: Vec3, col: Rgb, light: f32) -> Self { - let (norm_axis, norm_dir) = norm - .as_slice() - .into_iter() - .enumerate() - .find(|(_i, e)| **e != 0.0) - .unwrap_or((0, &1.0)); - let norm_bits = (norm_axis << 1) | if *norm_dir > 0.0 { 1 } else { 0 }; - + pub fn new(norm_bits: u32, light: u32, pos: Vec3, col: Rgb) -> Self { Self { pos_norm: 0 | ((pos.x as u32) & 0x00FF) << 0 | ((pos.y as u32) & 0x00FF) << 8 | ((pos.z.max(0.0).min((1 << 13) as f32) as u32) & 0x1FFF) << 16 - | ((norm_bits as u32) & 0x7) << 29, + | (norm_bits & 0x7) << 29, col_light: 0 | ((col.r.mul(255.0) as u32) & 0xFF) << 8 | ((col.g.mul(255.0) as u32) & 0xFF) << 16 | ((col.b.mul(255.0) as u32) & 0xFF) << 24 - | ((light.mul(255.0) as u32) & 0xFF) << 0, + | (light & 0xFF) << 0, } } } From cb1b6c4c292ed391ff4abdc3390301eff4f218b4 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Tue, 19 Nov 2019 18:13:33 +0300 Subject: [PATCH 2/8] Improve frustum culling by using AABBs, add related debug information --- Cargo.lock | 34 ++++++++++++++++++++++-- voxygen/Cargo.toml | 2 +- voxygen/src/hud/mod.rs | 31 +++++++++++++++++++++- voxygen/src/scene/camera.rs | 5 +--- voxygen/src/scene/figure/mod.rs | 24 ++++++++++++++--- voxygen/src/scene/mod.rs | 12 ++++++++- voxygen/src/scene/terrain.rs | 46 +++++++++++++++++---------------- voxygen/src/session.rs | 4 +++ 8 files changed, 123 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 47f8ff68bd..e89e538426 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -864,6 +864,15 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dirs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dirs-sys" version = "0.3.4" @@ -1055,7 +1064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "frustum_query" version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/yusdacra/frustum_query#866b36607a3a80356f0fc7a1cb29c2c59a70fdab" [[package]] name = "fsevent" @@ -2974,6 +2983,16 @@ name = "shrev" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "simplelog" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "siphasher" version = "0.2.3" @@ -3226,6 +3245,15 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "term" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termcolor" version = "1.0.5" @@ -3929,6 +3957,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum derivative 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "942ca430eef7a3806595a6737bc388bf51adb888d3fc0dd1b50f1c170167ee3a" "checksum directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" "checksum discord-rpc-sdk 0.1.1 (git+https://github.com/Songtronix/rust-discord-rpc.git)" = "" "checksum discord-rpc-sys 0.1.0 (git+https://github.com/Songtronix/rust-discord-rpc.git)" = "" @@ -3952,7 +3981,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum frustum_query 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e1771c26abed26b2527d888742fffd27dab86d205bf4846748abf29c06ef5a05" +"checksum frustum_query 0.1.2 (git+https://github.com/yusdacra/frustum_query)" = "" "checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" "checksum fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" @@ -4192,6 +4221,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" +"checksum term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index e432239808..acc9183562 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -55,7 +55,7 @@ directories = "2.0.2" num = "0.2.0" backtrace = "0.3.40" rand = "0.7.2" -frustum_query = "0.1.2" +frustum_query = { git = "https://github.com/yusdacra/frustum_query" } # context for pinning to commit: https://gitlab.com/veloren/veloren/issues/280 rodio = { git = "https://github.com/RustAudio/rodio", rev = "e5474a2"} cpal = "0.10" diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index b718dc912d..48d60c6bd5 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -119,6 +119,8 @@ widget_ids! { loaded_distance, time, entity_count, + num_chunks, + num_figures, // Game Version version, @@ -172,6 +174,10 @@ pub struct DebugInfo { pub ping_ms: f64, pub coordinates: Option, pub velocity: Option, + pub num_chunks: u32, + pub num_visible_chunks: u32, + pub num_figures: u32, + pub num_figures_visible: u32, } pub enum Event { @@ -979,6 +985,7 @@ impl Hud { .font_id(self.fonts.cyri) .font_size(14) .set(self.ids.time, ui_widgets); + // Number of entities let entity_count = client.state().ecs().entities().join().count(); Text::new(&format!("Entity count: {}", entity_count)) @@ -987,11 +994,33 @@ impl Hud { .font_id(self.fonts.cyri) .font_size(14) .set(self.ids.entity_count, ui_widgets); + + // Number of chunks + Text::new(&format!( + "Chunks: {} ({} visible)", + debug_info.num_chunks, debug_info.num_visible_chunks, + )) + .color(TEXT_COLOR) + .down_from(self.ids.entity_count, 5.0) + .font_id(self.fonts.cyri) + .font_size(14) + .set(self.ids.num_chunks, ui_widgets); + + // Number of figures + Text::new(&format!( + "Figures: {} ({} visible)", + debug_info.num_figures, debug_info.num_figures_visible, + )) + .color(TEXT_COLOR) + .down_from(self.ids.num_chunks, 5.0) + .font_id(self.fonts.cyri) + .font_size(14) + .set(self.ids.num_figures, ui_widgets); // Help Window Text::new("Press 'F1' to show Keybindings") .color(TEXT_COLOR) - .down_from(self.ids.entity_count, 5.0) + .down_from(self.ids.num_figures, 5.0) .font_id(self.fonts.cyri) .font_size(14) .set(self.ids.help_info, ui_widgets); diff --git a/voxygen/src/scene/camera.rs b/voxygen/src/scene/camera.rs index 4176c53769..f7a990b279 100644 --- a/voxygen/src/scene/camera.rs +++ b/voxygen/src/scene/camera.rs @@ -103,10 +103,7 @@ impl Camera { pub fn frustum(&self, client: &Client) -> Frustum { let (view_mat, proj_mat, _) = self.compute_dependents(client); - Frustum::from_modelview_and_projection( - &view_mat.into_col_array(), - &proj_mat.into_col_array(), - ) + Frustum::from_modelview_projection((proj_mat * view_mat).into_col_arrays()) } /// Rotate the camera about its focus by the given delta, limiting the input accordingly. diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index a5f88385d7..3623914008 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -43,6 +43,8 @@ pub struct FigureMgr { fish_small_states: HashMap>, biped_large_states: HashMap>, object_states: HashMap>, + figure_count: usize, + visible_figure_count: usize, } impl FigureMgr { @@ -59,6 +61,8 @@ impl FigureMgr { fish_small_states: HashMap::new(), biped_large_states: HashMap::new(), object_states: HashMap::new(), + figure_count: 0, + visible_figure_count: 0, } } @@ -78,6 +82,8 @@ impl FigureMgr { .get(client.entity()) .map_or(Vec3::zero(), |pos| pos.0); + self.figure_count = 0; + for (entity, pos, ori, scale, body, character, last_character, stats) in ( &ecs.entities(), &ecs.read_storage::(), @@ -90,6 +96,7 @@ impl FigureMgr { ) .join() { + self.figure_count += 1; // Don't process figures outside the vd let vd_frac = Vec2::from(pos.0 - player_pos) .map2(TerrainChunk::RECT_SIZE, |d: f32, sz| { @@ -823,6 +830,8 @@ impl FigureMgr { .read_storage::(); let character_state = character_state_storage.get(client.entity()); + self.visible_figure_count = 0; + for (entity, _, _, body, stats, _) in ( &ecs.entities(), &ecs.read_storage::(), @@ -835,15 +844,14 @@ impl FigureMgr { // Don't render figures outside of frustum (camera viewport, max draw distance is farplane) .filter(|(_, pos, _, _, _, scale)| { frustum.sphere_intersecting( - &pos.0.x, - &pos.0.y, - &pos.0.z, - &(scale.unwrap_or(&Scale(1.0)).0 * 2.0), + pos.0.into_array(), + scale.unwrap_or(&Scale(1.0)).0 * 2.0, ) }) // Don't render dead entities .filter(|(_, _, _, _, stats, _)| stats.map_or(true, |s| !s.is_dead)) { + self.visible_figure_count += 1; if let Some((locals, bone_consts)) = match body { Body::Humanoid(_) => self .character_states @@ -912,6 +920,14 @@ impl FigureMgr { } } } + + pub fn figure_count(&self) -> usize { + self.figure_count + } + + pub fn figure_count_visible(&self) -> usize { + self.visible_figure_count + } } pub struct FigureState { diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index d43450806d..28c9f97abc 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -94,7 +94,7 @@ impl Scene { } } - /// Get a reference to the scene's globals + /// Get a reference to the scene's globals. pub fn globals(&self) -> &Consts { &self.globals } @@ -104,6 +104,16 @@ impl Scene { &self.camera } + /// Get a reference to the scene's terrain. + pub fn terrain(&self) -> &Terrain { + &self.terrain + } + + /// Get a reference to the scene's figure manager. + pub fn figure_mgr(&self) -> &FigureMgr { + &self.figure_mgr + } + /// Get a mutable reference to the scene's camera. pub fn camera_mut(&mut self) -> &mut Camera { &mut self.camera diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 93202101e2..6b39543a34 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -1035,10 +1035,7 @@ impl Terrain { } // Construct view frustum - let frustum = Frustum::from_modelview_and_projection( - &view_mat.into_col_array(), - &proj_mat.into_col_array(), - ); + let frustum = Frustum::from_modelview_projection((proj_mat * view_mat).into_col_arrays()); // Update chunk visibility let chunk_sz = V::RECT_SIZE.x as f32; @@ -1050,28 +1047,33 @@ impl Terrain { let in_range = Vec2::::from(focus_pos).distance_squared(nearest_in_chunk) < loaded_distance.powf(2.0); - // Ensure the chunk is within the view frustrum - let chunk_mid = Vec3::new( - chunk_pos.x + chunk_sz / 2.0, - chunk_pos.y + chunk_sz / 2.0, - (chunk.z_bounds.0 + chunk.z_bounds.1) * 0.5, - ); - let chunk_radius = ((chunk.z_bounds.1 - chunk.z_bounds.0) / 2.0) - .max(chunk_sz / 2.0) - .powf(2.0) - .mul(2.0) - .sqrt(); - let in_frustum = frustum.sphere_intersecting( - &chunk_mid.x, - &chunk_mid.y, - &chunk_mid.z, - &chunk_radius, - ); + if !in_range { + chunk.visible = in_range; + continue; + } - chunk.visible = in_range && in_frustum; + // Ensure the chunk is within the view frustum + let chunk_min = [chunk_pos.x, chunk_pos.y, chunk.z_bounds.0]; + let chunk_max = [ + chunk_pos.x + chunk_sz, + chunk_pos.y + chunk_sz, + chunk.z_bounds.1, + ]; + + let in_frustum = frustum.aabb_intersecting(chunk_min, chunk_max); + + chunk.visible = in_frustum; } } + pub fn chunk_count(&self) -> usize { + self.chunks.len() + } + + pub fn visible_chunk_count(&self) -> usize { + self.chunks.iter().filter(|(_, c)| c.visible).count() + } + pub fn render( &self, renderer: &mut Renderer, diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 3deff8abd4..e3eb0bac70 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -385,6 +385,10 @@ impl PlayState for SessionState { .read_storage::() .get(self.client.borrow().entity()) .cloned(), + num_chunks: self.scene.terrain().chunk_count() as u32, + num_visible_chunks: self.scene.terrain().visible_chunk_count() as u32, + num_figures: self.scene.figure_mgr().figure_count() as u32, + num_figures_visible: self.scene.figure_mgr().figure_count_visible() as u32, }, &self.scene.camera(), clock.get_last_delta(), From 820b4ea7fcf8be56300a40f2aff99437a4977294 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Tue, 19 Nov 2019 22:43:30 +0300 Subject: [PATCH 3/8] Use temporal coherence for chunk frustum culling --- Cargo.lock | 12 ++++++------ voxygen/Cargo.toml | 2 +- voxygen/src/scene/camera.rs | 2 +- voxygen/src/scene/figure/mod.rs | 2 +- voxygen/src/scene/terrain.rs | 7 +++++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e89e538426..06b2135261 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1062,9 +1062,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "frustum_query" -version = "0.1.2" -source = "git+https://github.com/yusdacra/frustum_query#866b36607a3a80356f0fc7a1cb29c2c59a70fdab" +name = "frustum_culling" +version = "0.1.0" +source = "git+https://gitlab.com/yusdacra/frustum_culling#735aef658c7e5eb0c4d543cacbea2f3e06216438" [[package]] name = "fsevent" @@ -3549,8 +3549,8 @@ dependencies = [ "dot_vox 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "euc 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", - "frustum_query 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "frustum_culling 0.1.0 (git+https://gitlab.com/yusdacra/frustum_culling)", "gfx 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_device_gl 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_window_glutin 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3981,7 +3981,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum frustum_query 0.1.2 (git+https://github.com/yusdacra/frustum_query)" = "" +"checksum frustum_culling 0.1.0 (git+https://gitlab.com/yusdacra/frustum_culling)" = "" "checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" "checksum fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index acc9183562..e493a44a92 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -55,7 +55,7 @@ directories = "2.0.2" num = "0.2.0" backtrace = "0.3.40" rand = "0.7.2" -frustum_query = { git = "https://github.com/yusdacra/frustum_query" } +frustum_culling = { git = "https://gitlab.com/yusdacra/frustum_culling" } # context for pinning to commit: https://gitlab.com/veloren/veloren/issues/280 rodio = { git = "https://github.com/RustAudio/rodio", rev = "e5474a2"} cpal = "0.10" diff --git a/voxygen/src/scene/camera.rs b/voxygen/src/scene/camera.rs index f7a990b279..b1595b0eaa 100644 --- a/voxygen/src/scene/camera.rs +++ b/voxygen/src/scene/camera.rs @@ -1,6 +1,6 @@ use client::Client; use common::vol::{ReadVol, Vox}; -use frustum_query::frustum::Frustum; +use frustum_culling::Frustum; use std::f32::consts::PI; use vek::*; diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 3623914008..7d94eb92cd 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -843,7 +843,7 @@ impl FigureMgr { .join() // Don't render figures outside of frustum (camera viewport, max draw distance is farplane) .filter(|(_, pos, _, _, _, scale)| { - frustum.sphere_intersecting( + frustum.test_sphere( pos.0.into_array(), scale.unwrap_or(&Scale(1.0)).0 * 2.0, ) diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 6b39543a34..4ef832be70 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -16,7 +16,7 @@ use common::{ }; use crossbeam::channel; use dot_vox::DotVoxData; -use frustum_query::frustum::Frustum; +use frustum_query::Frustum; use hashbrown::{hash_map::Entry, HashMap}; use std::{f32, fmt::Debug, i32, marker::PhantomData, ops::Mul, time::Duration}; use vek::*; @@ -31,6 +31,7 @@ struct TerrainChunkData { visible: bool, z_bounds: (f32, f32), + frustum_last_plane_index: u8, } struct ChunkMeshState { @@ -1021,6 +1022,7 @@ impl Terrain { .expect("Failed to upload chunk locals to the GPU!"), visible: false, z_bounds: response.z_bounds, + frustum_last_plane_index: 0, }, ); @@ -1060,8 +1062,9 @@ impl Terrain { chunk.z_bounds.1, ]; - let in_frustum = frustum.aabb_intersecting(chunk_min, chunk_max); + let (in_frustum, last_plane_index) = frustum.test_aabb_coherence(chunk_min, chunk_max, chunk.frustum_last_plane_index); + chunk.frustum_last_plane_index = last_plane_index; chunk.visible = in_frustum; } } From cc61925486f463cc1be50c80ae606dde5d44d33d Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 20 Nov 2019 02:29:34 +0300 Subject: [PATCH 4/8] Use temporal coherence for figure frustum culling, don't process figures if they are not in view frustum --- Cargo.lock | 2 +- voxygen/src/menu/char_selection/scene.rs | 2 + voxygen/src/scene/figure/mod.rs | 173 ++++++++++++++++++----- voxygen/src/scene/mod.rs | 2 +- 4 files changed, 143 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06b2135261..73f02110b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1064,7 +1064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "frustum_culling" version = "0.1.0" -source = "git+https://gitlab.com/yusdacra/frustum_culling#735aef658c7e5eb0c4d543cacbea2f3e06216438" +source = "git+https://gitlab.com/yusdacra/frustum_culling#7145dbee5eadf4df0cbe5aeda856a0967f47ace4" [[package]] name = "fsevent" diff --git a/voxygen/src/menu/char_selection/scene.rs b/voxygen/src/menu/char_selection/scene.rs index 906e60c0a4..e5712f956e 100644 --- a/voxygen/src/menu/char_selection/scene.rs +++ b/voxygen/src/menu/char_selection/scene.rs @@ -169,6 +169,8 @@ impl Scene { 1.0 / 60.0, // TODO: Use actual deltatime here? 1.0, 1.0, + 0, + true, ); } diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 7d94eb92cd..cdf1be2e24 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -43,8 +43,6 @@ pub struct FigureMgr { fish_small_states: HashMap>, biped_large_states: HashMap>, object_states: HashMap>, - figure_count: usize, - visible_figure_count: usize, } impl FigureMgr { @@ -61,8 +59,6 @@ impl FigureMgr { fish_small_states: HashMap::new(), biped_large_states: HashMap::new(), object_states: HashMap::new(), - figure_count: 0, - visible_figure_count: 0, } } @@ -70,7 +66,7 @@ impl FigureMgr { self.model_cache.clean(tick); } - pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) { + pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client, camera: &Camera) { let time = client.state().get_time(); let tick = client.get_tick(); let ecs = client.state().ecs(); @@ -82,8 +78,6 @@ impl FigureMgr { .get(client.entity()) .map_or(Vec3::zero(), |pos| pos.0); - self.figure_count = 0; - for (entity, pos, ori, scale, body, character, last_character, stats) in ( &ecs.entities(), &ecs.read_storage::(), @@ -96,7 +90,79 @@ impl FigureMgr { ) .join() { - self.figure_count += 1; + // Don't process figures outside the frustum spectrum + let frustum = camera.frustum(client); + + let (in_frustum, lpindex) = frustum.test_sphere_coherence( + pos.0.into_array(), + scale.unwrap_or(&Scale(1.0)).0 * 2.0, + match body { + Body::Humanoid(_) => { + self.character_states.get(&entity).map(|state| state.lpindex) + } + Body::QuadrupedSmall(_) => { + self.quadruped_small_states.get(&entity).map(|state| state.lpindex) + } + Body::QuadrupedMedium(_) => { + self.quadruped_medium_states.get(&entity).map(|state| state.lpindex) + } + Body::BirdMedium(_) => { + self.bird_medium_states.get(&entity).map(|state| state.lpindex) + } + Body::FishMedium(_) => { + self.fish_medium_states.get(&entity).map(|state| state.lpindex) + } + Body::Dragon(_) => { + self.dragon_states.get(&entity).map(|state| state.lpindex) + } + Body::BirdSmall(_) => { + self.bird_small_states.get(&entity).map(|state| state.lpindex) + } + Body::FishSmall(_) => { + self.fish_small_states.get(&entity).map(|state| state.lpindex) + } + Body::BipedLarge(_) => { + self.biped_large_states.get(&entity).map(|state| state.lpindex) + } + Body::Object(_) => { + self.object_states.get(&entity).map(|state| state.lpindex) + } + }.unwrap_or(0), + ); + + match body { + Body::Humanoid(_) => { + self.character_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + Body::QuadrupedSmall(_) => { + self.quadruped_small_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + Body::QuadrupedMedium(_) => { + self.quadruped_medium_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + Body::BirdMedium(_) => { + self.bird_medium_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + Body::FishMedium(_) => { + self.fish_medium_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + Body::Dragon(_) => { + self.dragon_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + Body::BirdSmall(_) => { + self.bird_small_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + Body::FishSmall(_) => { + self.fish_small_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + Body::BipedLarge(_) => { + self.biped_large_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + Body::Object(_) => { + self.object_states.get_mut(&entity).map(|state| state.visible = in_frustum); + } + } + // Don't process figures outside the vd let vd_frac = Vec2::from(pos.0 - player_pos) .map2(TerrainChunk::RECT_SIZE, |d: f32, sz| { @@ -139,7 +205,7 @@ impl FigureMgr { } } continue; - } else if vd_frac > 1.0 { + } else if vd_frac > 1.0 || !in_frustum { continue; } @@ -320,6 +386,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } Body::QuadrupedSmall(_) => { @@ -377,6 +445,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } Body::QuadrupedMedium(_) => { @@ -434,6 +504,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } Body::BirdMedium(_) => { @@ -489,6 +561,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } Body::FishMedium(_) => { @@ -544,6 +618,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } Body::Dragon(_) => { @@ -599,6 +675,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } Body::BirdSmall(_) => { @@ -654,6 +732,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } Body::FishSmall(_) => { @@ -709,6 +789,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } Body::BipedLarge(_) => { @@ -764,6 +846,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } Body::Object(_) => { @@ -783,6 +867,8 @@ impl FigureMgr { dt, movement_animation_rate, action_animation_rate, + lpindex, + true, ); } } @@ -823,15 +909,11 @@ impl FigureMgr { let tick = client.get_tick(); let ecs = client.state().ecs(); - let frustum = camera.frustum(client); - let character_state_storage = client .state() .read_storage::(); let character_state = character_state_storage.get(client.entity()); - self.visible_figure_count = 0; - for (entity, _, _, body, stats, _) in ( &ecs.entities(), &ecs.read_storage::(), @@ -841,59 +923,55 @@ impl FigureMgr { ecs.read_storage::().maybe(), ) .join() - // Don't render figures outside of frustum (camera viewport, max draw distance is farplane) - .filter(|(_, pos, _, _, _, scale)| { - frustum.test_sphere( - pos.0.into_array(), - scale.unwrap_or(&Scale(1.0)).0 * 2.0, - ) - }) // Don't render dead entities .filter(|(_, _, _, _, stats, _)| stats.map_or(true, |s| !s.is_dead)) { - self.visible_figure_count += 1; - if let Some((locals, bone_consts)) = match body { + if let Some((locals, bone_consts, visible)) = match body { Body::Humanoid(_) => self .character_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), Body::QuadrupedSmall(_) => self .quadruped_small_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), Body::QuadrupedMedium(_) => self .quadruped_medium_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), Body::BirdMedium(_) => self .bird_medium_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), Body::FishMedium(_) => self .fish_medium_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), Body::Dragon(_) => self .dragon_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), Body::BirdSmall(_) => self .bird_small_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), Body::FishSmall(_) => self .fish_small_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), Body::BipedLarge(_) => self .biped_large_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), Body::Object(_) => self .object_states .get(&entity) - .map(|state| (state.locals(), state.bone_consts())), + .map(|state| (state.locals(), state.bone_consts(), state.visible)), } { + if !visible { + continue; + } + let is_player = entity == client.entity(); let player_camera_mode = if is_player { @@ -922,11 +1000,30 @@ impl FigureMgr { } pub fn figure_count(&self) -> usize { - self.figure_count + self.character_states.len() + + self.quadruped_small_states.len() + + self.character_states.len() + + self.quadruped_medium_states.len() + + self.bird_medium_states.len() + + self.fish_medium_states.len() + + self.dragon_states.len() + + self.bird_small_states.len() + + self.fish_small_states.len() + + self.biped_large_states.len() + + self.object_states.len() } pub fn figure_count_visible(&self) -> usize { - self.visible_figure_count + self.character_states.iter().filter(|(_, c)| c.visible).count() + + self.quadruped_small_states.iter().filter(|(_, c)| c.visible).count() + + self.quadruped_medium_states.iter().filter(|(_, c)| c.visible).count() + + self.bird_medium_states.iter().filter(|(_, c)| c.visible).count() + + self.fish_medium_states.iter().filter(|(_, c)| c.visible).count() + + self.dragon_states.iter().filter(|(_, c)| c.visible).count() + + self.bird_small_states.iter().filter(|(_, c)| c.visible).count() + + self.fish_small_states.iter().filter(|(_, c)| c.visible).count() + + self.biped_large_states.iter().filter(|(_, c)| c.visible).count() + + self.object_states.iter().filter(|(_, c)| c.visible).count() } } @@ -939,6 +1036,8 @@ pub struct FigureState { pos: Vec3, ori: Vec3, last_ori: Vec3, + lpindex: u8, + visible: bool, } impl FigureState { @@ -954,6 +1053,8 @@ impl FigureState { pos: Vec3::zero(), ori: Vec3::zero(), last_ori: Vec3::zero(), + lpindex: 0, + visible: false, } } @@ -968,7 +1069,11 @@ impl FigureState { dt: f32, movement_rate: f32, action_rate: f32, + lpindex: u8, + visible: bool, ) { + self.visible = visible; + self.lpindex = lpindex; self.last_ori = Lerp::lerp(self.last_ori, ori, 15.0 * dt); // Update interpolation values diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 28c9f97abc..66aaacf40c 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -301,7 +301,7 @@ impl Scene { ); // Maintain the figures. - self.figure_mgr.maintain(renderer, client); + self.figure_mgr.maintain(renderer, client, &self.camera); // Remove unused figures. self.figure_mgr.clean(client.get_tick()); From 53382813233c83030efeae4c4ba927140e15d733 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 24 Nov 2019 23:53:47 +0300 Subject: [PATCH 5/8] Fix figure visible value not updating --- Cargo.lock | 32 +-------- voxygen/src/scene/figure/mod.rs | 122 +++++++++++++++++++++----------- 2 files changed, 80 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73f02110b1..691c3eb30d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -864,15 +864,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "dirs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "dirs-sys" version = "0.3.4" @@ -2983,16 +2974,6 @@ name = "shrev" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "simplelog" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "siphasher" version = "0.2.3" @@ -3245,15 +3226,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "term" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "termcolor" version = "1.0.5" @@ -3549,7 +3521,7 @@ dependencies = [ "dot_vox 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "euc 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "frustum_culling 0.1.0 (git+https://gitlab.com/yusdacra/frustum_culling)", "gfx 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_device_gl 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3957,7 +3929,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum derivative 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "942ca430eef7a3806595a6737bc388bf51adb888d3fc0dd1b50f1c170167ee3a" "checksum directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" -"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" "checksum discord-rpc-sdk 0.1.1 (git+https://github.com/Songtronix/rust-discord-rpc.git)" = "" "checksum discord-rpc-sys 0.1.0 (git+https://github.com/Songtronix/rust-discord-rpc.git)" = "" @@ -4221,7 +4192,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" -"checksum term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index cdf1be2e24..69cd4c3a51 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -90,6 +90,84 @@ impl FigureMgr { ) .join() { + // Don't process figures outside the vd + let vd_frac = Vec2::from(pos.0 - player_pos) + .map2(TerrainChunk::RECT_SIZE, |d: f32, sz| { + d.abs() as f32 / sz as f32 + }) + .magnitude() + / view_distance as f32; + // Keep from re-adding/removing entities on the border of the vd + if vd_frac > 1.2 { + match body { + Body::Humanoid(_) => { + self.character_states.remove(&entity); + } + Body::QuadrupedSmall(_) => { + self.quadruped_small_states.remove(&entity); + } + Body::QuadrupedMedium(_) => { + self.quadruped_medium_states.remove(&entity); + } + Body::BirdMedium(_) => { + self.bird_medium_states.remove(&entity); + } + Body::FishMedium(_) => { + self.fish_medium_states.remove(&entity); + } + Body::Dragon(_) => { + self.dragon_states.remove(&entity); + } + Body::BirdSmall(_) => { + self.bird_small_states.remove(&entity); + } + Body::FishSmall(_) => { + self.fish_small_states.remove(&entity); + } + Body::BipedLarge(_) => { + self.biped_large_states.remove(&entity); + } + Body::Object(_) => { + self.object_states.remove(&entity); + } + } + continue; + } else if vd_frac > 1.0 { + match body { + Body::Humanoid(_) => { + self.character_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::QuadrupedSmall(_) => { + self.quadruped_small_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::QuadrupedMedium(_) => { + self.quadruped_medium_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::BirdMedium(_) => { + self.bird_medium_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::FishMedium(_) => { + self.fish_medium_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::Dragon(_) => { + self.dragon_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::BirdSmall(_) => { + self.bird_small_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::FishSmall(_) => { + self.fish_small_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::BipedLarge(_) => { + self.biped_large_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::Object(_) => { + self.object_states.get_mut(&entity).map(|state| state.visible = false); + } + } + continue; + } + // Don't process figures outside the frustum spectrum let frustum = camera.frustum(client); @@ -163,49 +241,7 @@ impl FigureMgr { } } - // Don't process figures outside the vd - let vd_frac = Vec2::from(pos.0 - player_pos) - .map2(TerrainChunk::RECT_SIZE, |d: f32, sz| { - d.abs() as f32 / sz as f32 - }) - .magnitude() - / view_distance as f32; - // Keep from re-adding/removing entities on the border of the vd - if vd_frac > 1.2 { - match body { - Body::Humanoid(_) => { - self.character_states.remove(&entity); - } - Body::QuadrupedSmall(_) => { - self.quadruped_small_states.remove(&entity); - } - Body::QuadrupedMedium(_) => { - self.quadruped_medium_states.remove(&entity); - } - Body::BirdMedium(_) => { - self.bird_medium_states.remove(&entity); - } - Body::FishMedium(_) => { - self.fish_medium_states.remove(&entity); - } - Body::Dragon(_) => { - self.dragon_states.remove(&entity); - } - Body::BirdSmall(_) => { - self.bird_small_states.remove(&entity); - } - Body::FishSmall(_) => { - self.fish_small_states.remove(&entity); - } - Body::BipedLarge(_) => { - self.biped_large_states.remove(&entity); - } - Body::Object(_) => { - self.object_states.remove(&entity); - } - } - continue; - } else if vd_frac > 1.0 || !in_frustum { + if !in_frustum { continue; } From f5bdc4d6979dbd71bacace7e33a70d443aa51e87 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Tue, 7 Jan 2020 19:40:06 +0300 Subject: [PATCH 6/8] Use `treeculler` crate --- Cargo.lock | 17 ++++---- voxygen/Cargo.toml | 2 +- voxygen/src/scene/camera.rs | 4 +- voxygen/src/scene/figure/mod.rs | 71 ++++++++++++++++----------------- voxygen/src/scene/terrain.rs | 6 +-- 5 files changed, 51 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 691c3eb30d..038127bc5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1052,11 +1052,6 @@ name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "frustum_culling" -version = "0.1.0" -source = "git+https://gitlab.com/yusdacra/frustum_culling#7145dbee5eadf4df0cbe5aeda856a0967f47ace4" - [[package]] name = "fsevent" version = "0.4.0" @@ -3308,6 +3303,14 @@ dependencies = [ "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "treeculler" +version = "0.1.0" +source = "git+https://gitlab.com/yusdacra/treeculler.git#6c0fdf1c1cbf00be22e37410985d6a3973cd9bed" +dependencies = [ + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tuple_utils" version = "0.3.0" @@ -3522,7 +3525,6 @@ dependencies = [ "euc 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", - "frustum_culling 0.1.0 (git+https://gitlab.com/yusdacra/frustum_culling)", "gfx 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_device_gl 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_window_glutin 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3542,6 +3544,7 @@ dependencies = [ "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", "specs 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "treeculler 0.1.0 (git+https://gitlab.com/yusdacra/treeculler.git)", "vek 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", "veloren-client 0.4.0", "veloren-common 0.4.0", @@ -3952,7 +3955,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum frustum_culling 0.1.0 (git+https://gitlab.com/yusdacra/frustum_culling)" = "" "checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" "checksum fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" @@ -4201,6 +4203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tiny_http 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1661fa0a44c95d01604bd05c66732a446c657efb62b5164a7a083a3b552b4951" "checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20" "checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf" +"checksum treeculler 0.1.0 (git+https://gitlab.com/yusdacra/treeculler.git)" = "" "checksum tuple_utils 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44834418e2c5b16f47bedf35c28e148db099187dd5feee6367fb2525863af4f1" "checksum twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" "checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874" diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index e493a44a92..322575db69 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -55,7 +55,7 @@ directories = "2.0.2" num = "0.2.0" backtrace = "0.3.40" rand = "0.7.2" -frustum_culling = { git = "https://gitlab.com/yusdacra/frustum_culling" } +treeculler = { git = "https://gitlab.com/yusdacra/treeculler.git" } # context for pinning to commit: https://gitlab.com/veloren/veloren/issues/280 rodio = { git = "https://github.com/RustAudio/rodio", rev = "e5474a2"} cpal = "0.10" diff --git a/voxygen/src/scene/camera.rs b/voxygen/src/scene/camera.rs index b1595b0eaa..77886cb981 100644 --- a/voxygen/src/scene/camera.rs +++ b/voxygen/src/scene/camera.rs @@ -1,6 +1,6 @@ use client::Client; use common::vol::{ReadVol, Vox}; -use frustum_culling::Frustum; +use treeculler::Frustum; use std::f32::consts::PI; use vek::*; @@ -100,7 +100,7 @@ impl Camera { (view_mat, proj_mat, cam_pos) } - pub fn frustum(&self, client: &Client) -> Frustum { + pub fn frustum(&self, client: &Client) -> Frustum { let (view_mat, proj_mat, _) = self.compute_dependents(client); Frustum::from_modelview_projection((proj_mat * view_mat).into_col_arrays()) diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 69cd4c3a51..2c7d9e5d9f 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -27,6 +27,7 @@ use common::{ use hashbrown::HashMap; use log::trace; use specs::{Entity as EcsEntity, Join, WorldExt}; +use treeculler::{BoundingSphere, BVol}; use vek::*; const DAMAGE_FADE_COEFFICIENT: f64 = 5.0; @@ -171,9 +172,8 @@ impl FigureMgr { // Don't process figures outside the frustum spectrum let frustum = camera.frustum(client); - let (in_frustum, lpindex) = frustum.test_sphere_coherence( - pos.0.into_array(), - scale.unwrap_or(&Scale(1.0)).0 * 2.0, + let (in_frustum, lpindex) = BoundingSphere::new(pos.0.into_array(), scale.unwrap_or(&Scale(1.0)).0 * 2.0).coherent_test_against_frustum( + &frustum, match body { Body::Humanoid(_) => { self.character_states.get(&entity).map(|state| state.lpindex) @@ -208,40 +208,39 @@ impl FigureMgr { }.unwrap_or(0), ); - match body { - Body::Humanoid(_) => { - self.character_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - Body::QuadrupedSmall(_) => { - self.quadruped_small_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - Body::QuadrupedMedium(_) => { - self.quadruped_medium_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - Body::BirdMedium(_) => { - self.bird_medium_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - Body::FishMedium(_) => { - self.fish_medium_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - Body::Dragon(_) => { - self.dragon_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - Body::BirdSmall(_) => { - self.bird_small_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - Body::FishSmall(_) => { - self.fish_small_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - Body::BipedLarge(_) => { - self.biped_large_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - Body::Object(_) => { - self.object_states.get_mut(&entity).map(|state| state.visible = in_frustum); - } - } - if !in_frustum { + match body { + Body::Humanoid(_) => { + self.character_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::QuadrupedSmall(_) => { + self.quadruped_small_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::QuadrupedMedium(_) => { + self.quadruped_medium_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::BirdMedium(_) => { + self.bird_medium_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::FishMedium(_) => { + self.fish_medium_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::Dragon(_) => { + self.dragon_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::BirdSmall(_) => { + self.bird_small_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::FishSmall(_) => { + self.fish_small_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::BipedLarge(_) => { + self.biped_large_states.get_mut(&entity).map(|state| state.visible = false); + } + Body::Object(_) => { + self.object_states.get_mut(&entity).map(|state| state.visible = false); + } + } continue; } diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 4ef832be70..3f84b40318 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -16,9 +16,9 @@ use common::{ }; use crossbeam::channel; use dot_vox::DotVoxData; -use frustum_query::Frustum; +use treeculler::{Frustum, AABB, BVol}; use hashbrown::{hash_map::Entry, HashMap}; -use std::{f32, fmt::Debug, i32, marker::PhantomData, ops::Mul, time::Duration}; +use std::{f32, fmt::Debug, i32, marker::PhantomData, time::Duration}; use vek::*; struct TerrainChunkData { @@ -1062,7 +1062,7 @@ impl Terrain { chunk.z_bounds.1, ]; - let (in_frustum, last_plane_index) = frustum.test_aabb_coherence(chunk_min, chunk_max, chunk.frustum_last_plane_index); + let (in_frustum, last_plane_index) = AABB::new(chunk_min, chunk_max).coherent_test_against_frustum(&frustum, chunk.frustum_last_plane_index); chunk.frustum_last_plane_index = last_plane_index; chunk.visible = in_frustum; From a6b979104e42f8a611a5449b9d8ed7375bc2d610 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Tue, 7 Jan 2020 20:37:55 +0300 Subject: [PATCH 7/8] Replace radio list with drop down selector for AA mode setting --- voxygen/src/hud/settings_window.rs | 54 +++++++++++++++++------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/voxygen/src/hud/settings_window.rs b/voxygen/src/hud/settings_window.rs index 97f635463f..6d08ac6969 100644 --- a/voxygen/src/hud/settings_window.rs +++ b/voxygen/src/hud/settings_window.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::{ render::AaMode, - ui::{ImageSlider, RadioList, ScaleMode, ToggleButton}, + ui::{ImageSlider, ScaleMode, ToggleButton}, GlobalState, }; use conrod_core::{ @@ -84,8 +84,8 @@ widget_ids! { fov_slider, fov_text, fov_value, - aa_radio_buttons, aa_mode_text, + aa_mode_list, audio_volume_slider, audio_volume_text, sfx_volume_slider, @@ -1332,30 +1332,36 @@ impl<'a> Widget for SettingsWindow<'a> { .font_id(self.fonts.cyri) .color(TEXT_COLOR) .set(state.ids.aa_mode_text, ui); - let mode_label_list = [ - (&AaMode::None, "No AA"), - (&AaMode::Fxaa, "FXAA"), - (&AaMode::MsaaX4, "MSAA x4"), - (&AaMode::MsaaX8, "MSAA x8"), - (&AaMode::MsaaX16, "MSAA x16 (experimental)"), - (&AaMode::SsaaX4, "SSAA x4"), + + let mode_list = [ + AaMode::None, + AaMode::Fxaa, + AaMode::MsaaX4, + AaMode::MsaaX8, + AaMode::MsaaX16, + AaMode::SsaaX4, ]; - if let Some((_, mode)) = RadioList::new( - (0..mode_label_list.len()) - .find(|i| *mode_label_list[*i].0 == self.global_state.settings.graphics.aa_mode) - .unwrap_or(0), - self.imgs.check, - self.imgs.check_checked, - &mode_label_list, - ) - .hover_images(self.imgs.check_mo, self.imgs.check_checked_mo) - .press_images(self.imgs.check_press, self.imgs.check_press) - .down_from(state.ids.aa_mode_text, 8.0) - .text_color(TEXT_COLOR) - .font_size(12) - .set(state.ids.aa_radio_buttons, ui) + let mode_label_list = [ + "No AA", + "FXAA", + "MSAA x4", + "MSAA x8", + "MSAA x16 (experimental)", + "SSAA x4", + ]; + + // Get which AA mode is currently active + let selected = mode_list.iter().position(|x| *x == self.global_state.settings.graphics.aa_mode); + + if let Some(clicked) = DropDownList::new(&mode_label_list, selected) + .w_h(400.0, 22.0) + .color(MENU_BG) + .label_color(TEXT_COLOR) + .label_font_id(self.fonts.cyri) + .down_from(state.ids.aa_mode_text, 8.0) + .set(state.ids.aa_mode_list, ui) { - events.push(Event::ChangeAaMode(*mode)) + events.push(Event::ChangeAaMode(mode_list[clicked])); } } From 44d9e7c590bf6a9d1d6c72691a71f216c7455c20 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Wed, 8 Jan 2020 20:09:54 +0300 Subject: [PATCH 8/8] Cargo fmt --- voxygen/src/hud/mod.rs | 2 +- voxygen/src/hud/settings_window.rs | 4 +- voxygen/src/mesh/terrain.rs | 18 ++- voxygen/src/scene/camera.rs | 2 +- voxygen/src/scene/figure/mod.rs | 234 +++++++++++++++++++---------- voxygen/src/scene/terrain.rs | 9 +- 6 files changed, 183 insertions(+), 86 deletions(-) diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 48d60c6bd5..7af4cad854 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -994,7 +994,7 @@ impl Hud { .font_id(self.fonts.cyri) .font_size(14) .set(self.ids.entity_count, ui_widgets); - + // Number of chunks Text::new(&format!( "Chunks: {} ({} visible)", diff --git a/voxygen/src/hud/settings_window.rs b/voxygen/src/hud/settings_window.rs index 6d08ac6969..b63678dc58 100644 --- a/voxygen/src/hud/settings_window.rs +++ b/voxygen/src/hud/settings_window.rs @@ -1351,7 +1351,9 @@ impl<'a> Widget for SettingsWindow<'a> { ]; // Get which AA mode is currently active - let selected = mode_list.iter().position(|x| *x == self.global_state.settings.graphics.aa_mode); + let selected = mode_list + .iter() + .position(|x| *x == self.global_state.settings.graphics.aa_mode); if let Some(clicked) = DropDownList::new(&mode_label_list, selected) .w_h(400.0, 22.0) diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 5154c20617..75439e1f0a 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -238,11 +238,23 @@ impl + ReadVol + Debug> Meshable 1.0 { match body { Body::Humanoid(_) => { - self.character_states.get_mut(&entity).map(|state| state.visible = false); + self.character_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::QuadrupedSmall(_) => { - self.quadruped_small_states.get_mut(&entity).map(|state| state.visible = false); + self.quadruped_small_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::QuadrupedMedium(_) => { - self.quadruped_medium_states.get_mut(&entity).map(|state| state.visible = false); + self.quadruped_medium_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::BirdMedium(_) => { - self.bird_medium_states.get_mut(&entity).map(|state| state.visible = false); + self.bird_medium_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::FishMedium(_) => { - self.fish_medium_states.get_mut(&entity).map(|state| state.visible = false); + self.fish_medium_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::Dragon(_) => { - self.dragon_states.get_mut(&entity).map(|state| state.visible = false); + self.dragon_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::BirdSmall(_) => { - self.bird_small_states.get_mut(&entity).map(|state| state.visible = false); + self.bird_small_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::FishSmall(_) => { - self.fish_small_states.get_mut(&entity).map(|state| state.visible = false); + self.fish_small_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::BipedLarge(_) => { - self.biped_large_states.get_mut(&entity).map(|state| state.visible = false); + self.biped_large_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::Object(_) => { - self.object_states.get_mut(&entity).map(|state| state.visible = false); + self.object_states + .get_mut(&entity) + .map(|state| state.visible = false); } } continue; @@ -172,73 +192,104 @@ impl FigureMgr { // Don't process figures outside the frustum spectrum let frustum = camera.frustum(client); - let (in_frustum, lpindex) = BoundingSphere::new(pos.0.into_array(), scale.unwrap_or(&Scale(1.0)).0 * 2.0).coherent_test_against_frustum( - &frustum, - match body { - Body::Humanoid(_) => { - self.character_states.get(&entity).map(|state| state.lpindex) - } - Body::QuadrupedSmall(_) => { - self.quadruped_small_states.get(&entity).map(|state| state.lpindex) - } - Body::QuadrupedMedium(_) => { - self.quadruped_medium_states.get(&entity).map(|state| state.lpindex) - } - Body::BirdMedium(_) => { - self.bird_medium_states.get(&entity).map(|state| state.lpindex) - } - Body::FishMedium(_) => { - self.fish_medium_states.get(&entity).map(|state| state.lpindex) - } - Body::Dragon(_) => { - self.dragon_states.get(&entity).map(|state| state.lpindex) - } - Body::BirdSmall(_) => { - self.bird_small_states.get(&entity).map(|state| state.lpindex) - } - Body::FishSmall(_) => { - self.fish_small_states.get(&entity).map(|state| state.lpindex) - } - Body::BipedLarge(_) => { - self.biped_large_states.get(&entity).map(|state| state.lpindex) - } - Body::Object(_) => { - self.object_states.get(&entity).map(|state| state.lpindex) - } - }.unwrap_or(0), - ); + let (in_frustum, lpindex) = + BoundingSphere::new(pos.0.into_array(), scale.unwrap_or(&Scale(1.0)).0 * 2.0) + .coherent_test_against_frustum( + &frustum, + match body { + Body::Humanoid(_) => self + .character_states + .get(&entity) + .map(|state| state.lpindex), + Body::QuadrupedSmall(_) => self + .quadruped_small_states + .get(&entity) + .map(|state| state.lpindex), + Body::QuadrupedMedium(_) => self + .quadruped_medium_states + .get(&entity) + .map(|state| state.lpindex), + Body::BirdMedium(_) => self + .bird_medium_states + .get(&entity) + .map(|state| state.lpindex), + Body::FishMedium(_) => self + .fish_medium_states + .get(&entity) + .map(|state| state.lpindex), + Body::Dragon(_) => { + self.dragon_states.get(&entity).map(|state| state.lpindex) + } + Body::BirdSmall(_) => self + .bird_small_states + .get(&entity) + .map(|state| state.lpindex), + Body::FishSmall(_) => self + .fish_small_states + .get(&entity) + .map(|state| state.lpindex), + Body::BipedLarge(_) => self + .biped_large_states + .get(&entity) + .map(|state| state.lpindex), + Body::Object(_) => { + self.object_states.get(&entity).map(|state| state.lpindex) + } + } + .unwrap_or(0), + ); if !in_frustum { match body { Body::Humanoid(_) => { - self.character_states.get_mut(&entity).map(|state| state.visible = false); + self.character_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::QuadrupedSmall(_) => { - self.quadruped_small_states.get_mut(&entity).map(|state| state.visible = false); + self.quadruped_small_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::QuadrupedMedium(_) => { - self.quadruped_medium_states.get_mut(&entity).map(|state| state.visible = false); + self.quadruped_medium_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::BirdMedium(_) => { - self.bird_medium_states.get_mut(&entity).map(|state| state.visible = false); + self.bird_medium_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::FishMedium(_) => { - self.fish_medium_states.get_mut(&entity).map(|state| state.visible = false); + self.fish_medium_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::Dragon(_) => { - self.dragon_states.get_mut(&entity).map(|state| state.visible = false); + self.dragon_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::BirdSmall(_) => { - self.bird_small_states.get_mut(&entity).map(|state| state.visible = false); + self.bird_small_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::FishSmall(_) => { - self.fish_small_states.get_mut(&entity).map(|state| state.visible = false); + self.fish_small_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::BipedLarge(_) => { - self.biped_large_states.get_mut(&entity).map(|state| state.visible = false); + self.biped_large_states + .get_mut(&entity) + .map(|state| state.visible = false); } Body::Object(_) => { - self.object_states.get_mut(&entity).map(|state| state.visible = false); + self.object_states + .get_mut(&entity) + .map(|state| state.visible = false); } } continue; @@ -1036,29 +1087,60 @@ impl FigureMgr { pub fn figure_count(&self) -> usize { self.character_states.len() - + self.quadruped_small_states.len() - + self.character_states.len() - + self.quadruped_medium_states.len() - + self.bird_medium_states.len() - + self.fish_medium_states.len() - + self.dragon_states.len() - + self.bird_small_states.len() - + self.fish_small_states.len() - + self.biped_large_states.len() - + self.object_states.len() + + self.quadruped_small_states.len() + + self.character_states.len() + + self.quadruped_medium_states.len() + + self.bird_medium_states.len() + + self.fish_medium_states.len() + + self.dragon_states.len() + + self.bird_small_states.len() + + self.fish_small_states.len() + + self.biped_large_states.len() + + self.object_states.len() } pub fn figure_count_visible(&self) -> usize { - self.character_states.iter().filter(|(_, c)| c.visible).count() - + self.quadruped_small_states.iter().filter(|(_, c)| c.visible).count() - + self.quadruped_medium_states.iter().filter(|(_, c)| c.visible).count() - + self.bird_medium_states.iter().filter(|(_, c)| c.visible).count() - + self.fish_medium_states.iter().filter(|(_, c)| c.visible).count() - + self.dragon_states.iter().filter(|(_, c)| c.visible).count() - + self.bird_small_states.iter().filter(|(_, c)| c.visible).count() - + self.fish_small_states.iter().filter(|(_, c)| c.visible).count() - + self.biped_large_states.iter().filter(|(_, c)| c.visible).count() - + self.object_states.iter().filter(|(_, c)| c.visible).count() + self.character_states + .iter() + .filter(|(_, c)| c.visible) + .count() + + self + .quadruped_small_states + .iter() + .filter(|(_, c)| c.visible) + .count() + + self + .quadruped_medium_states + .iter() + .filter(|(_, c)| c.visible) + .count() + + self + .bird_medium_states + .iter() + .filter(|(_, c)| c.visible) + .count() + + self + .fish_medium_states + .iter() + .filter(|(_, c)| c.visible) + .count() + + self.dragon_states.iter().filter(|(_, c)| c.visible).count() + + self + .bird_small_states + .iter() + .filter(|(_, c)| c.visible) + .count() + + self + .fish_small_states + .iter() + .filter(|(_, c)| c.visible) + .count() + + self + .biped_large_states + .iter() + .filter(|(_, c)| c.visible) + .count() + + self.object_states.iter().filter(|(_, c)| c.visible).count() } } diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 3f84b40318..17ec303719 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -16,9 +16,9 @@ use common::{ }; use crossbeam::channel; use dot_vox::DotVoxData; -use treeculler::{Frustum, AABB, BVol}; use hashbrown::{hash_map::Entry, HashMap}; use std::{f32, fmt::Debug, i32, marker::PhantomData, time::Duration}; +use treeculler::{BVol, Frustum, AABB}; use vek::*; struct TerrainChunkData { @@ -1062,7 +1062,8 @@ impl Terrain { chunk.z_bounds.1, ]; - let (in_frustum, last_plane_index) = AABB::new(chunk_min, chunk_max).coherent_test_against_frustum(&frustum, chunk.frustum_last_plane_index); + let (in_frustum, last_plane_index) = AABB::new(chunk_min, chunk_max) + .coherent_test_against_frustum(&frustum, chunk.frustum_last_plane_index); chunk.frustum_last_plane_index = last_plane_index; chunk.visible = in_frustum; @@ -1071,8 +1072,8 @@ impl Terrain { pub fn chunk_count(&self) -> usize { self.chunks.len() - } - + } + pub fn visible_chunk_count(&self) -> usize { self.chunks.iter().filter(|(_, c)| c.visible).count() }