mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improve frustum culling by using AABBs, add related debug information
This commit is contained in:
parent
fd9cc76786
commit
e32153e980
34
Cargo.lock
generated
34
Cargo.lock
generated
@ -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)" = "<none>"
|
||||
"checksum discord-rpc-sys 0.1.0 (git+https://github.com/Songtronix/rust-discord-rpc.git)" = "<none>"
|
||||
@ -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)" = "<none>"
|
||||
"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"
|
||||
|
@ -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"
|
||||
|
@ -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<comp::Pos>,
|
||||
pub velocity: Option<comp::Vel>,
|
||||
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);
|
||||
|
@ -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.
|
||||
|
@ -43,6 +43,8 @@ pub struct FigureMgr {
|
||||
fish_small_states: HashMap<EcsEntity, FigureState<FishSmallSkeleton>>,
|
||||
biped_large_states: HashMap<EcsEntity, FigureState<BipedLargeSkeleton>>,
|
||||
object_states: HashMap<EcsEntity, FigureState<ObjectSkeleton>>,
|
||||
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::<Pos>(),
|
||||
@ -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::<common::comp::CharacterState>();
|
||||
let character_state = character_state_storage.get(client.entity());
|
||||
|
||||
self.visible_figure_count = 0;
|
||||
|
||||
for (entity, _, _, body, stats, _) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<Pos>(),
|
||||
@ -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<S: Skeleton> {
|
||||
|
@ -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<Globals> {
|
||||
&self.globals
|
||||
}
|
||||
@ -104,6 +104,16 @@ impl Scene {
|
||||
&self.camera
|
||||
}
|
||||
|
||||
/// Get a reference to the scene's terrain.
|
||||
pub fn terrain(&self) -> &Terrain<TerrainChunk> {
|
||||
&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
|
||||
|
@ -1035,10 +1035,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
}
|
||||
|
||||
// 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<V: RectRasterableVol> Terrain<V> {
|
||||
let in_range = Vec2::<f32>::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,
|
||||
|
@ -385,6 +385,10 @@ impl PlayState for SessionState {
|
||||
.read_storage::<Vel>()
|
||||
.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(),
|
||||
|
Loading…
Reference in New Issue
Block a user