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
use crate::app::{App, Plugin};
#[cfg(feature = "physics")]
use gizmo_physics_rigid::world::PhysicsWorld;
use crate::math::Vec3;
/// Gizmo Engine Physics Plugin.
/// When added, it initializes the physics world (PhysicsWorld).
#[non_exhaustive]
#[cfg(feature = "physics")]
pub struct PhysicsPlugin {
pub gravity: Vec3,
}
#[cfg(feature = "physics")]
impl Default for PhysicsPlugin {
fn default() -> Self {
Self {
gravity: Vec3::new(0.0, -9.81, 0.0),
}
}
}
#[cfg(feature = "physics")]
impl PhysicsPlugin {
/// Creates a new PhysicsPlugin with the default gravity.
pub fn new() -> Self {
Self::default()
}
/// Sets the gravity vector (chainable).
pub fn with_gravity(mut self, gravity: Vec3) -> Self {
self.gravity = gravity;
self
}
}
#[cfg(feature = "physics")]
impl<State: 'static> Plugin<State> for PhysicsPlugin {
fn build(&self, app: &mut App<State>) {
tracing::info!(
"[Plugin] PhysicsPlugin yükleniyor (Yerçekimi: {:?})...",
self.gravity
);
app.world
.insert_resource(PhysicsWorld::new().with_gravity(self.gravity));
// Run the physics step automatically at the app's fixed timestep (the
// `PhysicsTime` accumulator loop that also drives `TransformPlugin`), so
// callers don't hand-call `cpu_physics_step_system` every frame. Labelled
// so transform systems can order themselves after it if both are added.
app.schedule.add_di_system(
gizmo_core::system::SystemConfig::new(Box::new(
crate::systems::physics::PhysicsStepSystem,
))
.label("physics_step"),
);
// Resolve any `AutoBoxCollider` markers (box collider sized from Transform.scale)
// strictly BEFORE the physics step reads them, so a marked body never takes its
// first step with the placeholder unit box. Registered here (same plugin, same
// default phase) so the `physics_step` label is guaranteed to exist and the
// `.before` edge actually binds.
app.schedule.add_di_system(
gizmo_core::system::SystemConfig::new(Box::new(
crate::systems::auto_collider::AutoBoxColliderSystem,
))
.label("auto_box_collider")
.before("physics_step"),
);
}
}
/// The plugin that starts the Transform (hierarchy and synchronization) systems.
#[cfg(feature = "physics")]
pub struct TransformPlugin;
#[cfg(feature = "physics")]
impl<State: 'static> Plugin<State> for TransformPlugin {
fn build(&self, app: &mut App<State>) {
// Per-frame, not per fixed step — and this is an ordering fix as much as a cost one.
//
// These ran in the fixed-timestep schedule, so they propagated `0..N` times per
// rendered frame while the result is only ever consumed once, at draw. The comment
// on `PhysicsPlugin`'s `physics_step` label says transform systems "can order
// themselves after it", but no such edge was ever wired — so within a single fixed
// step the order was whatever the batcher chose.
//
// The update schedule runs after *every* fixed step of the frame (see
// `gizmo_app::frame::run_fixed_and_update`), so "transforms propagate after physics"
// is now structural rather than dependent on a label edge that did not exist. It is
// also after the per-frame update systems, which is what a camera moved by
// `FpsLookSystem` needs.
//
// `default_render_pass` still calls `ensure_global_transforms` immediately before
// drawing. That stays: it is the safety net for a custom `App` that never registers
// this plugin, and it is what backfills a `GlobalTransform` onto a freshly spawned
// mesh. With this plugin registered the propagation is simply already current.
app.update_schedule.add_di_system(
gizmo_core::system::SystemConfig::new(Box::new(
crate::systems::transform::TransformSyncSystem,
))
.label("transform_sync"),
);
app.update_schedule.add_di_system(
gizmo_core::system::SystemConfig::new(Box::new(
crate::systems::transform::TransformPropagateSystem,
))
.label("transform_propagate")
.after("transform_sync"),
);
}
}