Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add space_step() to step physics simulation manually #136

Open
wants to merge 1 commit into
base: blazium-dev
Choose a base branch
from
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
24 changes: 24 additions & 0 deletions doc/classes/PhysicsServer2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -935,13 +935,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 @@ -974,6 +989,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 @@ -882,6 +882,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 @@ -900,6 +906,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="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 @@ -935,6 +948,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="_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 @@ -1026,13 +1026,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 @@ -1065,6 +1080,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
Loading