mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Weapon trails now works with dual wielding
This commit is contained in:
parent
a967daa2f5
commit
b3a19ebc00
@ -113,7 +113,8 @@ impl Skeleton for ArthropodSkeleton {
|
||||
orientation: mount_orientation,
|
||||
scale: Vec3::one(),
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +137,8 @@ impl Skeleton for BipedLargeSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,8 @@ impl Skeleton for BipedSmallSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,8 @@ impl Skeleton for BirdLargeSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,8 @@ impl Skeleton for BirdMediumSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ skeleton_impls!(struct CharacterSkeleton {
|
||||
:: // Begin non-bone fields
|
||||
holding_lantern: bool,
|
||||
main_weapon_trail: bool,
|
||||
off_weapon_trail: bool,
|
||||
});
|
||||
|
||||
impl CharacterSkeleton {
|
||||
@ -127,6 +128,7 @@ impl Skeleton for CharacterSkeleton {
|
||||
shorts_mat
|
||||
} * Mat4::<f32>::from(self.lantern);
|
||||
let main_mat = control_l_mat * Mat4::<f32>::from(self.main);
|
||||
let second_mat = control_r_mat * Mat4::<f32>::from(self.second);
|
||||
|
||||
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
|
||||
make_bone(head_mat),
|
||||
@ -142,7 +144,7 @@ impl Skeleton for CharacterSkeleton {
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.shoulder_r)),
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.glider)),
|
||||
make_bone(main_mat),
|
||||
make_bone(control_r_mat * Mat4::<f32>::from(self.second)),
|
||||
make_bone(second_mat),
|
||||
make_bone(lantern_mat),
|
||||
// FIXME: Should this be control_l_mat?
|
||||
make_bone(control_mat * hand_l_mat * Mat4::<f32>::from(self.hold)),
|
||||
@ -157,7 +159,8 @@ impl Skeleton for CharacterSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: self.main_weapon_trail.then_some(main_mat),
|
||||
main_weapon_trail_mat: self.main_weapon_trail.then_some(main_mat),
|
||||
off_weapon_trail_mat: self.off_weapon_trail.then_some(second_mat),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,8 @@ impl Skeleton for DragonSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,8 @@ impl Skeleton for FishMediumSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,8 @@ impl Skeleton for FishSmallSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,8 @@ impl Skeleton for FixtureSkeleton {
|
||||
Offsets {
|
||||
lantern: None,
|
||||
mount_bone: Transform::default(),
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,8 @@ impl Skeleton for GolemSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ impl Skeleton for ItemDropSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
#![feature(
|
||||
generic_associated_types,
|
||||
bool_to_option,
|
||||
)]
|
||||
#![feature(generic_associated_types, bool_to_option)]
|
||||
#![allow(incomplete_features)]
|
||||
#[cfg(all(feature = "be-dyn-lib", feature = "use-dyn-lib"))]
|
||||
compile_error!("Can't use both \"be-dyn-lib\" and \"use-dyn-lib\" features at once");
|
||||
@ -106,7 +103,8 @@ pub fn init() { lazy_static::initialize(&LIB); }
|
||||
pub struct Offsets {
|
||||
pub lantern: Option<Vec3<f32>>,
|
||||
pub mount_bone: Transform<f32, f32, f32>,
|
||||
pub weapon_trail_mat: Option<Mat4<f32>>,
|
||||
pub main_weapon_trail_mat: Option<Mat4<f32>>,
|
||||
pub off_weapon_trail_mat: Option<Mat4<f32>>,
|
||||
}
|
||||
|
||||
pub trait Skeleton: Send + Sync + 'static {
|
||||
|
@ -49,7 +49,8 @@ impl Skeleton for ObjectSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,8 @@ impl Skeleton for QuadrupedLowSkeleton {
|
||||
orientation: mount_orientation,
|
||||
scale: Vec3::one(),
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,8 @@ impl Skeleton for QuadrupedMediumSkeleton {
|
||||
orientation: mount_orientation,
|
||||
scale: Vec3::one(),
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,8 @@ impl Skeleton for QuadrupedSmallSkeleton {
|
||||
orientation: mount_orientation,
|
||||
scale: Vec3::one(),
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ impl Skeleton for ShipSkeleton {
|
||||
),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,8 @@ impl Skeleton for TheropodSkeleton {
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,9 +33,8 @@ use common::{
|
||||
comp::{
|
||||
inventory::slot::EquipSlot,
|
||||
item::{Hands, ItemKind, ToolKind},
|
||||
Body, CharacterState, Collider, Controller, Health, Inventory, Item,
|
||||
ItemKey, Last, LightAnimation, LightEmitter, Ori, PhysicsState, PoiseState, Pos, Scale,
|
||||
Vel,
|
||||
Body, CharacterState, Collider, Controller, Health, Inventory, Item, ItemKey, Last,
|
||||
LightAnimation, LightEmitter, Ori, PhysicsState, PoiseState, Pos, Scale, Vel,
|
||||
},
|
||||
link::Is,
|
||||
mounting::Rider,
|
||||
@ -6192,7 +6191,8 @@ impl FigureColLights {
|
||||
|
||||
pub struct FigureStateMeta {
|
||||
lantern_offset: Option<anim::vek::Vec3<f32>>,
|
||||
abs_trail_points: Option<(anim::vek::Vec3<f32>, anim::vek::Vec3<f32>)>,
|
||||
main_abs_trail_points: Option<(anim::vek::Vec3<f32>, anim::vek::Vec3<f32>)>,
|
||||
off_abs_trail_points: Option<(anim::vek::Vec3<f32>, anim::vek::Vec3<f32>)>,
|
||||
// Animation to be applied to rider of this entity
|
||||
mount_transform: anim::vek::Transform<f32, f32, f32>,
|
||||
// Contains the position of this figure or if it is a rider it will contain the mount's
|
||||
@ -6270,7 +6270,8 @@ impl<S: Skeleton> FigureState<S> {
|
||||
Self {
|
||||
meta: FigureStateMeta {
|
||||
lantern_offset: offsets.lantern,
|
||||
abs_trail_points: None,
|
||||
main_abs_trail_points: None,
|
||||
off_abs_trail_points: None,
|
||||
mount_transform: offsets.mount_bone,
|
||||
mount_world_pos: anim::vek::Vec3::zero(),
|
||||
state_time: 0.0,
|
||||
@ -6440,7 +6441,16 @@ impl<S: Skeleton> FigureState<S> {
|
||||
renderer.update_consts(&mut self.meta.bound.1, &new_bone_consts[0..S::BONE_COUNT]);
|
||||
self.lantern_offset = offsets.lantern;
|
||||
// Handle weapon trails
|
||||
let weapon_offsets = offsets.weapon_trail_mat.map(|mat| {
|
||||
fn handle_weapon_trails(
|
||||
trail_mgr: &mut TrailMgr,
|
||||
new_weapon_trail_mat: Option<anim::vek::Mat4<f32>>,
|
||||
old_abs_trail_points: &mut Option<(anim::vek::Vec3<f32>, anim::vek::Vec3<f32>)>,
|
||||
entity: EcsEntity,
|
||||
is_main_weapon: bool,
|
||||
pos: anim::vek::Vec3<f32>,
|
||||
tools: (Option<ToolKind>, Option<ToolKind>),
|
||||
) {
|
||||
let weapon_offsets = new_weapon_trail_mat.map(|mat| {
|
||||
let (trail_start, trail_end) = match tools.0 {
|
||||
Some(ToolKind::Sword) => (20.25, 29.25),
|
||||
// TODO: Make sure these are good positions, only did tweaking on sword
|
||||
@ -6453,24 +6463,40 @@ impl<S: Skeleton> FigureState<S> {
|
||||
(mat * anim::vek::Vec4::new(0.0, 0.0, trail_end, 1.0)).xyz(),
|
||||
)
|
||||
});
|
||||
let offsets_abs_trail_points = weapon_offsets.map(|(a, b)| (a + pos, b + pos));
|
||||
if let Some(trail_mgr) = trail_mgr {
|
||||
if let Some(quad_mesh) = entity
|
||||
.as_ref()
|
||||
.and_then(|e| trail_mgr.entity_meshes.get_mut(e))
|
||||
{
|
||||
if let (Some((p1, p2)), Some((p4, p3))) =
|
||||
(self.abs_trail_points, offsets_abs_trail_points)
|
||||
let new_abs_trail_points = weapon_offsets.map(|(a, b)| (a + pos, b + pos));
|
||||
let trail_mgr_offset = trail_mgr.offset;
|
||||
let quad_mesh = trail_mgr.entity_mesh_or_insert(entity, is_main_weapon);
|
||||
if let (Some((p1, p2)), Some((p4, p3))) = (&old_abs_trail_points, new_abs_trail_points)
|
||||
{
|
||||
let vertex = |p: anim::vek::Vec3<f32>| trail::Vertex {
|
||||
pos: p.into_array(),
|
||||
};
|
||||
let quad = Quad::new(vertex(p1), vertex(p2), vertex(p3), vertex(p4));
|
||||
quad_mesh.replace_quad(trail_mgr.offset * 4, quad);
|
||||
let quad = Quad::new(vertex(*p1), vertex(*p2), vertex(p3), vertex(p4));
|
||||
quad_mesh.replace_quad(trail_mgr_offset * 4, quad);
|
||||
}
|
||||
*old_abs_trail_points = new_abs_trail_points;
|
||||
}
|
||||
|
||||
if let (Some(trail_mgr), Some(entity)) = (trail_mgr, entity) {
|
||||
handle_weapon_trails(
|
||||
trail_mgr,
|
||||
offsets.main_weapon_trail_mat,
|
||||
&mut self.main_abs_trail_points,
|
||||
*entity,
|
||||
true,
|
||||
*pos,
|
||||
*tools,
|
||||
);
|
||||
handle_weapon_trails(
|
||||
trail_mgr,
|
||||
offsets.off_weapon_trail_mat,
|
||||
&mut self.off_abs_trail_points,
|
||||
*entity,
|
||||
false,
|
||||
*pos,
|
||||
*tools,
|
||||
);
|
||||
}
|
||||
self.abs_trail_points = offsets_abs_trail_points;
|
||||
|
||||
// TODO: compute the mount bone only when it is needed
|
||||
self.mount_transform = offsets.mount_bone;
|
||||
|
@ -49,7 +49,8 @@ impl anim::Skeleton for VolumeKey {
|
||||
anim::Offsets {
|
||||
lantern: None,
|
||||
mount_bone: anim::vek::Transform::default(),
|
||||
weapon_trail_mat: None,
|
||||
main_weapon_trail_mat: None,
|
||||
off_weapon_trail_mat: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,19 @@
|
||||
use super::SceneData;
|
||||
use crate::render::{DynamicModel, Mesh, Quad, Renderer, TrailDrawer, TrailVertex};
|
||||
use common::comp::CharacterState;
|
||||
use common_base::span;
|
||||
use specs::{Entity as EcsEntity, Join, WorldExt};
|
||||
use specs::Entity as EcsEntity;
|
||||
use std::collections::HashMap;
|
||||
// use vek::*;
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
|
||||
struct MeshKey {
|
||||
entity: EcsEntity,
|
||||
is_main_weapon: bool,
|
||||
}
|
||||
|
||||
pub struct TrailMgr {
|
||||
/// Meshes for each entity
|
||||
pub entity_meshes: HashMap<EcsEntity, Mesh<TrailVertex>>,
|
||||
entity_meshes: HashMap<MeshKey, Mesh<TrailVertex>>,
|
||||
|
||||
/// Offset
|
||||
pub offset: usize,
|
||||
@ -47,7 +52,8 @@ impl TrailMgr {
|
||||
// Verts per quad are in b, c, a, d order
|
||||
vertices[i * 4 + 2] = vertices[i * 4 + 2] * TRAIL_SHRINKAGE
|
||||
+ vertices[i * 4] * (1.0 - TRAIL_SHRINKAGE);
|
||||
if i != (self.offset + TRAIL_DYNAMIC_MODEL_SIZE - 1) % TRAIL_DYNAMIC_MODEL_SIZE {
|
||||
if i != (self.offset + TRAIL_DYNAMIC_MODEL_SIZE - 1) % TRAIL_DYNAMIC_MODEL_SIZE
|
||||
{
|
||||
// Avoid shrinking edge of most recent quad so that edges of quads align
|
||||
vertices[i * 4 + 3] = vertices[i * 4 + 3] * TRAIL_SHRINKAGE
|
||||
+ vertices[i * 4 + 1] * (1.0 - TRAIL_SHRINKAGE);
|
||||
@ -59,26 +65,9 @@ impl TrailMgr {
|
||||
mesh.replace_quad(self.offset * 4, Quad::new(zero, zero, zero, zero));
|
||||
});
|
||||
|
||||
// Create a mesh for each entity that doesn't already have one
|
||||
let ecs = scene_data.state.ecs();
|
||||
for (entity, _char_state) in
|
||||
(&ecs.entities(), &ecs.read_storage::<CharacterState>()).join()
|
||||
{
|
||||
// Result returned doesn't matter, it just needs to only insert if entry didn't
|
||||
// already exist
|
||||
if let Ok(mesh) = self.entity_meshes.try_insert(entity, Mesh::new()) {
|
||||
// Allocate up to necessary length so repalce_quad works as expected elsewhere
|
||||
let zero = TrailVertex::zero();
|
||||
for _ in 0..TRAIL_DYNAMIC_MODEL_SIZE {
|
||||
mesh.push_quad(Quad::new(zero, zero, zero, zero));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear meshes for entities that no longer exist (is this even
|
||||
// necessary? not sure if this growing too big is a concern)
|
||||
// Clear meshes for entities that only have zero quads in mesh
|
||||
self.entity_meshes
|
||||
.retain(|entity, _| ecs.entities().is_alive(*entity));
|
||||
.retain(|_, mesh| mesh.iter().any(|vert| *vert != TrailVertex::zero()));
|
||||
|
||||
// Create dynamic model from currently existing meshes
|
||||
let mut big_mesh = Mesh::new();
|
||||
@ -111,4 +100,27 @@ impl TrailMgr {
|
||||
drawer.draw(&self.dynamic_model, self.model_len);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn entity_mesh_or_insert(
|
||||
&mut self,
|
||||
entity: EcsEntity,
|
||||
is_main_weapon: bool,
|
||||
) -> &mut Mesh<TrailVertex> {
|
||||
let key = MeshKey {
|
||||
entity,
|
||||
is_main_weapon,
|
||||
};
|
||||
self.entity_meshes
|
||||
.entry(key)
|
||||
.or_insert_with(Self::default_trail_mesh)
|
||||
}
|
||||
|
||||
fn default_trail_mesh() -> Mesh<TrailVertex> {
|
||||
let mut mesh = Mesh::new();
|
||||
let zero = TrailVertex::zero();
|
||||
for _ in 0..TRAIL_DYNAMIC_MODEL_SIZE {
|
||||
mesh.push_quad(Quad::new(zero, zero, zero, zero));
|
||||
}
|
||||
mesh
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user