From 768f4e684ccb2c12a3ed53a39666f99a5359d6bb Mon Sep 17 00:00:00 2001
From: Rhathe <rassinator@gmail.com>
Date: Fri, 1 May 2020 03:33:00 -0400
Subject: [PATCH] Enable setting of collision iterations in Physics2DServer

This allows fine-tuning of collision iterations for more
accurate collision physics with a performance cost.
---
 doc/classes/Physics2DServer.xml                | 9 +++++++++
 servers/physics_2d/physics_2d_server_sw.cpp    | 4 ++++
 servers/physics_2d/physics_2d_server_sw.h      | 2 ++
 servers/physics_2d/physics_2d_server_wrap_mt.h | 1 +
 servers/physics_2d_server.cpp                  | 2 ++
 servers/physics_2d_server.h                    | 2 ++
 6 files changed, 20 insertions(+)

diff --git a/doc/classes/Physics2DServer.xml b/doc/classes/Physics2DServer.xml
index e72895c8384..bf64e8f77fb 100644
--- a/doc/classes/Physics2DServer.xml
+++ b/doc/classes/Physics2DServer.xml
@@ -1002,6 +1002,15 @@
 				Activates or deactivates the 2D physics engine.
 			</description>
 		</method>
+		<method name="set_collision_iterations">
+			<return type="void">
+			</return>
+			<argument index="0" name="iterations" type="int">
+			</argument>
+			<description>
+				Sets the amount of iterations for calculating velocities of colliding bodies. The greater the amount, the more accurate the collisions, but with a performance loss.
+			</description>
+		</method>
 		<method name="shape_get_data" qualifiers="const">
 			<return type="Variant">
 			</return>
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 809c5c40e06..794c1b6bc70 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -1315,6 +1315,10 @@ void Physics2DServerSW::set_active(bool p_active) {
 	active = p_active;
 };
 
+void Physics2DServerSW::set_collision_iterations(int p_iterations) {
+	iterations = p_iterations;
+};
+
 void Physics2DServerSW::init() {
 
 	doing_sync = false;
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index c8f443e3b61..c17916ec414 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -284,6 +284,8 @@ public:
 	virtual void end_sync();
 	virtual void finish();
 
+	virtual void set_collision_iterations(int p_iterations);
+
 	virtual bool is_flushing_queries() const { return flushing_queries; }
 
 	int get_process_info(ProcessInfo p_info);
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index eec0a3933f6..98fb2a2d26d 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -304,6 +304,7 @@ public:
 
 	FUNC1(free, RID);
 	FUNC1(set_active, bool);
+	FUNC1(set_collision_iterations, int);
 
 	virtual void init();
 	virtual void step(real_t p_step);
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index 71e3bf8ae89..bcb8c6d3310 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -684,6 +684,8 @@ void Physics2DServer::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("set_active", "active"), &Physics2DServer::set_active);
 
+	ClassDB::bind_method(D_METHOD("set_collision_iterations", "iterations"), &Physics2DServer::set_collision_iterations);
+
 	ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &Physics2DServer::get_process_info);
 
 	BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS);
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 40c58ecac50..cfc6d3f3e69 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -593,6 +593,8 @@ public:
 
 	virtual bool is_flushing_queries() const = 0;
 
+	virtual void set_collision_iterations(int iterations) = 0;
+
 	enum ProcessInfo {
 
 		INFO_ACTIVE_OBJECTS,