Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
* PhysicalBone2D - Fixed issue where physics would simulate regardless of whether it was supposed to or not. Now physics only simulate when simulate_physics is true.
* PhysicalBone2D - Fixed issue where PhysicalBone2D nodes would be actively able to collide with other objects in the scene when simulate_physics is false.
* PhysicalBone2D - Removed bloat code that was not doing anything.
* PhysicalBones Modification2D - Fixed issue where the modification was not properly starting or stopping PhysicalBone2D nodes when calling start_simulation and stop_simulation.
* PhysicalBones Modification2D - Make start_simulation and stop_simulation calls stored and executed in _execute, so they still work when called in _ready.
  • Loading branch information
TwistedTwigleg committed Jul 31, 2020
1 parent 0858d7a commit 3edb4f2
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 58 deletions.
48 changes: 20 additions & 28 deletions scene/2d/physical_bone_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ void PhysicalBone2D::_notification(int p_what) {
child_joint->set_global_position(node_a->get_global_transform().get_origin());
}
}

// Remove any collision layers and masks if we're disabled.
// We do this so the RigidBody can still have it's layers and masks set like normal, but they will not be applied
// unless physics are told to simulate, only making them effective when we want them to be.
if (!_internal_simulate_physics) {
PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), 0);
PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), 0);
}
}

// Only in the editor: keep the PhysicalBone2D at the Bone2D position (if there is one) at all times.
Expand Down Expand Up @@ -125,27 +133,6 @@ void PhysicalBone2D::_find_joint_child() {
}
}

void PhysicalBone2D::_direct_state_changed(Object *p_state) {
if (!simulate_physics || !_internal_simulate_physics) {
return;
}
PhysicsDirectBodyState2D *state;
state = Object::cast_to<PhysicsDirectBodyState2D>(p_state);

if (!state) {
// This is not the physics we are looking for, so ignore it!
return;
}

Transform2D global_transform(state->get_transform());

// Add rotation constraints here? Might be something to add in the future...

set_notify_transform(false);
set_global_transform(global_transform);
set_notify_transform(true);
}

String PhysicalBone2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();

Expand Down Expand Up @@ -200,24 +187,27 @@ void PhysicalBone2D::_auto_configure_joint() {
}

void PhysicalBone2D::_start_physics_simulation() {
if (_internal_simulate_physics || !parent_skeleton) {
if (_internal_simulate_physics) {
return;
}

// Reset to Bone2D position
_position_at_bone2d();

// Let the RigidBody executing its force integration.
PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");

// Apply the layers and masks
PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer());
PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask());

_internal_simulate_physics = true;
}

void PhysicalBone2D::_stop_physics_simulation() {
if (!parent_skeleton) {
return;
}

if (_internal_simulate_physics) {
PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), nullptr, "");
// Stop the RigidBody from executing its force integration.
PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), nullptr, "");
_internal_simulate_physics = false;

// Reset to Bone2D position
Expand All @@ -242,8 +232,8 @@ void PhysicalBone2D::set_simulate_physics(bool p_simulate) {
if (p_simulate == simulate_physics) {
return;
}

simulate_physics = p_simulate;

if (simulate_physics) {
_start_physics_simulation();
} else {
Expand Down Expand Up @@ -340,6 +330,8 @@ void PhysicalBone2D::_bind_methods() {
}

PhysicalBone2D::PhysicalBone2D() {
// Stop the RigidBody from executing its force integration.
PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), nullptr, "");
}

PhysicalBone2D::~PhysicalBone2D() {
Expand Down
1 change: 0 additions & 1 deletion scene/2d/physical_bone_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ class PhysicalBone2D : public RigidBody2D {
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
void _notification(int p_what);
void _direct_state_changed(Object *p_state);
static void _bind_methods();

private:
Expand Down
62 changes: 33 additions & 29 deletions scene/resources/skeleton_modification_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2631,6 +2631,10 @@ void SkeletonModification2DPhysicalBones::execute(float delta) {
return;
}

if (_simulation_state_dirty) {
_update_simulation_state();
}

for (int i = 0; i < physical_bone_chain.size(); i++) {
PhysicalBone_Data2D bone_data = physical_bone_chain[i];
if (bone_data.physical_bone_node_cache.is_null()) {
Expand All @@ -2644,10 +2648,10 @@ void SkeletonModification2DPhysicalBones::execute(float delta) {
ERR_FAIL_INDEX_MSG(physical_bone->get_bone2d_index(), stack->skeleton->get_bone_count(), "PhysicalBone2D at index " + itos(i) + " has invalid Bone2D!");
Bone2D *bone_2d = stack->skeleton->get_bone(physical_bone->get_bone2d_index());

// TODO: make sure the PhysicalBone2D is simulating before applying.

bone_2d->set_global_transform(physical_bone->get_global_transform());
stack->skeleton->set_bone_local_pose_override(physical_bone->get_bone2d_index(), bone_2d->get_transform(), stack->strength, true);
if (physical_bone->get_simulate_physics()) {
bone_2d->set_global_transform(physical_bone->get_global_transform());
stack->skeleton->set_bone_local_pose_override(physical_bone->get_bone2d_index(), bone_2d->get_transform(), stack->strength, true);
}
}
}

Expand Down Expand Up @@ -2721,48 +2725,48 @@ void SkeletonModification2DPhysicalBones::fetch_physical_bones() {
}

void SkeletonModification2DPhysicalBones::start_simulation(const TypedArray<StringName> &p_bones) {
if (p_bones.size() <= 0) {
// Simulate all the bones!
for (int i = 0; i < physical_bone_chain.size(); i++) {
PhysicalBone2D *physical_bone = Object::cast_to<PhysicalBone2D>(ObjectDB::get_instance(physical_bone_chain[i].physical_bone_node_cache));
if (!physical_bone) {
continue;
}
_simulation_state_dirty = true;
_simulation_state_dirty_names = p_bones;
_simulation_state_dirty_process = true;

physical_bone->set_simulate_physics(true);
}
} else {
for (int i = 0; i < physical_bone_chain.size(); i++) {
PhysicalBone2D *physical_bone = Object::cast_to<PhysicalBone2D>(ObjectDB::get_instance(physical_bone_chain[i].physical_bone_node_cache));
if (!physical_bone) {
continue;
}
if (p_bones.has(physical_bone->get_name())) {
physical_bone->set_simulate_physics(true);
}
}
if (is_setup) {
_update_simulation_state();
}
}

void SkeletonModification2DPhysicalBones::stop_simulation(const TypedArray<StringName> &p_bones) {
if (p_bones.size() <= 0) {
// Stop all the bones!
_simulation_state_dirty = true;
_simulation_state_dirty_names = p_bones;
_simulation_state_dirty_process = false;

if (is_setup) {
_update_simulation_state();
}
}

void SkeletonModification2DPhysicalBones::_update_simulation_state() {
if (!_simulation_state_dirty) {
return;
}
_simulation_state_dirty = false;

if (_simulation_state_dirty_names.size() <= 0) {
for (int i = 0; i < physical_bone_chain.size(); i++) {
PhysicalBone2D *physical_bone = Object::cast_to<PhysicalBone2D>(ObjectDB::get_instance(physical_bone_chain[i].physical_bone_node_cache));
PhysicalBone2D *physical_bone = Object::cast_to<PhysicalBone2D>(stack->skeleton->get_node(physical_bone_chain[i].physical_bone_node));
if (!physical_bone) {
continue;
}

physical_bone->set_simulate_physics(false);
physical_bone->set_simulate_physics(_simulation_state_dirty_process);
}
} else {
for (int i = 0; i < physical_bone_chain.size(); i++) {
PhysicalBone2D *physical_bone = Object::cast_to<PhysicalBone2D>(ObjectDB::get_instance(physical_bone_chain[i].physical_bone_node_cache));
if (!physical_bone) {
continue;
}
if (p_bones.has(physical_bone->get_name())) {
physical_bone->set_simulate_physics(false);
if (_simulation_state_dirty_names.has(physical_bone->get_name())) {
physical_bone->set_simulate_physics(_simulation_state_dirty_process);
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions scene/resources/skeleton_modification_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,11 @@ class SkeletonModification2DPhysicalBones : public SkeletonModification2D {

void _physical_bone_update_cache(int p_joint_idx);

bool _simulation_state_dirty = false;
TypedArray<StringName> _simulation_state_dirty_names;
bool _simulation_state_dirty_process;
void _update_simulation_state();

protected:
static void _bind_methods();
bool _get(const StringName &p_path, Variant &r_ret) const;
Expand Down

0 comments on commit 3edb4f2

Please sign in to comment.