mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
particles on volume
This commit is contained in:
parent
1710dcc111
commit
7fbe2cd5ec
@ -18,7 +18,7 @@
|
||||
),
|
||||
|
||||
custom_indices: {
|
||||
1: Air(Door, 4),
|
||||
1: Air(ChairSingle, 4),
|
||||
},
|
||||
),
|
||||
AirBalloon: (
|
||||
|
@ -31,7 +31,7 @@ use common::{
|
||||
},
|
||||
figure::{Segment, TerrainSegment},
|
||||
slowjob::SlowJobPool,
|
||||
vol::{BaseVol, IntoVolIterator},
|
||||
vol::{BaseVol, IntoVolIterator, ReadVol},
|
||||
};
|
||||
use core::{hash::Hash, ops::Range};
|
||||
use crossbeam_utils::atomic;
|
||||
@ -58,6 +58,7 @@ pub struct TerrainMeshWorkerResponse<const N: usize> {
|
||||
vertex_range: [Range<u32>; N],
|
||||
sprite_instances: [Vec<SpriteInstance>; SPRITE_LOD_LEVELS],
|
||||
blocks_of_interest: BlocksOfInterest,
|
||||
blocks_offset: Vec3<f32>,
|
||||
}
|
||||
|
||||
/// NOTE: To test this cell for validity, we currently first use
|
||||
@ -655,6 +656,7 @@ where
|
||||
vertex_range,
|
||||
sprite_instances,
|
||||
blocks_of_interest,
|
||||
blocks_offset,
|
||||
}) = Arc::get_mut(recv).take().and_then(|cell| cell.take())
|
||||
{
|
||||
let model_entry = col_lights.create_terrain(
|
||||
@ -666,6 +668,7 @@ where
|
||||
ori,
|
||||
sprite_instances,
|
||||
blocks_of_interest,
|
||||
blocks_offset,
|
||||
);
|
||||
*model = TerrainModelEntryFuture::Done(model_entry);
|
||||
// NOTE: Borrow checker isn't smart enough to figure this out.
|
||||
@ -834,13 +837,16 @@ where
|
||||
lod.push(instance);
|
||||
},
|
||||
block_iter.clone().map(|(pos, block)| (pos.as_() + *offset, block)),
|
||||
|p| p.as_(), |_| 1.0, |_| 0.0,
|
||||
|p| p.as_(),
|
||||
|_| 1.0,
|
||||
|pos| dyna.get(pos).ok().and_then(|block| block.get_glow()).map(|glow| glow as f32 / 255.0).unwrap_or(0.0),
|
||||
&sprite_data,
|
||||
&sprite_config,
|
||||
);
|
||||
instances
|
||||
},
|
||||
blocks_of_interest: BlocksOfInterest::from_blocks(block_iter, 0.0, 10.0, 0.0),
|
||||
blocks_offset: *offset,
|
||||
}));
|
||||
});
|
||||
|
||||
@ -856,7 +862,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_blocks_of_interest(&self, body: Skel::Body) -> Option<&BlocksOfInterest> {
|
||||
pub fn get_blocks_of_interest(
|
||||
&self,
|
||||
body: Skel::Body,
|
||||
) -> Option<(&BlocksOfInterest, Vec3<f32>)> {
|
||||
let key = FigureKey {
|
||||
body,
|
||||
item_key: None,
|
||||
@ -867,7 +876,7 @@ where
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(&model.blocks_of_interest)
|
||||
Some((&model.blocks_of_interest, model.blocks_offset))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -143,6 +143,8 @@ pub struct TerrainModelEntry<const N: usize> {
|
||||
lod_vertex_ranges: [Range<u32>; N],
|
||||
model: FigureModel,
|
||||
|
||||
blocks_offset: Vec3<f32>,
|
||||
|
||||
terrain_locals: BoundTerrainLocals,
|
||||
sprite_instances: [Instances<SpriteInstance>; SPRITE_LOD_LEVELS],
|
||||
|
||||
@ -6939,14 +6941,14 @@ impl FigureMgr {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_sprite_instances(
|
||||
&self,
|
||||
fn get_sprite_instances<'a>(
|
||||
&'a self,
|
||||
entity: EcsEntity,
|
||||
body: &Body,
|
||||
collider: Option<&Collider>,
|
||||
) -> Option<(
|
||||
&BoundTerrainLocals,
|
||||
&[Instances<SpriteInstance>; SPRITE_LOD_LEVELS],
|
||||
&'a BoundTerrainLocals,
|
||||
&'a [Instances<SpriteInstance>; SPRITE_LOD_LEVELS],
|
||||
)> {
|
||||
match body {
|
||||
Body::Ship(body) => {
|
||||
@ -6964,6 +6966,28 @@ impl FigureMgr {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_blocks_of_interest<'a>(
|
||||
&'a self,
|
||||
entity: EcsEntity,
|
||||
body: &Body,
|
||||
collider: Option<&Collider>,
|
||||
) -> Option<(&'a BlocksOfInterest, Vec3<f32>)> {
|
||||
match body {
|
||||
Body::Ship(body) => {
|
||||
if let Some(Collider::Volume(vol)) = collider {
|
||||
let vk = VolumeKey {
|
||||
entity,
|
||||
mut_count: vol.mut_count,
|
||||
};
|
||||
self.volume_model_cache.get_blocks_of_interest(vk)
|
||||
} else {
|
||||
self.ship_model_cache.get_blocks_of_interest(*body)
|
||||
}
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn viewpoint_offset(&self, scene_data: &SceneData, entity: EcsEntity) -> Vec3<f32> {
|
||||
scene_data
|
||||
.state
|
||||
@ -7151,6 +7175,7 @@ impl FigureColLights {
|
||||
ori: Quaternion<f32>,
|
||||
sprite_instances: [Vec<SpriteInstance>; SPRITE_LOD_LEVELS],
|
||||
blocks_of_interest: BlocksOfInterest,
|
||||
blocks_offset: Vec3<f32>,
|
||||
) -> TerrainModelEntry<N> {
|
||||
span!(_guard, "create_figure", "FigureColLights::create_figure");
|
||||
let atlas = &mut self.atlas;
|
||||
@ -7192,6 +7217,7 @@ impl FigureColLights {
|
||||
terrain_locals,
|
||||
sprite_instances,
|
||||
blocks_of_interest,
|
||||
blocks_offset,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -655,8 +655,13 @@ impl Scene {
|
||||
lights.clear();
|
||||
|
||||
// Maintain the particles.
|
||||
self.particle_mgr
|
||||
.maintain(renderer, scene_data, &self.terrain, lights);
|
||||
self.particle_mgr.maintain(
|
||||
renderer,
|
||||
scene_data,
|
||||
&self.terrain,
|
||||
&self.figure_mgr,
|
||||
lights,
|
||||
);
|
||||
|
||||
// Maintain the trails.
|
||||
self.trail_mgr.maintain(renderer, scene_data);
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{terrain::BlocksOfInterest, SceneData, Terrain};
|
||||
use super::{terrain::BlocksOfInterest, FigureMgr, SceneData, Terrain};
|
||||
use crate::{
|
||||
ecs::comp::Interpolated,
|
||||
mesh::{greedy::GreedyMesh, segment::generate_mesh_base_vol_particle},
|
||||
@ -400,6 +400,7 @@ impl ParticleMgr {
|
||||
renderer: &mut Renderer,
|
||||
scene_data: &SceneData,
|
||||
terrain: &Terrain<TerrainChunk>,
|
||||
figure_mgr: &FigureMgr,
|
||||
lights: &mut Vec<Light>,
|
||||
) {
|
||||
span!(_guard, "maintain", "ParticleMgr::maintain");
|
||||
@ -415,7 +416,7 @@ impl ParticleMgr {
|
||||
self.maintain_body_particles(scene_data);
|
||||
self.maintain_char_state_particles(scene_data);
|
||||
self.maintain_beam_particles(scene_data, lights);
|
||||
self.maintain_block_particles(scene_data, terrain);
|
||||
self.maintain_block_particles(scene_data, terrain, figure_mgr);
|
||||
self.maintain_shockwave_particles(scene_data);
|
||||
self.maintain_aura_particles(scene_data);
|
||||
self.maintain_buff_particles(scene_data);
|
||||
@ -1434,6 +1435,7 @@ impl ParticleMgr {
|
||||
&mut self,
|
||||
scene_data: &SceneData,
|
||||
terrain: &Terrain<TerrainChunk>,
|
||||
figure_mgr: &FigureMgr,
|
||||
) {
|
||||
span!(
|
||||
_guard,
|
||||
@ -1533,6 +1535,7 @@ impl ParticleMgr {
|
||||
},
|
||||
];
|
||||
|
||||
let ecs = scene_data.state.ecs();
|
||||
let mut rng = thread_rng();
|
||||
for particles in particles.iter() {
|
||||
if !(particles.cond)(scene_data) {
|
||||
@ -1564,6 +1567,45 @@ impl ParticleMgr {
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
for (entity, body, pos, ori, collider) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<comp::Body>(),
|
||||
&ecs.read_storage::<comp::Pos>(),
|
||||
&ecs.read_storage::<comp::Ori>(),
|
||||
ecs.read_storage::<comp::Collider>().maybe(),
|
||||
)
|
||||
.join()
|
||||
{
|
||||
if let Some((blocks_of_interest, offset)) =
|
||||
figure_mgr.get_blocks_of_interest(entity, body, collider)
|
||||
{
|
||||
let blocks = (particles.blocks)(blocks_of_interest);
|
||||
|
||||
let avg_particles = dt * blocks.len() as f32 * particles.rate;
|
||||
let particle_count = avg_particles.trunc() as usize
|
||||
+ (rng.gen::<f32>() < avg_particles.fract()) as usize;
|
||||
|
||||
self.particles
|
||||
.resize_with(self.particles.len() + particle_count, || {
|
||||
let rel_pos = blocks
|
||||
.choose(&mut rng)
|
||||
.copied()
|
||||
.unwrap()
|
||||
.map(|e: i32| e as f32 + rng.gen::<f32>()); // Can't fail
|
||||
let wpos = (Mat4::from(ori.to_quat()).translated_3d(pos.0)
|
||||
* (rel_pos + offset).with_w(1.0))
|
||||
.xyz();
|
||||
|
||||
Particle::new(
|
||||
Duration::from_secs_f32(particles.lifetime),
|
||||
time,
|
||||
particles.mode,
|
||||
wpos,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
// smoke is more complex as it comes with varying rate and color
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user