1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::physics;
use crate::physics::{
JointsEntityMap, ModificationTracker, PhysicsHooksWithQueryObject, RapierConfiguration,
SimulationToRenderTime,
};
use crate::prelude::IntersectionEvent;
use crate::rapier::geometry::ContactEvent;
use crate::rapier::pipeline::QueryPipeline;
use bevy::app::Events;
use bevy::ecs::query::WorldQuery;
use bevy::prelude::*;
use rapier::dynamics::{
CCDSolver, ImpulseJointSet, IntegrationParameters, IslandManager, MultibodyJointSet,
};
use rapier::geometry::{BroadPhase, NarrowPhase};
use rapier::pipeline::PhysicsPipeline;
use std::marker::PhantomData;
#[derive(Component)]
pub struct S;
pub type NoUserData<'a> = &'a S;
pub struct RapierPhysicsPlugin<UserData>(PhantomData<UserData>);
impl<UserData> Default for RapierPhysicsPlugin<UserData> {
fn default() -> Self {
Self(PhantomData)
}
}
pub const TRANSFORM_SYNC_STAGE: &'static str = "rapier::transform_sync_stage";
#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)]
pub enum PhysicsStages {
FinalizeCreations,
SyncTransforms,
}
impl<UserData: 'static + WorldQuery + Send + Sync> Plugin for RapierPhysicsPlugin<UserData> {
fn build(&self, app: &mut App) {
app.add_stage_before(
CoreStage::PreUpdate,
PhysicsStages::FinalizeCreations,
SystemStage::parallel(),
)
.add_stage_before(
CoreStage::PostUpdate,
PhysicsStages::SyncTransforms,
SystemStage::parallel(),
)
.insert_resource(PhysicsPipeline::new())
.insert_resource(QueryPipeline::new())
.insert_resource(RapierConfiguration::default())
.insert_resource(IntegrationParameters::default())
.insert_resource(BroadPhase::new())
.insert_resource(NarrowPhase::new())
.insert_resource(IslandManager::new())
.insert_resource(ImpulseJointSet::new())
.insert_resource(MultibodyJointSet::new())
.insert_resource(CCDSolver::new())
.insert_resource(Events::<IntersectionEvent>::default())
.insert_resource(Events::<ContactEvent>::default())
.insert_resource(SimulationToRenderTime::default())
.insert_resource(JointsEntityMap::default())
.insert_resource(ModificationTracker::default())
.add_system_to_stage(
PhysicsStages::FinalizeCreations,
physics::attach_bodies_and_colliders_system
.label(physics::PhysicsSystems::AttachBodiesAndColliders),
)
.add_system_to_stage(
PhysicsStages::FinalizeCreations,
physics::create_joints_system.label(physics::PhysicsSystems::CreateJoints),
)
.add_system_to_stage(
CoreStage::PreUpdate,
physics::finalize_collider_attach_to_bodies
.label(physics::PhysicsSystems::FinalizeColliderAttachToBodies),
)
.add_system_to_stage(
CoreStage::Update,
physics::step_world_system::<UserData>.label(physics::PhysicsSystems::StepWorld),
)
.add_system_to_stage(
PhysicsStages::SyncTransforms,
physics::sync_transforms.label(physics::PhysicsSystems::SyncTransforms),
)
.add_system_to_stage(
CoreStage::PostUpdate,
physics::collect_removals.label(physics::PhysicsSystems::CollectRemovals),
);
if app
.world
.get_resource::<PhysicsHooksWithQueryObject<UserData>>()
.is_none()
{
app.insert_resource(PhysicsHooksWithQueryObject::<UserData>(Box::new(())));
}
}
}