Skip to main content

borger/
physics.rs

1use crate::tick::TickInfo;
2use crate::untracked::UntrackedState;
3use glam::Vec3;
4use rapier3d::prelude::*;
5use std::fmt::{Debug, Error, Formatter};
6
7///Wrapper around all types required to step the Rapier simulation.
8///Due to time constraints, the entire physics scene must be rebuilt
9///at the start of every tick. All rigid bodies are discarded at the
10///end of the tick. Will revisit someday to make this less awful.
11pub struct Physics {
12	///Resets every tick
13	pub integration_parameters: IntegrationParameters,
14	///Resets every tick
15	pub islands: IslandManager,
16	///Resets every tick
17	pub broad_phase: BroadPhaseBvh,
18	///Resets every tick
19	pub narrow_phase: NarrowPhase,
20	///Resets every tick
21	pub rigid_bodies: RigidBodySet,
22	///Resets every tick
23	pub colliders: ColliderSet,
24	///Resets every tick
25	pub impulse_joints: ImpulseJointSet,
26	///Resets every tick
27	pub multibody_joints: MultibodyJointSet,
28	///Resets every tick
29	pub ccd_solver: CCDSolver,
30
31	level_col_handle: Option<ColliderHandle>,
32}
33
34impl UntrackedState for Physics {
35	fn reset_untracked(&mut self) {
36		let level_col = self
37			.level_col_handle
38			.map(|level_col_handle| {
39				self.colliders
40					.remove(level_col_handle, &mut self.islands, &mut self.rigid_bodies, false)
41			})
42			.flatten();
43
44		self.integration_parameters = IntegrationParameters::default();
45		self.integration_parameters.dt = TickInfo::SIM_DT;
46
47		self.islands = IslandManager::new();
48		self.broad_phase = BroadPhaseBvh::new();
49		self.narrow_phase = NarrowPhase::new();
50		self.rigid_bodies = RigidBodySet::new();
51		self.colliders = ColliderSet::new();
52		self.impulse_joints = ImpulseJointSet::new();
53		self.multibody_joints = MultibodyJointSet::new();
54		self.ccd_solver = CCDSolver::new();
55
56		if let Some(level_col) = level_col {
57			self.level_col_handle = Some(self.colliders.insert(level_col));
58		}
59	}
60}
61
62impl Debug for Physics {
63	fn fmt(&self, _: &mut Formatter) -> Result<(), Error> {
64		Ok(())
65	}
66}
67
68impl Physics {
69	pub fn init_static_level_geom(&mut self, level_col: Collider) {
70		self.level_col_handle = Some(self.colliders.insert(level_col));
71	}
72
73	#[allow(unused)]
74	pub(crate) fn default() -> Self {
75		Self {
76			integration_parameters: IntegrationParameters::default(),
77			islands: IslandManager::new(),
78			broad_phase: BroadPhaseBvh::new(),
79			narrow_phase: NarrowPhase::new(),
80			rigid_bodies: RigidBodySet::new(),
81			colliders: ColliderSet::new(),
82			impulse_joints: ImpulseJointSet::new(),
83			multibody_joints: MultibodyJointSet::new(),
84			ccd_solver: CCDSolver::new(),
85
86			level_col_handle: None,
87		}
88	}
89
90	pub fn step(&mut self, gravity: Vec3, hooks: &dyn PhysicsHooks, events: &dyn EventHandler) {
91		PhysicsPipeline::new().step(
92			gravity,
93			&self.integration_parameters,
94			&mut self.islands,
95			&mut self.broad_phase,
96			&mut self.narrow_phase,
97			&mut self.rigid_bodies,
98			&mut self.colliders,
99			&mut self.impulse_joints,
100			&mut self.multibody_joints,
101			&mut self.ccd_solver,
102			hooks,
103			events,
104		);
105	}
106
107	pub fn query<'a>(&'a self, filter: QueryFilter<'a>) -> QueryPipeline<'a> {
108		self.broad_phase.as_query_pipeline(
109			self.narrow_phase.query_dispatcher(),
110			&self.rigid_bodies,
111			&self.colliders,
112			filter,
113		)
114	}
115}