Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions doc/classes/PhysicsServer2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -951,13 +951,29 @@
Creates a 2D space in the physics server, and returns the [RID] that identifies it. A space contains bodies and areas, and controls the stepping of the physics simulation of the objects in it.
</description>
</method>
<method name="space_flush_queries" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<description>
Runs the contact and area monitoring callbacks queued by [param space], so that the results of a manual [method space_step] become observable.
[b]Note:[/b] [param space] must not be active. The engine already flushes queries for active spaces every physics frame.
</description>
</method>
<method name="space_get_direct_state">
<return type="PhysicsDirectSpaceState2D" />
<param index="0" name="space" type="RID" />
<description>
Returns the state of a space, a [PhysicsDirectSpaceState2D]. This object can be used for collision/intersection queries.
</description>
</method>
<method name="space_get_last_process_info" experimental="">
<return type="int" />
<param index="0" name="space" type="RID" />
<param index="1" name="process_info" type="int" enum="PhysicsServer2D.ProcessInfo" />
<description>
Returns information about the current state of [param space]. See [enum ProcessInfo] for a list of available states.
</description>
</method>
<method name="space_get_param" qualifiers="const">
<return type="float" />
<param index="0" name="space" type="RID" />
Expand Down Expand Up @@ -990,6 +1006,16 @@
Sets the value of the given space parameter.
</description>
</method>
<method name="space_step" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<param index="1" name="delta" type="float" />
<description>
Manually advances [param space] forward by [param delta] seconds. This can be used to fast-forward a simulation, as in rollback-style networking, or to predict an outcome, such as previewing the path of a ball in a billiards game.
[b]Note:[/b] [param space] must not be active. An active space is already advanced once per physics frame by the engine, so stepping it manually would advance it twice. Deactivate it with [method space_set_active] first.
[b]Note:[/b] Stepping does not run contact or area monitoring callbacks. Call [method space_flush_queries] afterwards if you need them.
</description>
</method>
<method name="world_boundary_shape_create">
<return type="RID" />
<description>
Expand Down
20 changes: 20 additions & 0 deletions doc/classes/PhysicsServer2DExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,12 @@
Overridable version of [method PhysicsServer2D.space_create].
</description>
</method>
<method name="_space_flush_queries" qualifiers="virtual required" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<description>
</description>
</method>
<method name="_space_get_contact_count" qualifiers="virtual required const">
<return type="int" />
<param index="0" name="space" type="RID" />
Expand All @@ -1048,6 +1054,13 @@
Overridable version of [method PhysicsServer2D.space_get_direct_state].
</description>
</method>
<method name="_space_get_last_process_info" qualifiers="virtual required" experimental="">
<return type="int" />
<param index="0" name="space" type="RID" />
<param index="1" name="process_info" type="int" enum="PhysicsServer2D.ProcessInfo" />
<description>
</description>
</method>
<method name="_space_get_param" qualifiers="virtual required const">
<return type="float" />
<param index="0" name="space" type="RID" />
Expand Down Expand Up @@ -1089,6 +1102,13 @@
Overridable version of [method PhysicsServer2D.space_set_param].
</description>
</method>
<method name="_space_step" qualifiers="virtual required" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<param index="1" name="delta" type="float" />
<description>
</description>
</method>
<method name="_step" qualifiers="virtual required">
<return type="void" />
<param index="0" name="step" type="float" />
Expand Down
26 changes: 26 additions & 0 deletions doc/classes/PhysicsServer3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1404,13 +1404,29 @@
Creates a space. A space is a collection of parameters for the physics engine that can be assigned to an area or a body. It can be assigned to an area with [method area_set_space], or to a body with [method body_set_space].
</description>
</method>
<method name="space_flush_queries" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<description>
Runs the contact and area monitoring callbacks queued by [param space], so that the results of a manual [method space_step] become observable.
[b]Note:[/b] [param space] must not be active. The engine already flushes queries for active spaces every physics frame.
</description>
</method>
<method name="space_get_direct_state">
<return type="PhysicsDirectSpaceState3D" />
<param index="0" name="space" type="RID" />
<description>
Returns the state of a space, a [PhysicsDirectSpaceState3D]. This object can be used to make collision/intersection queries.
</description>
</method>
<method name="space_get_last_process_info" experimental="">
<return type="int" />
<param index="0" name="space" type="RID" />
<param index="1" name="process_info" type="int" enum="PhysicsServer3D.ProcessInfo" />
<description>
Returns information about the current state of [param space]. See [enum ProcessInfo] for a list of available states.
</description>
</method>
<method name="space_get_param" qualifiers="const">
<return type="float" />
<param index="0" name="space" type="RID" />
Expand Down Expand Up @@ -1443,6 +1459,16 @@
Sets the value for a space parameter. A list of available parameters is on the [enum SpaceParameter] constants.
</description>
</method>
<method name="space_step" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<param index="1" name="delta" type="float" />
<description>
Manually advances [param space] forward by [param delta] seconds. This can be used to fast-forward a simulation, as in rollback-style networking, or to predict an outcome, such as previewing the path of a ball in a billiards game.
[b]Note:[/b] [param space] must not be active. An active space is already advanced once per physics frame by the engine, so stepping it manually would advance it twice. Deactivate it with [method space_set_active] first.
[b]Note:[/b] Stepping does not run contact or area monitoring callbacks. Call [method space_flush_queries] afterwards if you need them.
</description>
</method>
<method name="sphere_shape_create">
<return type="RID" />
<description>
Expand Down
20 changes: 20 additions & 0 deletions doc/classes/PhysicsServer3DExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,12 @@
<description>
</description>
</method>
<method name="_space_flush_queries" qualifiers="virtual required" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<description>
</description>
</method>
<method name="_space_get_contact_count" qualifiers="virtual required const">
<return type="int" />
<param index="0" name="space" type="RID" />
Expand All @@ -1288,6 +1294,13 @@
<description>
</description>
</method>
<method name="_space_get_last_process_info" qualifiers="virtual required" experimental="">
<return type="int" />
<param index="0" name="space" type="RID" />
<param index="1" name="process_info" type="int" enum="PhysicsServer3D.ProcessInfo" />
<description>
</description>
</method>
<method name="_space_get_param" qualifiers="virtual required const">
<return type="float" />
<param index="0" name="space" type="RID" />
Expand Down Expand Up @@ -1323,6 +1336,13 @@
<description>
</description>
</method>
<method name="_space_step" qualifiers="virtual required" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<param index="1" name="delta" type="float" />
<description>
</description>
</method>
<method name="_sphere_shape_create" qualifiers="virtual required">
<return type="RID" />
<description>
Expand Down
61 changes: 61 additions & 0 deletions modules/godot_physics_2d/godot_physics_server_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,48 @@ bool GodotPhysicsServer2D::space_is_active(RID p_space) const {
return active_spaces.has(space);
}

void GodotPhysicsServer2D::space_step(RID p_space, real_t p_delta) {
GodotSpace2D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL(space);
ERR_FAIL_COND_MSG(active_spaces.has(space), "An active space can't be stepped manually. Deactivate it with space_set_active() first.");

// Only drain the pending shape updates that belong to this space, rather than calling
// _update_shapes(), so that stepping one space never mutates another. Manually stepped
// spaces are typically used for lockstep/rollback simulation, where that isolation matters.
SelfList<GodotCollisionObject2D> *collision_object_self = pending_shape_update_list.first();
while (collision_object_self) {
if (collision_object_self->self()->get_space() == space) {
collision_object_self->self()->_shape_changed();

SelfList<GodotCollisionObject2D> *to_remove = collision_object_self;
collision_object_self = collision_object_self->next();

pending_shape_update_list.remove(to_remove);
} else {
collision_object_self = collision_object_self->next();
}
}

stepper->step(space, p_delta);
}

void GodotPhysicsServer2D::space_flush_queries(RID p_space) {
GodotSpace2D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL(space);
ERR_FAIL_COND_MSG(active_spaces.has(space), "An active space should not flush queries manually. Deactivate it with space_set_active() first.");

// Validate before raising the flag: an early return with it still set would leave the
// server permanently "flushing", silently disabling the guards that read
// is_flushing_queries() (e.g. Area2D::set_monitorable). Save and restore rather than
// forcing false, so a nested flush from inside a physics callback can't clear the outer one.
const bool was_flushing_queries = flushing_queries;
flushing_queries = true;

space->call_queries();

flushing_queries = was_flushing_queries;
}

void GodotPhysicsServer2D::space_set_param(RID p_space, PS2DE::SpaceParameter p_param, real_t p_value) {
GodotSpace2D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL(space);
Expand Down Expand Up @@ -1388,6 +1430,25 @@ int GodotPhysicsServer2D::get_process_info(PS2DE::ProcessInfo p_info) {
return 0;
}

int GodotPhysicsServer2D::space_get_last_process_info(RID p_space, PS2DE::ProcessInfo p_info) {
GodotSpace2D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL_V(space, 0);

switch (p_info) {
case PS2DE::INFO_ACTIVE_OBJECTS: {
return space->get_active_objects();
} break;
case PS2DE::INFO_COLLISION_PAIRS: {
return space->get_collision_pairs();
} break;
case PS2DE::INFO_ISLAND_COUNT: {
return space->get_island_count();
} break;
}

return 0;
}

GodotPhysicsServer2D *GodotPhysicsServer2D::godot_singleton = nullptr;

GodotPhysicsServer2D::GodotPhysicsServer2D(bool p_using_threads) {
Expand Down
3 changes: 3 additions & 0 deletions modules/godot_physics_2d/godot_physics_server_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ class GodotPhysicsServer2D : public PhysicsServer2D {
virtual RID space_create() override;
virtual void space_set_active(RID p_space, bool p_active) override;
virtual bool space_is_active(RID p_space) const override;
virtual void space_step(RID p_space, real_t p_delta) override;
virtual void space_flush_queries(RID p_space) override;

virtual void space_set_param(RID p_space, PS2DE::SpaceParameter p_param, real_t p_value) override;
virtual real_t space_get_param(RID p_space, PS2DE::SpaceParameter p_param) const override;
Expand Down Expand Up @@ -298,6 +300,7 @@ class GodotPhysicsServer2D : public PhysicsServer2D {
virtual bool is_flushing_queries() const override { return flushing_queries; }

int get_process_info(PS2DE::ProcessInfo p_info) override;
int space_get_last_process_info(RID p_space, PS2DE::ProcessInfo p_info) override;

GodotPhysicsServer2D(bool p_using_threads = false);
~GodotPhysicsServer2D() {}
Expand Down
61 changes: 61 additions & 0 deletions modules/godot_physics_3d/godot_physics_server_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,48 @@ bool GodotPhysicsServer3D::space_is_active(RID p_space) const {
return active_spaces.has(space);
}

void GodotPhysicsServer3D::space_step(RID p_space, real_t p_delta) {
GodotSpace3D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL(space);
ERR_FAIL_COND_MSG(active_spaces.has(space), "An active space can't be stepped manually. Deactivate it with space_set_active() first.");

// Only drain the pending shape updates that belong to this space, rather than calling
// _update_shapes(), so that stepping one space never mutates another. Manually stepped
// spaces are typically used for lockstep/rollback simulation, where that isolation matters.
SelfList<GodotCollisionObject3D> *collision_object_self = pending_shape_update_list.first();
while (collision_object_self) {
if (collision_object_self->self()->get_space() == space) {
collision_object_self->self()->_shape_changed();

SelfList<GodotCollisionObject3D> *to_remove = collision_object_self;
collision_object_self = collision_object_self->next();

pending_shape_update_list.remove(to_remove);
} else {
collision_object_self = collision_object_self->next();
}
}

stepper->step(space, p_delta);
}

void GodotPhysicsServer3D::space_flush_queries(RID p_space) {
GodotSpace3D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL(space);
ERR_FAIL_COND_MSG(active_spaces.has(space), "An active space should not flush queries manually. Deactivate it with space_set_active() first.");

// Validate before raising the flag: an early return with it still set would leave the
// server permanently "flushing", silently disabling the guards that read
// is_flushing_queries() (e.g. Area3D::set_monitorable). Save and restore rather than
// forcing false, so a nested flush from inside a physics callback can't clear the outer one.
const bool was_flushing_queries = flushing_queries;
flushing_queries = true;

space->call_queries();

flushing_queries = was_flushing_queries;
}

void GodotPhysicsServer3D::space_set_param(RID p_space, PS3DE::SpaceParameter p_param, real_t p_value) {
GodotSpace3D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL(space);
Expand Down Expand Up @@ -1786,6 +1828,25 @@ int GodotPhysicsServer3D::get_process_info(PS3DE::ProcessInfo p_info) {
return 0;
}

int GodotPhysicsServer3D::space_get_last_process_info(RID p_space, PS3DE::ProcessInfo p_info) {
GodotSpace3D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL_V(space, 0);

switch (p_info) {
case PS3DE::INFO_ACTIVE_OBJECTS: {
return space->get_active_objects();
} break;
case PS3DE::INFO_COLLISION_PAIRS: {
return space->get_collision_pairs();
} break;
case PS3DE::INFO_ISLAND_COUNT: {
return space->get_island_count();
} break;
}

return 0;
}

void GodotPhysicsServer3D::_update_shapes() {
while (pending_shape_update_list.first()) {
pending_shape_update_list.first()->self()->_shape_changed();
Expand Down
3 changes: 3 additions & 0 deletions modules/godot_physics_3d/godot_physics_server_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ class GodotPhysicsServer3D : public PhysicsServer3D {
virtual RID space_create() override;
virtual void space_set_active(RID p_space, bool p_active) override;
virtual bool space_is_active(RID p_space) const override;
virtual void space_step(RID p_space, real_t p_delta) override;
virtual void space_flush_queries(RID p_space) override;

virtual void space_set_param(RID p_space, PS3DE::SpaceParameter p_param, real_t p_value) override;
virtual real_t space_get_param(RID p_space, PS3DE::SpaceParameter p_param) const override;
Expand Down Expand Up @@ -387,6 +389,7 @@ class GodotPhysicsServer3D : public PhysicsServer3D {
virtual bool is_flushing_queries() const override { return flushing_queries; }

int get_process_info(PS3DE::ProcessInfo p_info) override;
int space_get_last_process_info(RID p_space, PS3DE::ProcessInfo p_info) override;

GodotPhysicsServer3D(bool p_using_threads = false);
~GodotPhysicsServer3D() {}
Expand Down
Loading