Merge pull request #606 from nekomatata/physics-tests-contacts-update

Updated 2d/3d physics contact performance tests
This commit is contained in:
Aaron Franke
2021-04-14 12:34:24 -05:00
committed by GitHub
17 changed files with 205 additions and 114 deletions

View File

@@ -68,12 +68,10 @@ func clear_drawn_nodes():
_drawn_nodes.clear()
func create_rigidbody_box(size, pickable = false, use_icon = false):
var shape = RectangleShape2D.new()
shape.extents = 0.5 * size
func create_rigidbody(shape, pickable = false, transform = Transform.IDENTITY):
var collision = CollisionShape2D.new()
collision.shape = shape
collision.transform = transform
var body = RigidBody2D.new()
body.add_child(collision)
@@ -82,6 +80,32 @@ func create_rigidbody_box(size, pickable = false, use_icon = false):
var script = load("res://utils/rigidbody_pick.gd")
body.set_script(script)
return body
func create_rigidbody_collision(collision, pickable = false, transform = Transform.IDENTITY):
var collision_copy = collision.duplicate()
collision_copy.transform = transform
if collision is CollisionShape2D:
collision_copy.shape = collision.shape.duplicate()
var body = RigidBody2D.new()
body.add_child(collision_copy)
if pickable:
var script = load("res://utils/rigidbody_pick.gd")
body.set_script(script)
return body
func create_rigidbody_box(size, pickable = false, use_icon = false, transform = Transform.IDENTITY):
var shape = RectangleShape2D.new()
shape.extents = 0.5 * size
var body = create_rigidbody(shape, pickable, transform)
if use_icon:
var texture = load("res://icon.png")
var icon = Sprite.new()

View File

@@ -167,7 +167,7 @@ func _on_option_selected(option):
func _find_type_index(type_name):
for type_index in _collision_shapes.size():
for type_index in range(_collision_shapes.size()):
var type_shape = _collision_shapes[type_index]
if type_shape.resource_name.find(type_name) > -1:
return type_index

View File

@@ -11,8 +11,6 @@ const OPTION_TEST_CASE_CHANGE_POSITIONS = "Test case/Set body positions after ad
const BOX_SIZE = Vector2(64, 64)
onready var options = $Options
var _update_joint = false
var _selected_joint = null
@@ -27,8 +25,10 @@ var _joint_types = {}
func _ready():
var options = $Options
var joints = $Joints
for joint_index in joints.get_child_count():
for joint_index in range(joints.get_child_count()):
var joint_node = joints.get_child(joint_index)
joint_node.visible = false
var joint_name = joint_node.name

View File

@@ -28,7 +28,7 @@ func _create_pyramid():
var pos_x = -0.5 * (num_boxes - 1) * (box_size.x + box_spacing.x)
for box_index in num_boxes:
for box_index in range(num_boxes):
var box = template_body.duplicate()
box.position = Vector2(pos_x, 0.0)
box.name = "Box%02d" % (box_index + 1)

View File

@@ -26,7 +26,7 @@ func _create_stack():
var pos_x = -0.5 * (width - 1) * (box_size.x + box_spacing.x)
for box_index in width:
for box_index in range(width):
var box = template_body.duplicate()
box.position = Vector2(pos_x, 0.0)
box.name = "Box%02d" % (box_index + 1)

View File

@@ -148,7 +148,7 @@ func _remove_objects():
# Remove objects in reversed order to avoid the overhead of changing children index in parent.
var object_count = _objects.size()
for object_index in object_count:
for object_index in range(object_count):
root_node.remove_child(_objects[object_count - object_index - 1])
timer = OS.get_ticks_usec() - timer

View File

@@ -10,12 +10,15 @@ const OPTION_TYPE_CONCAVE_POLYGON = "Shape type/Concave Polygon"
export(Array) var spawns = Array()
export(int) var spawn_count = 100
export(int, 1, 10) var spawn_multiplier = 5
onready var options = $Options
var _object_templates = []
var _log_physics = false
var _log_physics_time = 0
var _log_physics_time_start = 0
func _ready():
yield(start_timer(0.5), "timeout")
@@ -40,6 +43,25 @@ func _ready():
_start_all_types()
func _physics_process(_delta):
if _log_physics:
var time = OS.get_ticks_usec()
var time_delta = time - _log_physics_time
var time_total = time - _log_physics_time_start
_log_physics_time = time
Log.print_log(" Physics Tick: %.3f ms (total = %.3f ms)" % [0.001 * time_delta, 0.001 * time_total])
func _log_physics_start():
_log_physics = true
_log_physics_time_start = OS.get_ticks_usec()
_log_physics_time = _log_physics_time_start
func _log_physics_stop():
_log_physics = false
func _exit_tree():
for object_template in _object_templates:
object_template.free()
@@ -66,7 +88,7 @@ func _on_option_selected(option):
func _find_type_index(type_name):
for type_index in _object_templates.size():
for type_index in range(_object_templates.size()):
var type_node = _object_templates[type_index]
if type_node.name.find(type_name) > -1:
return type_index
@@ -85,44 +107,47 @@ func _start_type(type_index):
if is_timer_canceled():
return
_log_physics_start()
_spawn_objects(type_index)
yield(wait_for_physics_ticks(5), "wait_done")
_log_physics_stop()
yield(start_timer(1.0), "timeout")
if is_timer_canceled():
return
_log_physics_start()
_activate_objects()
yield(wait_for_physics_ticks(5), "wait_done")
_log_physics_stop()
yield(start_timer(5.0), "timeout")
if is_timer_canceled():
return
_log_physics_start()
_despawn_objects()
Log.print_log("* Done.")
yield(wait_for_physics_ticks(5), "wait_done")
_log_physics_stop()
yield(start_timer(1.0), "timeout")
func _start_all_types():
for type_index in _object_templates.size():
yield(start_timer(1.0), "timeout")
Log.print_log("* Start all types.")
for type_index in range(_object_templates.size()):
yield(_start_type(type_index), "completed")
if is_timer_canceled():
return
_spawn_objects(type_index)
yield(start_timer(1.0), "timeout")
if is_timer_canceled():
return
_activate_objects()
yield(start_timer(5.0), "timeout")
if is_timer_canceled():
return
_despawn_objects()
Log.print_log("* Done.")
Log.print_log("* Done all types.")
func _spawn_objects(type_index):
@@ -132,33 +157,37 @@ func _spawn_objects(type_index):
Log.print_log("* Spawning: " + template_node.name)
for _index in range(spawn_multiplier):
for _node_index in spawn_count / spawn_multiplier:
var node = template_node.duplicate() as Node2D
spawn_parent.add_child(node)
for _node_index in range(spawn_count):
# Create a new object and shape every time to avoid the overhead of connecting many bodies to the same shape.
var collision = template_node.get_child(0)
var body = create_rigidbody_collision(collision, false, collision.transform)
body.set_sleeping(true)
spawn_parent.add_child(body)
func _activate_objects():
var spawn_parent = $SpawnTarget1
for spawn in spawns:
var spawn_parent = get_node(spawn)
Log.print_log("* Activating")
Log.print_log("* Activating")
for node_index in spawn_parent.get_child_count():
var node = spawn_parent.get_child(node_index) as RigidBody2D
node.set_sleeping(false)
for node_index in range(spawn_parent.get_child_count()):
var node = spawn_parent.get_child(node_index) as RigidBody2D
node.set_sleeping(false)
func _despawn_objects():
for spawn in spawns:
var spawn_parent = get_node(spawn)
if spawn_parent.get_child_count() == 0:
return
var object_count = spawn_parent.get_child_count()
if object_count == 0:
continue
Log.print_log("* Despawning")
while spawn_parent.get_child_count():
var node_index = spawn_parent.get_child_count() - 1
var node = spawn_parent.get_child(node_index)
# Remove objects in reversed order to avoid the overhead of changing children index in parent.
for object_index in range(object_count):
var node = spawn_parent.get_child(object_count - object_index - 1)
spawn_parent.remove_child(node)
node.queue_free()

View File

@@ -17,7 +17,9 @@ height = 30.0
[node name="Test" type="Node2D"]
script = ExtResource( 2 )
_enable_debug_collision = false
spawns = [ NodePath("SpawnTarget1") ]
spawn_count = 200
[node name="Options" parent="." instance=ExtResource( 4 )]

View File

@@ -13,7 +13,7 @@ func add_menu_item(item_path, checkbox = false, checked = false, radio = false):
var path = ""
var popup = get_popup()
for element_index in path_element_count - 1:
for element_index in range(path_element_count - 1):
var popup_label = path_elements[element_index]
path += popup_label + "/"
popup = _add_popup(popup, path, popup_label)
@@ -59,7 +59,7 @@ func _on_item_pressed(item_index, popup_menu, path):
var checked = popup_menu.is_item_checked(item_index)
if not checked:
popup_menu.set_item_checked(item_index, true)
for other_index in popup_menu.get_item_count():
for other_index in range(popup_menu.get_item_count()):
if other_index != item_index:
popup_menu.set_item_checked(other_index, false)
emit_signal("option_selected", item_path)