mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'zesterer/small-fixes' into 'master'
Fixed handling of orientation changes for airships See merge request veloren/veloren!2640
This commit is contained in:
commit
1501f0467e
@ -84,7 +84,7 @@ pub use self::{
|
||||
misc::Object,
|
||||
ori::Ori,
|
||||
phys::{
|
||||
Collider, Density, ForceUpdate, Mass, PhysicsState, Pos, PosVelDefer, PreviousPhysCache,
|
||||
Collider, Density, ForceUpdate, Mass, PhysicsState, Pos, PosVelOriDefer, PreviousPhysCache,
|
||||
Scale, Sticky, Vel,
|
||||
},
|
||||
player::DisconnectReason,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::Fluid;
|
||||
use super::{Fluid, Ori};
|
||||
use crate::{consts::WATER_DENSITY, terrain::Block, uid::Uid};
|
||||
use hashbrown::HashSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -31,12 +31,13 @@ impl Component for Vel {
|
||||
|
||||
/// Used to defer writes to Pos/Vel in nested join loops
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct PosVelDefer {
|
||||
pub struct PosVelOriDefer {
|
||||
pub pos: Option<Pos>,
|
||||
pub vel: Option<Vel>,
|
||||
pub ori: Option<Ori>,
|
||||
}
|
||||
|
||||
impl Component for PosVelDefer {
|
||||
impl Component for PosVelOriDefer {
|
||||
// TODO: why not regular vec storage????
|
||||
type Storage = IdvStorage<Self>;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ impl State {
|
||||
|
||||
// Register common unsynced components
|
||||
ecs.register::<comp::PreviousPhysCache>();
|
||||
ecs.register::<comp::PosVelDefer>();
|
||||
ecs.register::<comp::PosVelOriDefer>();
|
||||
|
||||
// Register client-local components
|
||||
// TODO: only register on the client
|
||||
|
@ -3,7 +3,7 @@ use common::{
|
||||
body::ship::figuredata::{VoxelCollider, VOXEL_COLLIDER_MANIFEST},
|
||||
fluid_dynamics::{Fluid, LiquidKind, Wings},
|
||||
BeamSegment, Body, CharacterState, Collider, Density, Mass, Mounting, Ori, PhysicsState,
|
||||
Pos, PosVelDefer, PreviousPhysCache, Projectile, Scale, Shockwave, Stats, Sticky, Vel,
|
||||
Pos, PosVelOriDefer, PreviousPhysCache, Projectile, Scale, Shockwave, Stats, Sticky, Vel,
|
||||
},
|
||||
consts::{AIR_DENSITY, FRIC_GROUND, GRAVITY},
|
||||
event::{EventBus, ServerEvent},
|
||||
@ -134,7 +134,7 @@ pub struct PhysicsWrite<'a> {
|
||||
physics_states: WriteStorage<'a, PhysicsState>,
|
||||
positions: WriteStorage<'a, Pos>,
|
||||
velocities: WriteStorage<'a, Vel>,
|
||||
pos_vel_defers: WriteStorage<'a, PosVelDefer>,
|
||||
pos_vel_ori_defers: WriteStorage<'a, PosVelOriDefer>,
|
||||
orientations: WriteStorage<'a, Ori>,
|
||||
previous_phys_cache: WriteStorage<'a, PreviousPhysCache>,
|
||||
outcomes: Write<'a, Vec<Outcome>>,
|
||||
@ -537,27 +537,29 @@ impl<'a> PhysicsData<'a> {
|
||||
ref mut write,
|
||||
} = self;
|
||||
|
||||
prof_span!(guard, "insert PosVelDefer");
|
||||
prof_span!(guard, "insert PosVelOriDefer");
|
||||
// NOTE: keep in sync with join below
|
||||
(
|
||||
&read.entities,
|
||||
read.colliders.mask(),
|
||||
&write.positions,
|
||||
&write.velocities,
|
||||
&write.orientations,
|
||||
write.orientations.mask(),
|
||||
write.physics_states.mask(),
|
||||
!&write.pos_vel_defers, // This is the one we are adding
|
||||
!&write.pos_vel_ori_defers, // This is the one we are adding
|
||||
write.previous_phys_cache.mask(),
|
||||
!&read.mountings,
|
||||
)
|
||||
.join()
|
||||
.map(|t| (t.0, *t.2, *t.3))
|
||||
.map(|t| (t.0, *t.2, *t.3, *t.4))
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
.for_each(|(entity, pos, vel)| {
|
||||
let _ = write.pos_vel_defers.insert(entity, PosVelDefer {
|
||||
.for_each(|(entity, pos, vel, ori)| {
|
||||
let _ = write.pos_vel_ori_defers.insert(entity, PosVelOriDefer {
|
||||
pos: Some(pos),
|
||||
vel: Some(vel),
|
||||
ori: Some(ori),
|
||||
});
|
||||
});
|
||||
drop(guard);
|
||||
@ -658,6 +660,20 @@ impl<'a> PhysicsData<'a> {
|
||||
|
||||
// Third pass: resolve collisions for non-terrain-like entities
|
||||
Self::resolve_et_collision(job, read, write, voxel_collider_spatial_grid, false);
|
||||
|
||||
// Update cached 'old' physics values to the current values ready for the next
|
||||
// tick
|
||||
prof_span!(guard, "record ori into phys_cache");
|
||||
for (ori, previous_phys_cache, _) in (
|
||||
&write.orientations,
|
||||
&mut write.previous_phys_cache,
|
||||
&read.colliders,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
previous_phys_cache.ori = ori.to_quat();
|
||||
}
|
||||
drop(guard);
|
||||
}
|
||||
|
||||
fn resolve_et_collision(
|
||||
@ -686,7 +702,7 @@ impl<'a> PhysicsData<'a> {
|
||||
read.bodies.maybe(),
|
||||
read.character_states.maybe(),
|
||||
&mut write.physics_states,
|
||||
&mut write.pos_vel_defers,
|
||||
&mut write.pos_vel_ori_defers,
|
||||
previous_phys_cache,
|
||||
!&read.mountings,
|
||||
)
|
||||
@ -705,20 +721,22 @@ impl<'a> PhysicsData<'a> {
|
||||
collider,
|
||||
pos,
|
||||
vel,
|
||||
_ori,
|
||||
ori,
|
||||
body,
|
||||
character_state,
|
||||
mut physics_state,
|
||||
pos_vel_defer,
|
||||
pos_vel_ori_defer,
|
||||
_previous_cache,
|
||||
_,
|
||||
)| {
|
||||
let mut land_on_ground = None;
|
||||
let mut outcomes = Vec::new();
|
||||
// Defer the writes of positions and velocities to allow an inner loop over
|
||||
// terrain-like entities
|
||||
// Defer the writes of positions, velocities and orientations to allow an inner
|
||||
// loop over terrain-like entities
|
||||
let old_vel = *vel;
|
||||
let mut vel = *vel;
|
||||
let old_ori = *ori;
|
||||
let mut ori = *ori;
|
||||
|
||||
let scale = if let Collider::Voxel { .. } = collider {
|
||||
scale.map(|s| s.0).unwrap_or(1.0)
|
||||
@ -1028,16 +1046,17 @@ impl<'a> PhysicsData<'a> {
|
||||
|
||||
// The velocity of the collider, taking into account
|
||||
// orientation.
|
||||
let wpos_rel = (Mat4::<f32>::translation_3d(pos_other.0)
|
||||
let pos_rel = (Mat4::<f32>::translation_3d(Vec3::zero())
|
||||
* Mat4::from(ori_other.to_quat())
|
||||
* Mat4::<f32>::translation_3d(voxel_collider.translation))
|
||||
.inverted()
|
||||
.mul_point(wpos);
|
||||
let wpos_last = (Mat4::<f32>::translation_3d(pos_other.0)
|
||||
.mul_point(wpos - pos_other.0);
|
||||
let rpos_last = (Mat4::<f32>::translation_3d(Vec3::zero())
|
||||
* Mat4::from(previous_cache_other.ori)
|
||||
* Mat4::<f32>::translation_3d(voxel_collider.translation))
|
||||
.mul_point(wpos_rel);
|
||||
let vel_other = vel_other.0 + (wpos - wpos_last) / read.dt.0;
|
||||
.mul_point(pos_rel);
|
||||
let vel_other = vel_other.0
|
||||
+ (wpos - (pos_other.0 + rpos_last)) / read.dt.0;
|
||||
|
||||
cpos.0 = transform_to.mul_point(Vec3::zero());
|
||||
vel.0 = ori_to.mul_direction(vel.0 - vel_other);
|
||||
@ -1071,6 +1090,12 @@ impl<'a> PhysicsData<'a> {
|
||||
// recent terrain that collision was attempted with
|
||||
if physics_state_delta.on_ground.is_some() {
|
||||
physics_state.ground_vel = vel_other;
|
||||
|
||||
// Rotate if on ground
|
||||
ori = ori.rotated(
|
||||
ori_other.to_quat()
|
||||
* previous_cache_other.ori.inverse(),
|
||||
);
|
||||
}
|
||||
physics_state.on_ground =
|
||||
physics_state.on_ground.or(physics_state_delta.on_ground);
|
||||
@ -1102,15 +1127,19 @@ impl<'a> PhysicsData<'a> {
|
||||
);
|
||||
|
||||
if tgt_pos != pos.0 {
|
||||
pos_vel_defer.pos = Some(Pos(tgt_pos));
|
||||
pos_vel_ori_defer.pos = Some(Pos(tgt_pos));
|
||||
} else {
|
||||
pos_vel_defer.pos = None;
|
||||
pos_vel_ori_defer.pos = None;
|
||||
}
|
||||
|
||||
if vel != old_vel {
|
||||
pos_vel_defer.vel = Some(vel);
|
||||
pos_vel_ori_defer.vel = Some(vel);
|
||||
} else {
|
||||
pos_vel_defer.vel = None;
|
||||
pos_vel_ori_defer.vel = None;
|
||||
}
|
||||
if ori != old_ori {
|
||||
pos_vel_ori_defer.ori = Some(ori);
|
||||
} else {
|
||||
pos_vel_ori_defer.ori = None;
|
||||
}
|
||||
|
||||
(land_on_ground, outcomes)
|
||||
@ -1139,35 +1168,26 @@ impl<'a> PhysicsData<'a> {
|
||||
write.outcomes.append(&mut outcomes);
|
||||
|
||||
prof_span!(guard, "write deferred pos and vel");
|
||||
for (_, pos, vel, pos_vel_defer, _) in (
|
||||
for (_, pos, vel, ori, pos_vel_ori_defer, _) in (
|
||||
&read.entities,
|
||||
&mut write.positions,
|
||||
&mut write.velocities,
|
||||
&mut write.pos_vel_defers,
|
||||
&mut write.orientations,
|
||||
&mut write.pos_vel_ori_defers,
|
||||
&read.colliders,
|
||||
)
|
||||
.join()
|
||||
.filter(|tuple| matches!(tuple.4, Collider::Voxel { .. }) == terrain_like_entities)
|
||||
.filter(|tuple| matches!(tuple.5, Collider::Voxel { .. }) == terrain_like_entities)
|
||||
{
|
||||
if let Some(new_pos) = pos_vel_defer.pos.take() {
|
||||
if let Some(new_pos) = pos_vel_ori_defer.pos.take() {
|
||||
*pos = new_pos;
|
||||
}
|
||||
if let Some(new_vel) = pos_vel_defer.vel.take() {
|
||||
if let Some(new_vel) = pos_vel_ori_defer.vel.take() {
|
||||
*vel = new_vel;
|
||||
}
|
||||
if let Some(new_ori) = pos_vel_ori_defer.ori.take() {
|
||||
*ori = new_ori;
|
||||
}
|
||||
drop(guard);
|
||||
|
||||
prof_span!(guard, "record ori into phys_cache");
|
||||
for (ori, previous_phys_cache, _) in (
|
||||
&write.orientations,
|
||||
&mut write.previous_phys_cache,
|
||||
&read.colliders,
|
||||
)
|
||||
.join()
|
||||
.filter(|tuple| matches!(tuple.2, Collider::Voxel { .. }) == terrain_like_entities)
|
||||
{
|
||||
previous_phys_cache.ori = ori.to_quat();
|
||||
}
|
||||
drop(guard);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user