rapier_viewport_plugin/
state.rs1use indexmap::IndexMap;
2
3use rapier3d::dynamics::{
4 CCDSolver, ImpulseJointSet, IntegrationParameters, IslandManager, MultibodyJointSet, RigidBody,
5 RigidBodyHandle, RigidBodySet,
6};
7use rapier3d::geometry::{
8 BroadPhaseBvh, Collider, ColliderHandle, ColliderSet, NarrowPhase,
9};
10use rapier3d::math::Vector;
11use rapier3d::pipeline::PhysicsPipeline;
12use viewport_lib::NodeId;
13
14pub struct RapierState {
32 pub integration_params: IntegrationParameters,
33 pub pipeline: PhysicsPipeline,
34 pub islands: IslandManager,
35 pub broad_phase: BroadPhaseBvh,
36 pub narrow_phase: NarrowPhase,
37 pub bodies: RigidBodySet,
38 pub colliders: ColliderSet,
39 pub impulse_joints: ImpulseJointSet,
40 pub multibody_joints: MultibodyJointSet,
41 pub ccd_solver: CCDSolver,
42 pub gravity: Vector,
43
44 pub node_to_body: IndexMap<NodeId, RigidBodyHandle>,
45 pub body_to_node: IndexMap<RigidBodyHandle, NodeId>,
46 pub node_to_collider: IndexMap<NodeId, ColliderHandle>,
47 pub collider_to_node: IndexMap<ColliderHandle, NodeId>,
48}
49
50impl RapierState {
51 pub fn new(gravity: Vector) -> Self {
52 Self {
53 integration_params: IntegrationParameters::default(),
54 pipeline: PhysicsPipeline::new(),
55 islands: IslandManager::new(),
56 broad_phase: BroadPhaseBvh::new(),
57 narrow_phase: NarrowPhase::new(),
58 bodies: RigidBodySet::new(),
59 colliders: ColliderSet::new(),
60 impulse_joints: ImpulseJointSet::new(),
61 multibody_joints: MultibodyJointSet::new(),
62 ccd_solver: CCDSolver::new(),
63 gravity,
64 node_to_body: IndexMap::new(),
65 body_to_node: IndexMap::new(),
66 node_to_collider: IndexMap::new(),
67 collider_to_node: IndexMap::new(),
68 }
69 }
70
71 pub fn add_body(&mut self, node_id: NodeId, body: RigidBody, collider: Collider) {
75 let body_handle = self.bodies.insert(body);
76 let collider_handle =
77 self.colliders
78 .insert_with_parent(collider, body_handle, &mut self.bodies);
79 self.node_to_body.insert(node_id, body_handle);
80 self.body_to_node.insert(body_handle, node_id);
81 self.node_to_collider.insert(node_id, collider_handle);
82 self.collider_to_node.insert(collider_handle, node_id);
83 }
84
85 pub fn remove_body(&mut self, node_id: NodeId) {
92 let Some(body_handle) = self.node_to_body.shift_remove(&node_id) else {
93 return;
94 };
95 self.body_to_node.shift_remove(&body_handle);
96
97 if let Some(collider_handle) = self.node_to_collider.shift_remove(&node_id) {
98 self.collider_to_node.shift_remove(&collider_handle);
99 }
100
101 self.bodies.remove(
102 body_handle,
103 &mut self.islands,
104 &mut self.colliders,
105 &mut self.impulse_joints,
106 &mut self.multibody_joints,
107 true,
108 );
109 }
110
111 pub fn clear_bodies(&mut self) {
113 let ids: Vec<NodeId> = self.node_to_body.keys().copied().collect();
114 for id in ids {
115 self.remove_body(id);
116 }
117 }
118
119 pub fn node_for_collider(&self, handle: ColliderHandle) -> Option<NodeId> {
121 self.collider_to_node.get(&handle).copied()
122 }
123
124 pub fn node_for_body(&self, handle: RigidBodyHandle) -> Option<NodeId> {
126 self.body_to_node.get(&handle).copied()
127 }
128}