feat(physics): collision resolution + proximity queries (P2)
Implement the kinematic physics & collision layer per ARCH-7 (no physics engine; distance-based collision + spatial queries). physics/ - components.rs (new): BodyMass, ProximitySensor, CollisionEvent, ProximityEvent - geometry.rs: add sphere_overlap() + split_by_inverse_mass() with unit tests - systems.rs: collision pipeline (detect_collisions -> resolve_collisions) with mass-weighted separation and inbound-velocity cancel, plus update_proximity_sensors spatial query and a log_physics_events observer. Core math factored into pure plan_collisions() with unit tests. - mod.rs: PhysicsPlugin registers events, FrameCollisions resource, and the InGame systems ordered after kinematic integration. in_system/scene.rs: give the player ship a BoundingVolume collider, BodyMass, and a ProximitySensor so it participates in collision and spatial queries. Bodies with a Velocity are movable; scenery is immovable. 19 unit tests pass; no new compiler/clippy warnings introduced.
This commit is contained in:
@@ -13,6 +13,7 @@ use crate::gameplay::galaxy::{
|
||||
SystemContents,
|
||||
};
|
||||
use crate::gameplay::in_system::DockedState;
|
||||
use crate::gameplay::physics::{BodyMass, ProximitySensor};
|
||||
|
||||
/// Tracks the currently active system for gameplay.
|
||||
#[derive(Resource, Debug, Clone, Default)]
|
||||
@@ -45,6 +46,16 @@ pub struct DockingTarget {
|
||||
/// Offset from station where player ship spawns when docked.
|
||||
const DOCKED_OFFSET: Vec3 = Vec3::new(1.5, 0.0, 0.0);
|
||||
|
||||
/// World-space collision radius for the player ship. Matches its scaled
|
||||
/// visual extent (a ~0.12-scale cuboid) so it cannot overlap stations,
|
||||
/// planets, or the star.
|
||||
const PLAYER_COLLIDER_RADIUS: f32 = 0.15;
|
||||
|
||||
/// World-space radius of the player ship's proximity sensor — the range at
|
||||
/// which nearby bodies (stations, belts, the star) register as in-range via
|
||||
/// `ProximityEvent`s.
|
||||
const PLAYER_SCAN_RADIUS: f32 = 8.0;
|
||||
|
||||
/// Represents a docking target (either a station or a habitable planet).
|
||||
#[derive(Debug, Clone)]
|
||||
struct DockingTargetInfo {
|
||||
@@ -352,6 +363,15 @@ fn spawn_player_ship_docked(
|
||||
Docked {
|
||||
station_entity: Entity::PLACEHOLDER, // Will be set when we find the actual station
|
||||
},
|
||||
// Physical presence: a collider for the collision pipeline and a
|
||||
// proximity sensor for spatial queries. `BodyMass` weights
|
||||
// ship-to-ship separation; the ship has no `Velocity` while docked
|
||||
// so the resolver treats it as immovable until undock.
|
||||
BoundingVolume {
|
||||
radius: PLAYER_COLLIDER_RADIUS,
|
||||
},
|
||||
BodyMass(1.0),
|
||||
ProximitySensor::new(PLAYER_SCAN_RADIUS),
|
||||
Transform::from_translation(ship_position).with_scale(Vec3::splat(0.12)),
|
||||
Visibility::default(),
|
||||
InheritedVisibility::default(),
|
||||
|
||||
Reference in New Issue
Block a user