Skip to content

Commit

Permalink
Add new options for speeding up collision generation
Browse files Browse the repository at this point in the history
  • Loading branch information
mphe committed Jun 19, 2024
1 parent d6d851d commit a5a59bd
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 4 deletions.
10 changes: 10 additions & 0 deletions addons/rmsmartshape/documentation/Shapes.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ A shape can be open or closed. Each new shape starts open. To close a shape, sim
- Second Param in Curve2D.tessellate.
- See [Curve2D Documentation](https://docs.godotengine.org/en/3.2/classes/class_curve2d.html#class-curve2d-method-tessellate).

### Collision Generation Method

- Controls which method should be used to generate the collision shape.
- See also in-engine documentation.

### Collision Update Mode

- Controls when to update collisions.
- See also in-engine documentation.

### Curve Bake Interval

- Bake interval value for Curve2D.
Expand Down
63 changes: 59 additions & 4 deletions addons/rmsmartshape/shapes/shape.gd
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ class_name SS2D_Shape
#
# To use search to jump between categories, use the regex: # .+ #

const TUP = preload("../lib/tuple.gd")

################
#-DECLARATIONS-#
################
Expand All @@ -33,6 +31,30 @@ signal make_unique_pressed(shape: SS2D_Shape)

enum ORIENTATION { COLINEAR, CLOCKWISE, C_CLOCKWISE }

enum CollisionGenerationMethod {
## Uses the shape curve to generate a collision polygon. Usually this method is accurate enough.
Fast,
## Uses the edge generation algorithm to create an accurate collision representation that
## exactly matches the shape's visuals.
## Depending on the shape's complexity, this method is very expensive.
Precise,
}

enum CollisionUpdateMode {
## Only update collisions in editor. If the corresponding CollisionPolygon2D is part of the same
## scene, it will be saved automatically by Godot, hence no additional regeneration at runtime
## is necessary, which reduces the loading times.
## Does not work if the CollisionPolygon2D is part of an instanced scene, as only the scene root
## node will be saved by Godot.
Editor,
## Only update collisions during runtime. Improves the shape-editing performance in editor but
## increases loading times as collision generation is deferred to runtime.
Runtime,
## Update collisions both in editor and during runtime. This is the default behavior in older
## SS2D versions.
EditorAndRuntime,
}

###########
#-EXPORTS-#
###########
Expand Down Expand Up @@ -102,6 +124,12 @@ var tessellation_tolerence: float = 6.0 :

@export_group("Collision")

## Controls which method should be used to generate the collision shape.
@export var collision_generation_method := CollisionGenerationMethod.Fast : set = set_collision_generation_method

## Controls when to update collisions.
@export var collision_update_mode := CollisionUpdateMode.Editor : set = set_collision_update_mode

## Controls size of generated polygon for CollisionPolygon2D.
@export_range(0.0, 64.0, 1.0, "or_greater")
var collision_size: float = 32 : set = set_collision_size
Expand Down Expand Up @@ -180,6 +208,16 @@ func set_render_edges(b: bool) -> void:
notify_property_list_changed()


func set_collision_generation_method(value: CollisionGenerationMethod) -> void:
collision_generation_method = value
set_as_dirty()


func set_collision_update_mode(value: CollisionUpdateMode) -> void:
collision_update_mode = value
set_as_dirty()


func set_collision_size(s: float) -> void:
collision_size = s
set_as_dirty()
Expand Down Expand Up @@ -815,7 +853,7 @@ func should_flip_edges() -> bool:
return flip_edges


func generate_collision_points() -> PackedVector2Array:
func _generate_collision_points_precise() -> PackedVector2Array:
var points := PackedVector2Array()
var num_points: int = _points.get_point_count()
if num_points < 2:
Expand Down Expand Up @@ -861,11 +899,28 @@ func generate_collision_points() -> PackedVector2Array:
return points


func _generate_collision_points_fast() -> PackedVector2Array:
return _points.get_tessellated_points()


func bake_collision() -> void:
if not _collision_polygon_node:
return

if collision_update_mode == CollisionUpdateMode.Editor and not Engine.is_editor_hint() \
or collision_update_mode == CollisionUpdateMode.Runtime and Engine.is_editor_hint():
return

var generated_points: PackedVector2Array

match collision_generation_method:
CollisionGenerationMethod.Fast:
generated_points = _generate_collision_points_fast()
CollisionGenerationMethod.Precise:
generated_points = _generate_collision_points_precise()

var xform := _collision_polygon_node.get_global_transform().affine_inverse() * get_global_transform()
_collision_polygon_node.polygon = xform * generate_collision_points()
_collision_polygon_node.polygon = xform * generated_points


func cache_edges() -> void:
Expand Down

0 comments on commit a5a59bd

Please sign in to comment.