Airship fixes: figure culling, player hitbox bounds w.r.t. airships, physics state unioning.

This commit is contained in:
Avi Weinstock 2021-03-11 19:01:16 -05:00
parent 5d85775dcf
commit bcd3799395
4 changed files with 31 additions and 7 deletions

View File

@ -2,7 +2,8 @@
DefaultAirship: (
bone0: (
//offset: (-20.0, -35.0, 1.0),
offset: (3.0, 7.0, 1.0),
//offset: (3.0, 7.0, 1.0),
offset: (0.25, 0.25, 0.25),
central: ("object.Human_Airship"),
),
bone1: (

View File

@ -1,7 +1,8 @@
use common::{
comp::{
BeamSegment, CharacterState, Collider, Gravity, Mass, Mounting, Ori, PhysicsState, Pos,
PreviousPhysCache, Projectile, Scale, Shockwave, Sticky, Vel, body::ship::figuredata::VOXEL_COLLIDER_MANIFEST,
body::ship::figuredata::VOXEL_COLLIDER_MANIFEST, BeamSegment, CharacterState, Collider,
Gravity, Mass, Mounting, Ori, PhysicsState, Pos, PreviousPhysCache, Projectile, Scale,
Shockwave, Sticky, Vel,
},
consts::{FRIC_GROUND, GRAVITY},
event::{EventBus, ServerEvent},
@ -592,9 +593,14 @@ impl<'a> PhysicsSystemData<'a> {
if let Collider::Voxel { id } = collider_other {
// use bounding cylinder regardless of our collider
// TODO: extract point-terrain collision above to its own function
let radius = collider.get_radius() * scale;
let (z_min, z_max) = collider.get_z_limits(scale);
let radius = collider.get_radius();
let (z_min, z_max) = collider.get_z_limits(1.0);
let radius = radius.min(0.45) * scale;
let z_min = z_min * scale;
let z_max = z_max.clamped(1.2, 1.95) * scale;
let mut physics_state_delta = physics_state.clone();
pos.0 -= pos_other.0;
let cylinder = (radius, z_min, z_max);
if let Some(dyna) = VOXEL_COLLIDER_MANIFEST.voxes.get(id) {
@ -605,11 +611,27 @@ impl<'a> PhysicsSystemData<'a> {
&mut pos,
pos_delta,
vel,
&mut physics_state,
&mut physics_state_delta,
&mut land_on_grounds,
);
}
pos.0 += pos_other.0;
// union in the state updates, so that the state isn't just based on
// the most recent terrain that collision was attempted with
physics_state.on_ground |= physics_state_delta.on_ground;
physics_state.on_ceiling |= physics_state_delta.on_ceiling;
physics_state.on_wall =
physics_state.on_wall.or(physics_state_delta.on_wall);
physics_state
.touch_entities
.append(&mut physics_state_delta.touch_entities);
physics_state.in_liquid =
match (physics_state.in_liquid, physics_state_delta.in_liquid) {
// this match computes `x <|> y <|> liftA2 max x y`
(Some(x), Some(y)) => Some(x.max(y)),
(_, y @ Some(_)) => y,
_ => None,
};
}
}
if pos != old_pos {

View File

@ -998,7 +998,7 @@ fn handle_spawn_airship(
server
.state
.create_ship(pos, comp::ship::Body::DefaultAirship, 1)
.with(comp::Scale(11.0))
.with(comp::Scale(11.0 / 0.8))
.with(LightEmitter {
col: Rgb::new(1.0, 0.65, 0.2),
strength: 2.0,

View File

@ -687,6 +687,7 @@ impl FigureMgr {
let (in_frustum, lpindex) = if let Some(mut meta) = state {
let (in_frustum, lpindex) = BoundingSphere::new(pos.0.into_array(), radius)
.coherent_test_against_frustum(frustum, meta.lpindex);
let in_frustum = in_frustum || matches!(body, Body::Ship(_));
meta.visible = in_frustum;
meta.lpindex = lpindex;
if in_frustum {