소스 검색

Merge pull request #106490 from mihe/jolt/non-monitoring-area-performance

Improve performance with non-monitoring areas when using Jolt Physics
Thaddeus Crews 4 달 전
부모
커밋
c225686e82
2개의 변경된 파일28개의 추가작업 그리고 5개의 파일을 삭제
  1. 21 5
      modules/jolt_physics/objects/jolt_area_3d.cpp
  2. 7 0
      modules/jolt_physics/objects/jolt_area_3d.h

+ 21 - 5
modules/jolt_physics/objects/jolt_area_3d.cpp

@@ -83,7 +83,7 @@ void JoltArea3D::_add_to_space() {
 
 	jolt_settings->SetShape(jolt_shape);
 
-	JPH::Body *new_jolt_body = space->add_rigid_body(*this, *jolt_settings);
+	JPH::Body *new_jolt_body = space->add_rigid_body(*this, *jolt_settings, _should_sleep());
 	if (new_jolt_body == nullptr) {
 		return;
 	}
@@ -275,6 +275,18 @@ void JoltArea3D::_force_areas_exited(bool p_remove) {
 	}
 }
 
+void JoltArea3D::_update_sleeping() {
+	if (space == nullptr) {
+		return;
+	}
+
+	if (_should_sleep()) {
+		space->get_body_iface().DeactivateBody(jolt_body->GetID());
+	} else {
+		space->get_body_iface().ActivateBody(jolt_body->GetID());
+	}
+}
+
 void JoltArea3D::_update_group_filter() {
 	if (!in_space()) {
 		return;
@@ -316,19 +328,23 @@ void JoltArea3D::_events_changed() {
 }
 
 void JoltArea3D::_body_monitoring_changed() {
-	if (has_body_monitor_callback()) {
+	if (is_monitoring_bodies()) {
 		_force_bodies_entered();
 	} else {
 		_force_bodies_exited(false);
 	}
+
+	_update_sleeping();
 }
 
 void JoltArea3D::_area_monitoring_changed() {
-	if (has_area_monitor_callback()) {
+	if (is_monitoring_areas()) {
 		_force_areas_entered();
 	} else {
 		_force_areas_exited(false);
 	}
+
+	_update_sleeping();
 }
 
 void JoltArea3D::_monitorable_changed() {
@@ -513,7 +529,7 @@ void JoltArea3D::set_monitorable(bool p_monitorable) {
 }
 
 bool JoltArea3D::can_monitor(const JoltBody3D &p_other) const {
-	return (collision_mask & p_other.get_collision_layer()) != 0;
+	return is_monitoring_bodies() && (collision_mask & p_other.get_collision_layer()) != 0;
 }
 
 bool JoltArea3D::can_monitor(const JoltSoftBody3D &p_other) const {
@@ -521,7 +537,7 @@ bool JoltArea3D::can_monitor(const JoltSoftBody3D &p_other) const {
 }
 
 bool JoltArea3D::can_monitor(const JoltArea3D &p_other) const {
-	return p_other.is_monitorable() && (collision_mask & p_other.get_collision_layer()) != 0;
+	return is_monitoring_areas() && p_other.is_monitorable() && (collision_mask & p_other.get_collision_layer()) != 0;
 }
 
 bool JoltArea3D::can_interact_with(const JoltBody3D &p_other) const {

+ 7 - 0
modules/jolt_physics/objects/jolt_area_3d.h

@@ -116,6 +116,8 @@ private:
 
 	virtual JPH::EMotionType _get_motion_type() const override { return JPH::EMotionType::Kinematic; }
 
+	bool _should_sleep() const { return !is_monitoring(); }
+
 	virtual void _add_to_space() override;
 
 	void _enqueue_call_queries();
@@ -137,6 +139,7 @@ private:
 	void _force_areas_entered();
 	void _force_areas_exited(bool p_remove);
 
+	void _update_sleeping();
 	void _update_group_filter();
 	void _update_default_gravity();
 
@@ -165,6 +168,10 @@ public:
 	bool has_area_monitor_callback() const { return area_monitor_callback.is_valid(); }
 	void set_area_monitor_callback(const Callable &p_callback);
 
+	bool is_monitoring_bodies() const { return has_body_monitor_callback(); }
+	bool is_monitoring_areas() const { return has_area_monitor_callback(); }
+	bool is_monitoring() const { return is_monitoring_bodies() || is_monitoring_areas(); }
+
 	bool is_monitorable() const { return monitorable; }
 	void set_monitorable(bool p_monitorable);