attempt to generate collider on background thread
This commit is contained in:
12
.vscode/launch.json
vendored
12
.vscode/launch.json
vendored
@@ -14,12 +14,12 @@
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}/target/debug",
|
||||
"preLaunchTask": "Build",
|
||||
// "environment": [
|
||||
// {
|
||||
// "name": "RUST_BACKTRACE",
|
||||
// "value": "1"
|
||||
// }
|
||||
// ]
|
||||
"environment": [
|
||||
{
|
||||
"name": "RUST_BACKTRACE",
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -8,7 +8,7 @@ pub mod tile_manager;
|
||||
pub mod tile_mapper;
|
||||
|
||||
pub mod prelude {
|
||||
use crate::hex_utils::{tile_to_world_distance, HexCoord, INNER_RADIUS, OUTER_RADIUS, SHORT_DIAGONAL};
|
||||
use crate::hex_utils::{HexCoord, INNER_RADIUS, OUTER_RADIUS, SHORT_DIAGONAL};
|
||||
use bevy::math::{IVec2, UVec2, Vec2, Vec3};
|
||||
use bevy::prelude::Resource;
|
||||
use bevy::prelude::*;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use bevy::core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin};
|
||||
use bevy::input::mouse::{MouseMotion, MouseScrollUnit, MouseWheel};
|
||||
use bevy::pbr::ScreenSpaceAmbientOcclusionBundle;
|
||||
use bevy::prelude::*;
|
||||
use bevy::window::CursorGrabMode;
|
||||
use bevy_rapier3d::plugin::RapierContext;
|
||||
use world_generation::hex_utils::HexCoord;
|
||||
use world_generation::prelude::Map;
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
use bevy::prelude::*;
|
||||
use world_generation::{
|
||||
hex_utils::{tile_to_world_distance, SHORT_DIAGONAL},
|
||||
prelude::Chunk,
|
||||
};
|
||||
use world_generation::{hex_utils::SHORT_DIAGONAL, prelude::Chunk};
|
||||
|
||||
#[derive(Component, Reflect)]
|
||||
#[reflect(Component)]
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
use std::mem::swap;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier3d::geometry::{Collider, TriMeshFlags};
|
||||
use bevy::tasks::*;
|
||||
use bevy::utils::futures;
|
||||
use bevy_rapier3d::geometry::Collider;
|
||||
use bevy_rapier3d::geometry::TriMeshFlags;
|
||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||
use world_generation::{
|
||||
biome_painter::BiomePainterAsset,
|
||||
chunk_colliders::generate_chunk_collider,
|
||||
hex_utils::{self, offset_to_world, SHORT_DIAGONAL},
|
||||
mesh_generator::generate_chunk_mesh,
|
||||
hex_utils::SHORT_DIAGONAL,
|
||||
prelude::{Chunk, Map},
|
||||
tile_manager::TileAsset,
|
||||
tile_mapper::TileMapperAsset,
|
||||
@@ -13,7 +16,7 @@ use world_generation::{
|
||||
|
||||
use crate::{
|
||||
prelude::{ChunkAtlas, PhosChunk, PhosChunkRegistry},
|
||||
utlis::render_distance_system::RenderDistanceVisibility,
|
||||
utlis::{chunk_utils::prepare_chunk_mesh, render_distance_system::RenderDistanceVisibility},
|
||||
};
|
||||
|
||||
use super::prelude::CurrentBiomePainter;
|
||||
@@ -24,6 +27,7 @@ impl Plugin for ChunkRebuildPlugin {
|
||||
app.insert_resource(ChunkRebuildQueue::default());
|
||||
app.init_resource::<PhosChunkRegistry>();
|
||||
app.add_systems(PreUpdate, chunk_rebuilder);
|
||||
app.add_systems(PreUpdate, collider_task_resolver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +55,7 @@ fn chunk_rebuilder(
|
||||
|
||||
for chunk_index in &queue.queue {
|
||||
let chunk = chunks.chunks[*chunk_index];
|
||||
// commands.entity(chunk).remove::<Handle<Mesh>>();
|
||||
commands.entity(chunk).despawn();
|
||||
}
|
||||
|
||||
@@ -62,21 +67,26 @@ fn chunk_rebuilder(
|
||||
.queue
|
||||
.par_iter()
|
||||
.map(|idx| {
|
||||
let chunk = &heightmap.chunks[*idx];
|
||||
let mesh = generate_chunk_mesh(chunk, &heightmap, cur_painter, &tile_assets, &tile_mappers);
|
||||
let (col_verts, col_indicies) = generate_chunk_collider(chunk, &heightmap);
|
||||
let collider =
|
||||
Collider::trimesh_with_flags(col_verts, col_indicies, TriMeshFlags::MERGE_DUPLICATE_VERTICES);
|
||||
return (
|
||||
mesh,
|
||||
collider,
|
||||
offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.),
|
||||
hex_utils::offset_to_index(chunk.chunk_offset, heightmap.width),
|
||||
return prepare_chunk_mesh(
|
||||
&heightmap.chunks[*idx],
|
||||
&heightmap,
|
||||
cur_painter,
|
||||
&tile_assets,
|
||||
&tile_mappers,
|
||||
);
|
||||
})
|
||||
.collect();
|
||||
|
||||
for (mesh, collider, pos, index) in chunk_meshes {
|
||||
let pool = TaskPool::new();
|
||||
|
||||
for (mesh, collider_data, pos, index) in chunk_meshes {
|
||||
let task = pool.spawn(async {
|
||||
Collider::trimesh_with_flags(
|
||||
collider_data.0,
|
||||
collider_data.1,
|
||||
TriMeshFlags::DELETE_DUPLICATE_TRIANGLES,
|
||||
)
|
||||
});
|
||||
let chunk = commands.spawn((
|
||||
MaterialMeshBundle {
|
||||
mesh: meshes.add(mesh),
|
||||
@@ -90,9 +100,25 @@ fn chunk_rebuilder(
|
||||
0.,
|
||||
(Chunk::SIZE / 2) as f32 * 1.5,
|
||||
)),
|
||||
collider,
|
||||
ColliderTask { task },
|
||||
));
|
||||
chunks.chunks[index] = chunk.id();
|
||||
}
|
||||
queue.queue.clear();
|
||||
}
|
||||
|
||||
fn collider_task_resolver(mut chunks: Query<(&mut ColliderTask, Entity), With<PhosChunk>>, mut commands: Commands) {
|
||||
for (mut task, entity) in &mut chunks {
|
||||
match futures::check_ready(&mut task.task) {
|
||||
Some(c) => {
|
||||
commands.entity(entity).insert(c);
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
struct ColliderTask {
|
||||
pub task: Task<Collider>,
|
||||
}
|
||||
|
||||
@@ -2,16 +2,9 @@
|
||||
use bevy::log::*;
|
||||
use bevy::{asset::LoadState, pbr::ExtendedMaterial, prelude::*};
|
||||
use bevy_inspector_egui::quick::ResourceInspectorPlugin;
|
||||
use bevy_rapier3d::geometry::Collider;
|
||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||
use world_generation::{
|
||||
biome_painter::*,
|
||||
chunk_colliders::generate_chunk_collider,
|
||||
heightmap::generate_heightmap,
|
||||
hex_utils::{self, offset_to_world, SHORT_DIAGONAL},
|
||||
mesh_generator::generate_chunk_mesh,
|
||||
prelude::*,
|
||||
tile_manager::*,
|
||||
biome_painter::*, heightmap::generate_heightmap, hex_utils::SHORT_DIAGONAL, prelude::*, tile_manager::*,
|
||||
tile_mapper::*,
|
||||
};
|
||||
|
||||
@@ -19,7 +12,10 @@ use crate::{
|
||||
camera_system::components::*,
|
||||
prelude::{ChunkAtlas, PhosChunk, PhosChunkRegistry, PhosMap},
|
||||
shader_extensions::chunk_material::ChunkMaterial,
|
||||
utlis::render_distance_system::RenderDistanceVisibility,
|
||||
utlis::{
|
||||
chunk_utils::{prepare_chunk_mesh, prepare_chunk_mesh_with_collider},
|
||||
render_distance_system::RenderDistanceVisibility,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -218,22 +214,7 @@ fn spawn_map(
|
||||
.chunks
|
||||
.par_iter()
|
||||
.map(|chunk: &Chunk| {
|
||||
#[cfg(feature = "tracing")]
|
||||
let _gen_mesh = info_span!("Generate Chunk").entered();
|
||||
let mesh = generate_chunk_mesh(chunk, &heightmap, cur_painter, &tile_assets, &tile_mappers);
|
||||
let (col_verts, col_indicies) = generate_chunk_collider(chunk, &heightmap);
|
||||
let collider: Collider;
|
||||
{
|
||||
#[cfg(feature = "tracing")]
|
||||
let _collider_span = info_span!("Create Collider Trimesh").entered();
|
||||
collider = Collider::trimesh(col_verts, col_indicies);
|
||||
}
|
||||
return (
|
||||
mesh,
|
||||
collider,
|
||||
offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.),
|
||||
hex_utils::offset_to_index(chunk.chunk_offset, heightmap.width),
|
||||
);
|
||||
return prepare_chunk_mesh_with_collider(chunk, &heightmap, cur_painter, &tile_assets, &tile_mappers);
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ fn deform(
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let mut multi = 0.;
|
||||
if mouse.pressed(MouseButton::Left) {
|
||||
if mouse.just_pressed(MouseButton::Left) {
|
||||
multi = 1.;
|
||||
} else if mouse.pressed(MouseButton::Right) {
|
||||
multi = -1.;
|
||||
|
||||
51
game/main/src/utlis/chunk_utils.rs
Normal file
51
game/main/src/utlis/chunk_utils.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
#[cfg(feature = "tracing")]
|
||||
use bevy::log::*;
|
||||
use bevy::{asset::Assets, ecs::system::Res, math::Vec3, render::mesh::Mesh};
|
||||
use bevy_rapier3d::geometry::{Collider, TriMeshFlags};
|
||||
use world_generation::{
|
||||
biome_painter::BiomePainterAsset,
|
||||
chunk_colliders::generate_chunk_collider,
|
||||
hex_utils::{offset_to_index, offset_to_world},
|
||||
mesh_generator::generate_chunk_mesh,
|
||||
prelude::{Chunk, Map},
|
||||
tile_manager::TileAsset,
|
||||
tile_mapper::TileMapperAsset,
|
||||
};
|
||||
|
||||
pub fn prepare_chunk_mesh(
|
||||
chunk: &Chunk,
|
||||
heightmap: &Map,
|
||||
painter: &BiomePainterAsset,
|
||||
tile_assets: &Res<Assets<TileAsset>>,
|
||||
tile_mappers: &Res<Assets<TileMapperAsset>>,
|
||||
) -> (Mesh, (Vec<Vec3>, Vec<[u32; 3]>), Vec3, usize) {
|
||||
#[cfg(feature = "tracing")]
|
||||
let _gen_mesh = info_span!("Generate Chunk").entered();
|
||||
let mesh = generate_chunk_mesh(chunk, &heightmap, painter, &tile_assets, &tile_mappers);
|
||||
let col_data = generate_chunk_collider(chunk, &heightmap);
|
||||
|
||||
return (
|
||||
mesh,
|
||||
col_data,
|
||||
offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.),
|
||||
offset_to_index(chunk.chunk_offset, heightmap.width),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn prepare_chunk_mesh_with_collider(
|
||||
chunk: &Chunk,
|
||||
heightmap: &Map,
|
||||
painter: &BiomePainterAsset,
|
||||
tile_assets: &Res<Assets<TileAsset>>,
|
||||
tile_mappers: &Res<Assets<TileMapperAsset>>,
|
||||
) -> (Mesh, Collider, Vec3, usize) {
|
||||
let (mesh, (col_verts, col_indicies), pos, index) =
|
||||
prepare_chunk_mesh(chunk, heightmap, painter, tile_assets, tile_mappers);
|
||||
let collider: Collider;
|
||||
{
|
||||
#[cfg(feature = "tracing")]
|
||||
let _collider_span = info_span!("Create Collider Trimesh").entered();
|
||||
collider = Collider::trimesh_with_flags(col_verts, col_indicies, TriMeshFlags::DELETE_DUPLICATE_TRIANGLES);
|
||||
}
|
||||
return (mesh, collider, pos, index);
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
pub mod chunk_utils;
|
||||
pub mod render_distance_system;
|
||||
|
||||
Reference in New Issue
Block a user