Better orientation, axels

This commit is contained in:
Joshua Barretto 2023-05-24 23:21:00 +01:00
parent 6a2796dc17
commit f986e0793d
13 changed files with 70 additions and 35 deletions

View File

@ -199,16 +199,16 @@
),
Carriage: (
bone0: (
offset: (-4.5, -6.5, -0.5),
offset: (-4.5, -7.0, -0.5),
central: ("carriage.structure"),
),
bone1: (
offset: (0.0, 0.0, 0.0),
central: ("empty"),
offset: (-2.0, -5.0, -2.0),
central: ("carriage.axle"),
),
bone2: (
offset: (0.0, 0.0, 0.0),
central: ("empty"),
offset: (-2.0, -5.0, -2.0),
central: ("carriage.axle"),
),
bone3: (
offset: (0.0, 0.0, 0.0),

BIN
assets/common/voxel/carriage/axle.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/common/voxel/carriage/prop.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/common/voxel/carriage/rudder.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/common/voxel/carriage/structure.vox (Stored with Git LFS)

Binary file not shown.

View File

@ -19,7 +19,13 @@ pub const ALL_BODIES: [Body; 6] = [
];
pub const ALL_AIRSHIPS: [Body; 2] = [Body::DefaultAirship, Body::AirBalloon];
pub const ALL_SHIPS: [Body; 5] = [Body::SailBoat, Body::Galleon, Body::Skiff, Body::Submarine, Body::Carriage];
pub const ALL_SHIPS: [Body; 5] = [
Body::SailBoat,
Body::Galleon,
Body::Skiff,
Body::Submarine,
Body::Carriage,
];
make_case_elim!(
body,
@ -114,7 +120,7 @@ impl Body {
Body::Submarine => Density(WATER_DENSITY), // Neutrally buoyant
Body::Carriage => Density(WATER_DENSITY * 0.5),
_ => Density(AIR_DENSITY * 0.95 + WATER_DENSITY * 0.05), /* Most boats should be very
* buoyant */
* buoyant */
}
}
@ -130,6 +136,8 @@ impl Body {
!self.can_fly() && !matches!(self, Body::Carriage) // TODO: Differentiate this more carefully
}
pub fn has_wheels(&self) -> bool { matches!(self, Body::Carriage) }
pub fn make_collider(&self) -> Collider {
match self.manifest_entry() {
Some(manifest_entry) => Collider::Voxel {

View File

@ -63,7 +63,6 @@ pub struct PreviousPhysCache {
pub origins: Option<(Vec2<f32>, Vec2<f32>)>,
pub pos: Option<Pos>,
pub ori: Quaternion<f32>,
pub pos_interp: Option<Pos>,
}
impl Component for PreviousPhysCache {

View File

@ -5,8 +5,8 @@ use crate::{
item::{tool::AbilityMap, MaterialStatManifest},
ActiveAbilities, Beam, Body, CharacterActivity, CharacterState, Combo, ControlAction,
Controller, ControllerInputs, Density, Energy, Health, InputAttr, InputKind, Inventory,
InventoryAction, Mass, Melee, Ori, PhysicsState, Pos, Scale, SkillSet, Stance, StateUpdate,
Stats, Vel, PreviousPhysCache,
InventoryAction, Mass, Melee, Ori, PhysicsState, Pos, PreviousPhysCache, Scale, SkillSet,
Stance, StateUpdate, Stats, Vel,
},
link::Is,
mounting::{Rider, VolumeRider},

View File

@ -21,7 +21,7 @@ use crate::{
event::{LocalEvent, ServerEvent},
outcome::Outcome,
states::{behavior::JoinData, utils::CharacterState::Idle, *},
terrain::{TerrainGrid, UnlockKind},
terrain::{Block, TerrainGrid, UnlockKind},
util::Dir,
vol::ReadVol,
};
@ -146,7 +146,7 @@ impl Body {
quadruped_low::Species::Deadwood => 140.0,
quadruped_low::Species::Mossdrake => 100.0,
},
Body::Ship(ship::Body::Carriage) => 350.0,
Body::Ship(ship::Body::Carriage) => 200.0,
Body::Ship(_) => 0.0,
Body::Arthropod(arthropod) => match arthropod.species {
arthropod::Species::Tarantula => 135.0,
@ -221,7 +221,7 @@ impl Body {
quadruped_low::Species::Mossdrake => 1.7,
_ => 2.0,
},
Body::Ship(ship::Body::Carriage) => 0.6,
Body::Ship(ship::Body::Carriage) => 0.04,
Body::Ship(ship) if ship.has_water_thrust() => 5.0 / self.dimensions().y,
Body::Ship(_) => 6.0 / self.dimensions().y,
Body::Arthropod(_) => 3.5,
@ -589,11 +589,26 @@ pub fn handle_orientation(
(a.to_quat().into_vec4() - b.to_quat().into_vec4()).reduce(|a, b| a.abs() + b.abs())
}
let pitch = if matches!(data.body, Body::Ship(ship::Body::Carriage)) {
let change = (data.pos.0 - data.previous_physics.and_then(|p| p.pos_interp).unwrap_or(*data.pos).0) / data.dt.0;
change.z / change.xy().magnitude().max(1.0)
let (tilt_ori, efficiency) = if let Body::Ship(ship) = data.body && ship.has_wheels() && data.physics.on_ground.is_some() {
let height_at = |rpos| data
.terrain
.ray(
data.pos.0 + rpos + Vec3::unit_z() * 4.0,
data.pos.0 + rpos - Vec3::unit_z() * 4.0,
)
.until(Block::is_solid)
.cast()
.0;
let x_diff = (height_at(data.ori.to_horizontal().right().to_vec() * 3.0) - height_at(data.ori.to_horizontal().right().to_vec() * -3.0)) / 10.0;
let y_diff = (height_at(data.ori.to_horizontal().look_dir().to_vec() * -4.5) - height_at(data.ori.to_horizontal().look_dir().to_vec() * 4.5)) / 10.0;
(
Quaternion::rotation_y(x_diff.atan()) * Quaternion::rotation_x(y_diff.atan()),
(data.vel.0 - data.physics.ground_vel).dot(data.ori.to_horizontal().look_dir().to_vec()).max(3.0) * efficiency,
)
} else {
0.0
(Quaternion::identity(), efficiency)
};
// Direction is set to the override if one is provided, else if entity is
@ -611,7 +626,7 @@ pub fn handle_orientation(
Dir::from_unnormalized(data.inputs.move_dir.into())
.map_or_else(|| to_horizontal_fast(data.ori), |dir| dir.into())
}
.pitched_up(pitch);
.rotated(tilt_ori);
// unit is multiples of 180°
let half_turns_per_tick = data.body.base_ori_rate() / data.scale.map_or(1.0, |s| s.0.sqrt())
* efficiency

View File

@ -10,7 +10,7 @@ use common::{
inventory::item::{tool::AbilityMap, MaterialStatManifest},
ActiveAbilities, Beam, Body, CharacterActivity, CharacterState, Combo, Controller, Density,
Energy, Health, Inventory, InventoryManip, Mass, Melee, Ori, PhysicsState, Poise, Pos,
Scale, SkillSet, Stance, StateUpdate, Stats, Vel, PreviousPhysCache,
PreviousPhysCache, Scale, SkillSet, Stance, StateUpdate, Stats, Vel,
},
event::{EventBus, LocalEvent, ServerEvent},
link::Is,

View File

@ -218,7 +218,6 @@ impl<'a> PhysicsData<'a> {
origins: None,
pos: None,
ori: Quaternion::identity(),
pos_interp: None,
});
}
@ -745,9 +744,6 @@ impl<'a> PhysicsData<'a> {
// it did not work (investigate root cause?)
previous_phys_cache.pos = Some(*pos);
previous_phys_cache.ori = ori.to_quat();
previous_phys_cache.pos_interp = Some(Pos(
previous_phys_cache.pos_interp.unwrap_or(*pos).0 * 0.85 + pos.0 * 0.15,
));
}
drop(guard);
}

View File

@ -45,10 +45,12 @@ impl Animation for IdleAnimation {
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2);
next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2);
next.bone1.orientation = Quaternion::rotation_y(acc_vel * 0.8);
next.bone1.orientation = Quaternion::rotation_z(s_a.bone1_ori)
* Quaternion::rotation_y(acc_vel * s_a.bone_rotation_rate);
next.bone2.position = Vec3::new(s_a.bone2.0, s_a.bone2.1, s_a.bone2.2);
next.bone2.orientation = Quaternion::rotation_y(-acc_vel * 0.8);
next.bone2.orientation = Quaternion::rotation_z(s_a.bone2_ori)
* Quaternion::rotation_y(-acc_vel * s_a.bone_rotation_rate);
next.bone3.position = Vec3::new(s_a.bone3.0, s_a.bone3.1, s_a.bone3.2);
next.bone3.orientation = Quaternion::rotation_z(tilt * 25.0);

View File

@ -70,6 +70,9 @@ pub struct SkeletonAttr {
bone1: (f32, f32, f32),
bone2: (f32, f32, f32),
bone3: (f32, f32, f32),
bone1_ori: f32,
bone2_ori: f32,
bone_rotation_rate: f32,
bone1_prop_trail_offset: Option<f32>,
bone2_prop_trail_offset: Option<f32>,
}
@ -92,6 +95,9 @@ impl Default for SkeletonAttr {
bone1: (0.0, 0.0, 0.0),
bone2: (0.0, 0.0, 0.0),
bone3: (0.0, 0.0, 0.0),
bone1_ori: 0.0,
bone2_ori: 0.0,
bone_rotation_rate: 0.0,
bone1_prop_trail_offset: None,
bone2_prop_trail_offset: None,
}
@ -119,7 +125,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
Galleon => (0.0, 0.0, 0.0),
Skiff => (0.0, 0.0, 0.0),
Submarine => (0.0, -15.0, 3.5),
Carriage => (0.0, 0.0, 0.0),
Carriage => (0.0, 3.0, 2.0),
Volume => (0.0, 0.0, 0.0),
},
bone2: match body {
@ -129,7 +135,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
Galleon => (0.0, 0.0, 0.0),
Skiff => (0.0, 0.0, 0.0),
Submarine => (0.0, 0.0, 0.0),
Carriage => (0.0, 0.0, 0.0),
Carriage => (0.0, -3.0, 2.0),
Volume => (0.0, 0.0, 0.0),
},
bone3: match body {
@ -142,6 +148,18 @@ impl<'a> From<&'a Body> for SkeletonAttr {
Carriage => (0.0, 0.0, 0.0),
Volume => (0.0, 0.0, 0.0),
},
bone1_ori: match body {
Carriage => std::f32::consts::PI * 0.5,
_ => 0.0,
},
bone2_ori: match body {
Carriage => std::f32::consts::PI * -0.5,
_ => 0.0,
},
bone_rotation_rate: match body {
Carriage => 0.25,
_ => 0.8,
},
bone1_prop_trail_offset: match body {
DefaultAirship => Some(8.5),
Submarine => Some(3.5),