Skip to content

Commit

Permalink
Merge pull request #136 from Ughuuu/ughuuu/physics_space_step_from_da…
Browse files Browse the repository at this point in the history
…ylily-zeleen

Add space_step() to step physics simulation manually
  • Loading branch information
jss2a98aj authored Jan 12, 2025
2 parents 668a001 + 39007c0 commit 3b808e0
Show file tree
Hide file tree
Showing 18 changed files with 246 additions and 2 deletions.
24 changes: 24 additions & 0 deletions doc/classes/PhysicsServer2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -950,13 +950,28 @@
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>
Flushes [param space]'s queries. It is necessary to call this method after calling [method space_step] with an active space from [code]_physics_process[/code]. Otherwise, call this method before calling [method space_step].
</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 @@ -989,6 +1004,15 @@
Sets the value of the given space parameter. See [enum SpaceParameter] for the list of available parameters.
</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 advance [param space] forward in [param delta]. This technique can be used for speeding up physics simulations, as seen in advanced rollback-style networking, or for predicting outcomes in scenarios such as hitting a ball in a billiards game.
[b]Note:[/b] If call this method with an active [param space] from [code]_physics_process()[/code], you should call [method space_flush_queries] afterwards. Otherwise, call [method space_flush_queries] beforehand.
</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 @@ -1024,6 +1024,12 @@
Overridable version of [method PhysicsServer2D.space_create].
</description>
</method>
<method name="_space_flush_queries" qualifiers="virtual" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<description>
</description>
</method>
<method name="_space_get_contact_count" qualifiers="virtual const">
<return type="int" />
<param index="0" name="space" type="RID" />
Expand All @@ -1047,6 +1053,13 @@
Overridable version of [method PhysicsServer2D.space_get_direct_state].
</description>
</method>
<method name="_space_get_last_process_info" qualifiers="virtual" 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 const">
<return type="float" />
<param index="0" name="space" type="RID" />
Expand Down Expand Up @@ -1088,6 +1101,13 @@
Overridable version of [method PhysicsServer2D.space_set_param].
</description>
</method>
<method name="_space_step" qualifiers="virtual" 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">
<return type="void" />
<param index="0" name="step" type="float" />
Expand Down
24 changes: 24 additions & 0 deletions doc/classes/PhysicsServer3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1314,13 +1314,28 @@
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>
Flushes [param space]'s queries. It is necessary to call this method after calling [method space_step] with an active space from [code]_physics_process[/code]. Otherwise, call this method before calling [method space_step].
</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 @@ -1353,6 +1368,15 @@
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 advance [param space] forward in [param delta]. This technique can be used for speeding up physics simulations, as seen in advanced rollback-style networking, or for predicting outcomes in scenarios such as hitting a ball in a billiards game.
[b]Note:[/b] If call this method with an active [param space] from [code]_physics_process()[/code], you should call [method space_flush_queries] afterwards. Otherwise, call [method space_flush_queries] beforehand.
</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 @@ -1214,6 +1214,12 @@
<description>
</description>
</method>
<method name="_space_flush_queries" qualifiers="virtual" experimental="">
<return type="void" />
<param index="0" name="space" type="RID" />
<description>
</description>
</method>
<method name="_space_get_contact_count" qualifiers="virtual const">
<return type="int" />
<param index="0" name="space" type="RID" />
Expand All @@ -1232,6 +1238,13 @@
<description>
</description>
</method>
<method name="_space_get_last_process_info" qualifiers="virtual" 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 const">
<return type="float" />
<param index="0" name="space" type="RID" />
Expand Down Expand Up @@ -1267,6 +1280,13 @@
<description>
</description>
</method>
<method name="_space_step" qualifiers="virtual" 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">
<return type="RID" />
<description>
Expand Down
3 changes: 3 additions & 0 deletions servers/extensions/physics_server_2d_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ void PhysicsServer2DExtension::_bind_methods() {
GDVIRTUAL_BIND(_space_create);
GDVIRTUAL_BIND(_space_set_active, "space", "active");
GDVIRTUAL_BIND(_space_is_active, "space");
GDVIRTUAL_BIND(_space_step, "space", "delta")
GDVIRTUAL_BIND(_space_flush_queries, "space")

GDVIRTUAL_BIND(_space_set_param, "space", "param", "value");
GDVIRTUAL_BIND(_space_get_param, "space", "param");
Expand Down Expand Up @@ -342,6 +344,7 @@ void PhysicsServer2DExtension::_bind_methods() {

GDVIRTUAL_BIND(_is_flushing_queries);
GDVIRTUAL_BIND(_get_process_info, "process_info");
GDVIRTUAL_BIND(_space_get_last_process_info, "space", "process_info");
}

PhysicsServer2DExtension::PhysicsServer2DExtension() {
Expand Down
3 changes: 3 additions & 0 deletions servers/extensions/physics_server_2d_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ class PhysicsServer2DExtension : public PhysicsServer2D {
EXBIND0R(RID, space_create)
EXBIND2(space_set_active, RID, bool)
EXBIND1RC(bool, space_is_active, RID)
EXBIND2(space_step, RID, real_t)
EXBIND1(space_flush_queries, RID)

EXBIND3(space_set_param, RID, SpaceParameter, real_t)
EXBIND2RC(real_t, space_get_param, RID, SpaceParameter)
Expand Down Expand Up @@ -448,6 +450,7 @@ class PhysicsServer2DExtension : public PhysicsServer2D {

EXBIND0RC(bool, is_flushing_queries)
EXBIND1R(int, get_process_info, ProcessInfo)
EXBIND2R(int, space_get_last_process_info, RID, ProcessInfo)

PhysicsServer2DExtension();
~PhysicsServer2DExtension();
Expand Down
3 changes: 3 additions & 0 deletions servers/extensions/physics_server_3d_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ void PhysicsServer3DExtension::_bind_methods() {
GDVIRTUAL_BIND(_space_create);
GDVIRTUAL_BIND(_space_set_active, "space", "active");
GDVIRTUAL_BIND(_space_is_active, "space");
GDVIRTUAL_BIND(_space_step, "space", "delta")
GDVIRTUAL_BIND(_space_flush_queries, "space")

GDVIRTUAL_BIND(_space_set_param, "space", "param", "value");
GDVIRTUAL_BIND(_space_get_param, "space", "param");
Expand Down Expand Up @@ -422,6 +424,7 @@ void PhysicsServer3DExtension::_bind_methods() {

GDVIRTUAL_BIND(_is_flushing_queries);
GDVIRTUAL_BIND(_get_process_info, "process_info");
GDVIRTUAL_BIND(_space_get_last_process_info, "space", "process_info");
}

PhysicsServer3DExtension::PhysicsServer3DExtension() {
Expand Down
3 changes: 3 additions & 0 deletions servers/extensions/physics_server_3d_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ class PhysicsServer3DExtension : public PhysicsServer3D {
EXBIND0R(RID, space_create)
EXBIND2(space_set_active, RID, bool)
EXBIND1RC(bool, space_is_active, RID)
EXBIND2(space_step, RID, real_t)
EXBIND1(space_flush_queries, RID)

EXBIND3(space_set_param, RID, SpaceParameter, real_t)
EXBIND2RC(real_t, space_get_param, RID, SpaceParameter)
Expand Down Expand Up @@ -536,6 +538,7 @@ class PhysicsServer3DExtension : public PhysicsServer3D {

EXBIND0RC(bool, is_flushing_queries)
EXBIND1R(int, get_process_info, ProcessInfo)
EXBIND2R(int, space_get_last_process_info, RID, ProcessInfo)

PhysicsServer3DExtension();
~PhysicsServer3DExtension();
Expand Down
57 changes: 57 additions & 0 deletions servers/physics_2d/godot_physics_server_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,44 @@ 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);

// TODO:
// May be let pending_shape_update_list as a member of GodotSpaces3D and update shapes by themselves.
// To avoid effecting Spces which are handled by developer (for lockstep/rollback netcode, it is particularly sensitive).
// Otherwise, call _update_shapes() directly.
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) {
// TODO::
// Like _update_shapes(), to provide controllability for developers, flushing_queries flag should active as a member of space and check it for each space.
// But I'm not sure about that, I am not familiar with multi-threads and the architecture of GodotPhysics.
flushing_queries = true;

GodotSpace2D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL(space);
space->call_queries();

flushing_queries = false;
}

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

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

switch (p_info) {
case INFO_ACTIVE_OBJECTS: {
return space->get_active_objects();
} break;
case INFO_COLLISION_PAIRS: {
return space->get_collision_pairs();
} break;
case 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 servers/physics_2d/godot_physics_server_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,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, SpaceParameter p_param, real_t p_value) override;
virtual real_t space_get_param(RID p_space, SpaceParameter p_param) const override;
Expand Down Expand Up @@ -299,6 +301,7 @@ class GodotPhysicsServer2D : public PhysicsServer2D {
virtual bool is_flushing_queries() const override { return flushing_queries; }

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

GodotPhysicsServer2D(bool p_using_threads = false);
~GodotPhysicsServer2D() {}
Expand Down
57 changes: 57 additions & 0 deletions servers/physics_3d/godot_physics_server_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,44 @@ 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);

// TODO:
// May be let pending_shape_update_list as a member of GodotSpaces3D and update shapes by themselves.
// To avoid effecting Spces which are handled by developer (for lockstep/rollback netcode, it is particularly sensitive).
// If it is unnecessary, call _update_shapes() directly.
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) {
// TODO:
// Like _update_shapes(), to provide controllability for developers, flushing_queries flag should active as a member of space and check it for each space.
// But I'm not sure about that, I am not familiar with multi-threads and the architecture of GodotPhysics.
flushing_queries = true;

GodotSpace3D *space = space_owner.get_or_null(p_space);
ERR_FAIL_NULL(space);
space->call_queries();

flushing_queries = false;
}

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

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

switch (p_info) {
case INFO_ACTIVE_OBJECTS: {
return space->get_active_objects();
} break;
case INFO_COLLISION_PAIRS: {
return space->get_collision_pairs();
} break;
case 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
Loading

0 comments on commit 3b808e0

Please sign in to comment.