mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
make sprites work on multiple ships at once
This commit is contained in:
parent
134d0f0c04
commit
e39790e9e4
@ -88,5 +88,9 @@
|
||||
offset: (0.0, 0.0, 0.0),
|
||||
central: ("empty"),
|
||||
),
|
||||
|
||||
custom_indices: {
|
||||
1: Air(Helm, 0),
|
||||
},
|
||||
),
|
||||
})
|
||||
|
BIN
assets/common/voxel/galleon/structure.vox
(Stored with Git LFS)
BIN
assets/common/voxel/galleon/structure.vox
(Stored with Git LFS)
Binary file not shown.
@ -100,7 +100,7 @@ impl Body {
|
||||
pub fn density(&self) -> Density {
|
||||
match self {
|
||||
Body::DefaultAirship | Body::AirBalloon | Body::Volume => Density(AIR_DENSITY),
|
||||
_ => Density(AIR_DENSITY * 0.8 + WATER_DENSITY * 0.2), // Most boats should be buoyant
|
||||
_ => Density(AIR_DENSITY * 0.2 + WATER_DENSITY * 0.8), // Most boats should be buoyant
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ use crate::{
|
||||
segment::{generate_mesh_base_vol_figure, generate_mesh_base_vol_terrain},
|
||||
},
|
||||
render::{
|
||||
pipelines::terrain::{BoundLocals as BoundTerrainLocals, Locals as TerrainLocals},
|
||||
BoneMeshes, ColLightInfo, FigureModel, Instances, Mesh, Renderer, SpriteInstance,
|
||||
TerrainVertex,
|
||||
},
|
||||
@ -621,8 +620,6 @@ where
|
||||
&'c mut self,
|
||||
renderer: &mut Renderer,
|
||||
col_lights: &mut super::FigureColLights,
|
||||
pos: Vec3<f32>,
|
||||
ori: Quaternion<f32>,
|
||||
body: Skel::Body,
|
||||
extra: <Skel::Body as BodySpec>::Extra,
|
||||
tick: u64,
|
||||
@ -664,8 +661,6 @@ where
|
||||
col_light,
|
||||
(opaque, bounds),
|
||||
vertex_range,
|
||||
pos,
|
||||
ori,
|
||||
sprite_instances,
|
||||
blocks_of_interest,
|
||||
blocks_offset,
|
||||
@ -883,10 +878,9 @@ where
|
||||
pub fn get_sprites(
|
||||
&self,
|
||||
body: Skel::Body,
|
||||
) -> Option<(
|
||||
&BoundTerrainLocals,
|
||||
) -> Option<
|
||||
&[Instances<SpriteInstance>; SPRITE_LOD_LEVELS],
|
||||
)> {
|
||||
> {
|
||||
let key = FigureKey {
|
||||
body,
|
||||
item_key: None,
|
||||
@ -897,13 +891,15 @@ where
|
||||
return None;
|
||||
};
|
||||
|
||||
Some((&model.terrain_locals, &model.sprite_instances))
|
||||
Some(&model.sprite_instances)
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn update_terrain_locals(
|
||||
&mut self,
|
||||
renderer: &mut Renderer,
|
||||
entity: Entity,
|
||||
body: Skel::Body,
|
||||
pos: Vec3<f32>,
|
||||
ori: Quaternion<f32>,
|
||||
@ -928,4 +924,5 @@ where
|
||||
)])
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -146,7 +146,6 @@ pub struct TerrainModelEntry<const N: usize> {
|
||||
|
||||
blocks_offset: Vec3<f32>,
|
||||
|
||||
terrain_locals: BoundTerrainLocals,
|
||||
sprite_instances: [Instances<SpriteInstance>; SPRITE_LOD_LEVELS],
|
||||
|
||||
blocks_of_interest: BlocksOfInterest,
|
||||
@ -204,8 +203,8 @@ struct FigureMgrStates {
|
||||
golem_states: HashMap<EcsEntity, FigureState<GolemSkeleton>>,
|
||||
object_states: HashMap<EcsEntity, FigureState<ObjectSkeleton>>,
|
||||
item_drop_states: HashMap<EcsEntity, FigureState<ItemDropSkeleton>>,
|
||||
ship_states: HashMap<EcsEntity, FigureState<ShipSkeleton>>,
|
||||
volume_states: HashMap<EcsEntity, FigureState<VolumeKey>>,
|
||||
ship_states: HashMap<EcsEntity, FigureState<ShipSkeleton, BoundTerrainLocals>>,
|
||||
volume_states: HashMap<EcsEntity, FigureState<VolumeKey, BoundTerrainLocals>>,
|
||||
arthropod_states: HashMap<EcsEntity, FigureState<ArthropodSkeleton>>,
|
||||
}
|
||||
|
||||
@ -330,10 +329,12 @@ impl FigureMgrStates {
|
||||
Body::Object(_) => self.object_states.remove(entity).map(|e| e.meta),
|
||||
Body::ItemDrop(_) => self.item_drop_states.remove(entity).map(|e| e.meta),
|
||||
Body::Ship(ship) => {
|
||||
if ship.manifest_entry().is_some() {
|
||||
if matches!(ship, ship::Body::Volume) {
|
||||
self.volume_states.remove(entity).map(|e| e.meta)
|
||||
} else if ship.manifest_entry().is_some() {
|
||||
self.ship_states.remove(entity).map(|e| e.meta)
|
||||
} else {
|
||||
self.volume_states.remove(entity).map(|e| e.meta)
|
||||
None
|
||||
}
|
||||
},
|
||||
Body::Arthropod(_) => self.arthropod_states.remove(entity).map(|e| e.meta),
|
||||
@ -471,6 +472,24 @@ impl FigureMgrStates {
|
||||
.filter(|(_, c)| c.visible())
|
||||
.count()
|
||||
}
|
||||
|
||||
fn get_terrain_locals<'a, Q: ?Sized>(&'a self, body: &Body, entity: &Q) -> Option<&'a BoundTerrainLocals>
|
||||
where
|
||||
EcsEntity: Borrow<Q>,
|
||||
Q: Hash + Eq, {
|
||||
match body {
|
||||
Body::Ship(body) => {
|
||||
if matches!(body, ship::Body::Volume) {
|
||||
self.volume_states.get(entity).map(|state| &state.extra)
|
||||
} else if body.manifest_entry().is_some() {
|
||||
self.ship_states.get(entity).map(|state| &state.extra)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FigureMgr {
|
||||
@ -6102,8 +6121,6 @@ impl FigureMgr {
|
||||
self.volume_model_cache.get_or_create_terrain_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
pos.0.into(),
|
||||
ori.into_vec4().into(),
|
||||
vk,
|
||||
Arc::clone(vol),
|
||||
tick,
|
||||
@ -6126,20 +6143,11 @@ impl FigureMgr {
|
||||
model,
|
||||
vk,
|
||||
);
|
||||
|
||||
self.volume_model_cache.update_terrain_locals(
|
||||
renderer,
|
||||
vk,
|
||||
pos.0.into(),
|
||||
ori.into_vec4().into(),
|
||||
);
|
||||
continue;
|
||||
} else if body.manifest_entry().is_some() {
|
||||
self.ship_model_cache.get_or_create_terrain_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
pos.0.into(),
|
||||
ori.into_vec4().into(),
|
||||
body,
|
||||
(),
|
||||
tick,
|
||||
@ -6218,13 +6226,6 @@ impl FigureMgr {
|
||||
model,
|
||||
body,
|
||||
);
|
||||
|
||||
self.ship_model_cache.update_terrain_locals(
|
||||
renderer,
|
||||
body,
|
||||
pos.0.into(),
|
||||
ori.into_vec4().into(),
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -6344,8 +6345,8 @@ impl FigureMgr {
|
||||
// Don't render dead entities
|
||||
.filter(|(_, _, _, _, health, _)| health.map_or(true, |h| !h.is_dead))
|
||||
{
|
||||
if let Some((data, sprite_instances)) =
|
||||
self.get_sprite_instances(entity, body, collider)
|
||||
if let Some((sprite_instances, data)) =
|
||||
self.get_sprite_instances(entity, body, collider).zip(self.states.get_terrain_locals(body, &entity))
|
||||
{
|
||||
let dist = collider
|
||||
.and_then(|collider| {
|
||||
@ -6888,7 +6889,27 @@ impl FigureMgr {
|
||||
)
|
||||
}),
|
||||
Body::Ship(body) => {
|
||||
if body.manifest_entry().is_some() {
|
||||
if matches!(body, ship::Body::Volume) {
|
||||
volume_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.bound(),
|
||||
volume_model_cache
|
||||
.get_model(
|
||||
col_lights,
|
||||
VolumeKey { entity, mut_count },
|
||||
None,
|
||||
tick,
|
||||
CameraMode::default(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.map(ModelEntryRef::Terrain),
|
||||
)
|
||||
})
|
||||
} else if body.manifest_entry().is_some() {
|
||||
ship_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(state))
|
||||
@ -6909,25 +6930,7 @@ impl FigureMgr {
|
||||
)
|
||||
})
|
||||
} else {
|
||||
volume_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.bound(),
|
||||
volume_model_cache
|
||||
.get_model(
|
||||
col_lights,
|
||||
VolumeKey { entity, mut_count },
|
||||
None,
|
||||
tick,
|
||||
CameraMode::default(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.map(ModelEntryRef::Terrain),
|
||||
)
|
||||
})
|
||||
None
|
||||
}
|
||||
},
|
||||
} {
|
||||
@ -6970,10 +6973,8 @@ impl FigureMgr {
|
||||
entity: EcsEntity,
|
||||
body: &Body,
|
||||
collider: Option<&Collider>,
|
||||
) -> Option<(
|
||||
&'a BoundTerrainLocals,
|
||||
&'a [Instances<SpriteInstance>; SPRITE_LOD_LEVELS],
|
||||
)> {
|
||||
) -> Option<
|
||||
&'a [Instances<SpriteInstance>; SPRITE_LOD_LEVELS]> {
|
||||
match body {
|
||||
Body::Ship(body) => {
|
||||
if let Some(Collider::Volume(vol)) = collider {
|
||||
@ -6982,8 +6983,10 @@ impl FigureMgr {
|
||||
mut_count: vol.mut_count,
|
||||
};
|
||||
self.volume_model_cache.get_sprites(vk)
|
||||
} else {
|
||||
} else if body.manifest_entry().is_some() {
|
||||
self.ship_model_cache.get_sprites(*body)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
_ => None,
|
||||
@ -7195,8 +7198,6 @@ impl FigureColLights {
|
||||
(tex, tex_size): ColLightInfo,
|
||||
(opaque, bounds): (Mesh<TerrainVertex>, math::Aabb<f32>),
|
||||
vertex_ranges: [Range<u32>; N],
|
||||
pos: Vec3<f32>,
|
||||
ori: Quaternion<f32>,
|
||||
sprite_instances: [Vec<SpriteInstance>; SPRITE_LOD_LEVELS],
|
||||
blocks_of_interest: BlocksOfInterest,
|
||||
blocks_offset: Vec3<f32>,
|
||||
@ -7222,13 +7223,6 @@ impl FigureColLights {
|
||||
);
|
||||
});
|
||||
|
||||
let terrain_locals = renderer.create_terrain_bound_locals(&[TerrainLocals::new(
|
||||
pos,
|
||||
ori,
|
||||
Vec2::zero(),
|
||||
0.0,
|
||||
)]);
|
||||
|
||||
let sprite_instances =
|
||||
sprite_instances.map(|instances| renderer.create_instances(&instances));
|
||||
|
||||
@ -7238,7 +7232,6 @@ impl FigureColLights {
|
||||
col_lights,
|
||||
lod_vertex_ranges: vertex_ranges,
|
||||
model: FigureModel { opaque: model },
|
||||
terrain_locals,
|
||||
sprite_instances,
|
||||
blocks_of_interest,
|
||||
blocks_offset,
|
||||
@ -7320,18 +7313,19 @@ impl FigureStateMeta {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FigureState<S> {
|
||||
pub struct FigureState<S, D = ()> {
|
||||
meta: FigureStateMeta,
|
||||
skeleton: S,
|
||||
extra: D,
|
||||
}
|
||||
|
||||
impl<S> Deref for FigureState<S> {
|
||||
impl<S, D> Deref for FigureState<S, D> {
|
||||
type Target = FigureStateMeta;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.meta }
|
||||
}
|
||||
|
||||
impl<S> DerefMut for FigureState<S> {
|
||||
impl<S, D> DerefMut for FigureState<S, D> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.meta }
|
||||
}
|
||||
|
||||
@ -7358,7 +7352,35 @@ pub struct FigureUpdateCommonParameters<'a> {
|
||||
pub ground_vel: Vec3<f32>,
|
||||
}
|
||||
|
||||
impl<S: Skeleton> FigureState<S> {
|
||||
pub trait FigureData: Sized {
|
||||
fn new(renderer: &mut Renderer) -> Self;
|
||||
|
||||
fn update(&mut self, renderer: &mut Renderer, parameters: &FigureUpdateCommonParameters);
|
||||
}
|
||||
|
||||
impl FigureData for () {
|
||||
fn new(_renderer: &mut Renderer) -> Self {
|
||||
()
|
||||
}
|
||||
|
||||
fn update(&mut self, _renderer: &mut Renderer, _parameters: &FigureUpdateCommonParameters) {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
impl FigureData for BoundTerrainLocals {
|
||||
fn new(renderer: &mut Renderer) -> Self {
|
||||
renderer.create_terrain_bound_locals(&[TerrainLocals::new(Vec3::zero(), Quaternion::identity(), Vec2::zero(), 0.0)])
|
||||
}
|
||||
|
||||
fn update(&mut self, renderer: &mut Renderer, parameters: &FigureUpdateCommonParameters) {
|
||||
renderer.update_consts(self, &[
|
||||
TerrainLocals::new(parameters.pos.into(), parameters.ori.into_vec4().into(), Vec2::zero(), 0.0),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Skeleton, D: FigureData> FigureState<S, D> {
|
||||
pub fn new(renderer: &mut Renderer, skeleton: S, body: S::Body) -> Self {
|
||||
let mut buf = [Default::default(); anim::MAX_BONE_COUNT];
|
||||
let offsets =
|
||||
@ -7386,6 +7408,7 @@ impl<S: Skeleton> FigureState<S> {
|
||||
bound: renderer.create_figure_bound_locals(&[FigureLocals::default()], bone_consts),
|
||||
},
|
||||
skeleton,
|
||||
extra: D::new(renderer),
|
||||
}
|
||||
}
|
||||
|
||||
@ -7394,7 +7417,7 @@ impl<S: Skeleton> FigureState<S> {
|
||||
renderer: &mut Renderer,
|
||||
trail_mgr: Option<&mut TrailMgr>,
|
||||
buf: &mut [anim::FigureBoneData; anim::MAX_BONE_COUNT],
|
||||
FigureUpdateCommonParameters {
|
||||
parameters @ FigureUpdateCommonParameters {
|
||||
entity,
|
||||
pos,
|
||||
ori,
|
||||
@ -7614,6 +7637,7 @@ impl<S: Skeleton> FigureState<S> {
|
||||
} else {
|
||||
self.acc_vel = 0.0;
|
||||
}
|
||||
self.extra.update(renderer, parameters);
|
||||
}
|
||||
|
||||
pub fn bound(&self) -> &pipelines::figure::BoundLocals { &self.bound }
|
||||
|
Loading…
Reference in New Issue
Block a user