Added cart, notion of rolling resistance (hacky)

This commit is contained in:
Joshua Barretto 2023-05-26 22:27:31 +01:00
parent 9aa757cd09
commit 5a41d7e33e
9 changed files with 99 additions and 11 deletions

View File

@ -233,4 +233,40 @@
19: Air(Lantern, 4),
},
),
Cart: (
bone0: (
offset: (-3.5, -3.5, 0.5),
central: ("cart.structure"),
),
bone1: (
offset: (-1.0, -2.5, -1.0),
central: ("cart.axle"),
),
bone2: (
offset: (-1.0, -2.5, -1.0),
central: ("cart.axle"),
),
bone3: (
offset: (0.0, 0.0, 0.0),
central: ("empty"),
),
custom_indices: {
1: Air(ChairSingle, 4),
2: Air(Helm, 0),
3: Air(ChairSingle, 2),
4: Air(ChairSingle, 6),
9: Air(CraftingBench, 0),
10: Air(Window1, 0),
11: Air(RepairBench, 0),
12: Air(DismantlingBench, 4),
13: Air(Window1, 2),
14: Air(Crate, 0),
15: Air(Cauldron, 2),
16: Air(ChairSingle, 0),
17: Air(CookingPot, 0),
18: Air(WallLampSmall, 4),
19: Air(Lantern, 4),
},
),
})

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

Binary file not shown.

BIN
assets/common/voxel/cart/structure.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1198,6 +1198,7 @@ impl Body {
ship::Body::Skiff => [1.0, -2.0, 2.0],
ship::Body::Submarine => [1.0, -2.0, 2.0],
ship::Body::Carriage => [1.0, -2.0, 2.0],
ship::Body::Cart => [1.0, -2.0, 2.0],
ship::Body::Volume => [0.0, 0.0, 0.0],
},
_ => [0.0, 0.0, 0.0],

View File

@ -19,12 +19,13 @@ pub const ALL_BODIES: [Body; 6] = [
];
pub const ALL_AIRSHIPS: [Body; 2] = [Body::DefaultAirship, Body::AirBalloon];
pub const ALL_SHIPS: [Body; 5] = [
pub const ALL_SHIPS: [Body; 6] = [
Body::SailBoat,
Body::Galleon,
Body::Skiff,
Body::Submarine,
Body::Carriage,
Body::Cart,
];
make_case_elim!(
@ -40,6 +41,7 @@ make_case_elim!(
Skiff = 5,
Submarine = 6,
Carriage = 7,
Cart = 8,
}
);
@ -72,6 +74,7 @@ impl Body {
Body::Skiff => Some("skiff.structure"),
Body::Submarine => Some("submarine.structure"),
Body::Carriage => Some("carriage.structure"),
Body::Cart => Some("cart.structure"),
Body::Volume => None,
}
}
@ -84,7 +87,8 @@ impl Body {
Body::Galleon => Vec3::new(14.0, 48.0, 10.0),
Body::Skiff => Vec3::new(7.0, 15.0, 10.0),
Body::Submarine => Vec3::new(2.0, 15.0, 8.0),
Body::Carriage => Vec3::new(6.0, 12.0, 8.0),
Body::Carriage => Vec3::new(5.0, 12.0, 2.0),
Body::Cart => Vec3::new(5.0, 8.0, 5.0),
}
}
@ -119,6 +123,7 @@ impl Body {
Body::DefaultAirship | Body::AirBalloon | Body::Volume => Density(AIR_DENSITY),
Body::Submarine => Density(WATER_DENSITY), // Neutrally buoyant
Body::Carriage => Density(WATER_DENSITY * 0.5),
Body::Cart => Density(AIR_DENSITY * 1.2),
_ => Density(AIR_DENSITY * 0.95 + WATER_DENSITY * 0.05), /* Most boats should be very
* buoyant */
}
@ -136,7 +141,7 @@ impl Body {
matches!(self, Body::SailBoat | Body::Galleon | Body::Skiff)
}
pub fn has_wheels(&self) -> bool { matches!(self, Body::Carriage) }
pub fn has_wheels(&self) -> bool { matches!(self, Body::Carriage | Body::Cart) }
pub fn make_collider(&self) -> Collider {
match self.manifest_entry() {

View File

@ -875,6 +875,8 @@ impl<'a> PhysicsData<'a> {
let (_, z_max) = collider.get_z_limits(scale);
let z_min = 0.0;
let body = read.bodies.get(entity);
let mut cpos = *pos;
let cylinder = (radius, z_min, z_max);
box_voxel_collision(
@ -894,6 +896,14 @@ impl<'a> PhysicsData<'a> {
},
read,
&ori,
|vel| if let Some(Body::Ship(ship)) = body && ship.has_wheels() {
vel
.try_normalized()
.and_then(|dir| Some(orientations.get(entity)?.right().dot(dir).abs()))
.unwrap_or(1.0)
} else {
1.0
},
);
tgt_pos = cpos.0;
},
@ -909,6 +919,8 @@ impl<'a> PhysicsData<'a> {
let z_min = 0.0;
let z_max = z_max.clamped(1.2, 1.95) * scale;
let body = read.bodies.get(entity);
let cylinder = (radius, z_min, z_max);
let mut cpos = *pos;
box_voxel_collision(
@ -928,6 +940,14 @@ impl<'a> PhysicsData<'a> {
},
read,
&ori,
|vel| if let Some(Body::Ship(ship)) = body && ship.has_wheels() {
vel
.try_normalized()
.and_then(|dir| Some(1.0 - orientations.get(entity)?.right().dot(dir).abs()))
.unwrap_or(1.0)
} else {
1.0
},
);
// Sticky things shouldn't move when on a surface
@ -1191,6 +1211,8 @@ impl<'a> PhysicsData<'a> {
vel.0 = previous_cache_other.ori.inverse()
* (vel.0 - vel_other);
let body = read.bodies.get(entity);
// Perform collision resolution
box_voxel_collision(
(radius, z_min, z_max),
@ -1214,6 +1236,14 @@ impl<'a> PhysicsData<'a> {
},
read,
&ori,
|vel| if let Some(Body::Ship(ship)) = body && ship.has_wheels() {
(previous_cache_other.ori * vel)
.try_normalized()
.and_then(|dir| Some(1.0 - orientations.get(entity)?.right().dot(dir).abs()))
.unwrap_or(1.0)
} else {
1.0
},
);
// Transform entity attributes back into world space now
@ -1433,6 +1463,8 @@ fn box_voxel_collision<T: BaseVol<Vox = Block> + ReadVol>(
mut land_on_ground: impl FnMut(Entity, Vel, Vec3<f32>),
read: &PhysicsRead,
ori: &Ori,
// Get the proportion of surface friction that should be applied based on the current velocity
friction_factor: impl Fn(Vec3<f32>) -> f32,
) {
// We cap out scale at 10.0 to prevent an enormous amount of lag
let scale = read.scales.get(entity).map_or(1.0, |s| s.0.min(10.0));
@ -1905,7 +1937,8 @@ fn box_voxel_collision<T: BaseVol<Vox = Block> + ReadVol>(
} * physics_state
.on_ground
.map(|b| b.get_friction())
.unwrap_or(0.0);
.unwrap_or(0.0)
* friction_factor(vel.0);
let wall_fric = if physics_state.on_wall.is_some() && climbing {
FRIC_GROUND
} else {

View File

@ -79,9 +79,11 @@ impl<'a> System<'a> for Sys {
})
.unwrap_or_default();
let tether_pos = follower_pos.0 + tether_offset;
let pull_factor =
(leader_pos.0.distance(tether_pos) - is_follower.tether_length).clamp(0.0, 1.0);
let strength = pull_factor * 30000.0;
let pull_factor = ((leader_pos.0.distance(tether_pos) - is_follower.tether_length)
* 0.5)
.clamp(0.0, 1.0)
.powf(2.0);
let strength = pull_factor * 50000.0;
let pull_dir = (leader_pos.0 - follower_pos.0)
.try_normalized()
.unwrap_or_default();

View File

@ -1630,7 +1630,7 @@ fn handle_spawn(
.link(Tethered {
leader,
follower,
tether_length: 4.0,
tether_length: 3.0,
})
.map_err(|_| "Failed to tether entities")?;
} else {
@ -1824,7 +1824,7 @@ fn handle_spawn_ship(
.link(Tethered {
leader,
follower,
tether_length: 6.0,
tether_length: 3.0,
})
.map_err(|_| "Failed to tether entities")?;
} else {

View File

@ -116,6 +116,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
Skiff => (0.0, 0.0, 0.0),
Submarine => (0.0, 0.0, 0.0),
Carriage => (0.0, 0.0, 0.0),
Cart => (0.0, 0.0, 0.0),
Volume => (0.0, 0.0, 0.0),
},
bone1: match body {
@ -126,6 +127,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
Skiff => (0.0, 0.0, 0.0),
Submarine => (0.0, -15.0, 3.5),
Carriage => (0.0, 3.0, 2.0),
Cart => (0.0, 1.0, 1.0),
Volume => (0.0, 0.0, 0.0),
},
bone2: match body {
@ -136,6 +138,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
Skiff => (0.0, 0.0, 0.0),
Submarine => (0.0, 0.0, 0.0),
Carriage => (0.0, -3.0, 2.0),
Cart => (0.0, -2.5, 1.0),
Volume => (0.0, 0.0, 0.0),
},
bone3: match body {
@ -146,18 +149,20 @@ impl<'a> From<&'a Body> for SkeletonAttr {
Skiff => (0.0, 0.0, 0.0),
Submarine => (0.0, -18.0, 3.5),
Carriage => (0.0, 0.0, 0.0),
Cart => (0.0, 0.0, 0.0),
Volume => (0.0, 0.0, 0.0),
},
bone1_ori: match body {
Carriage => std::f32::consts::PI * 0.5,
Carriage | Cart => std::f32::consts::PI * 0.5,
_ => 0.0,
},
bone2_ori: match body {
Carriage => std::f32::consts::PI * -0.5,
Carriage | Cart => std::f32::consts::PI * -0.5,
_ => 0.0,
},
bone_rotation_rate: match body {
Carriage => 0.25,
Cart => 0.4,
_ => 0.8,
},
bone1_prop_trail_offset: match body {