Class CollisionGeometryUtils
- Namespace
- GridPlacement.GDScript
- Assembly
- MoonBark.GridPlacement.GDScript.dll
Pure, stateless helpers used by the placement/collision mapping pipeline. These functions are extracted from the runtime mapper to allow focused unit tests and reuse from multiple contexts without side-effects.\n\n[b]Default Overlap Thresholds[/b] - Edge epsilon: [code]0.01[/code] (1% tolerance for edge detection) - Minimum area fraction: [code]0.05[/code] (5% of tile area required for overlap) - Very small polygons (< 5% of tile area) are filtered out to avoid spurious detections - For 16×16 tiles, minimum overlap area is 12.8 square units - For 32×32 tiles, minimum overlap area is 51.2 square units\n\n[b]Testing Notes[/b] - Micro polygons smaller than 5% threshold return zero tiles (by design) - Use larger polygons (≥25% tile area) for reliable collision detection in tests - Production mapper may use different thresholds for specific shape types\n\n[i]Documentation style[/i]: Comments use BBCode to render nicely in the Godot editor's help panel.\n\nCross‑references - Center‑based tile semantics: Indicator and mapper math assume tile centers; e.g., 16×16 → center offset (+8,+8). - Iteration range epsilon: compute_tile_iteration_range applies symmetric epsilons to min/max to avoid fencepost tiles when world bounds align exactly to tile borders (bottom‑inclusive, top‑exclusive in practice).
class CollisionGeometryUtils extends RefCounted
Properties
shape_transform
var shape_transform = Transform2D()
shape_local_offset
var shape_local_offset = shape_owner.position
world_points
var world_points: PackedVector2Array = PackedVector2Array()
global_xform
var global_xform = polygon_node.get_global_transform()
result
var result = {}
epsilon
var epsilon = 0.0001
adjusted_min_corner
var adjusted_min_corner = bounds.position + Vector2(epsilon, epsilon)
start_tile
var start_tile = map.local_to_map(map.to_local(adjusted_min_corner))
adjusted_max_corner
var adjusted_max_corner = bounds.position + bounds.size - Vector2(epsilon, epsilon)
end_tile_inclusive
var end_tile_inclusive = map.local_to_map(map.to_local(adjusted_max_corner))
end_exclusive
var end_exclusive = Vector2i(end_tile_inclusive.x + 1, end_tile_inclusive.y + 1)
offsets
var offsets: Array[Vector2i] = []
overlapped_tiles
var overlapped_tiles: Array[Vector2i] = CollisionGeometryCalculator.calculate_tile_overlap(world_points, tile_size, tile_shape, tile_map_layer, 0.01, 0.05)
n
var n = points.size()
sign
var sign = 0
a
var a = points[i]
b
var b = points[(i+1) % n]
c
var c = points[(i+2) % n]
cross
var cross = (b - a).cross(c - b)
curr_sign
var curr_sign = signi(cross)
Methods
build_shape_transform
static func build_shape_transform(col_obj: Node2D, shape_owner: Node2D) -> Transform2D:
Parameters
col_objshape_owner
Returns
to_world_polygon
static func to_world_polygon(polygon_node: CollisionPolygon2D) -> PackedVector2Array:
Parameters
polygon_node
Returns
compute_tile_iteration_range
static func compute_tile_iteration_range(bounds: Rect2, map: TileMapLayer) -> Dictionary:
Parameters
boundsmap
Returns
center_tile_for_polygon_positioner
static func center_tile_for_polygon_positioner(map: TileMapLayer, positioner: Node2D) -> Vector2i:
Parameters
mappositioner
Returns
center_tile_for_shape_object
static func center_tile_for_shape_object(map: TileMapLayer, col_obj: Node2D) -> Vector2i:
Parameters
mapcol_obj
Returns
compute_polygon_tile_offsets
static func compute_polygon_tile_offsets(world_points: PackedVector2Array, tile_size: Vector2, center_tile: Vector2i, tile_shape: TileSet.TileShape = TileSet.TILE_SHAPE_SQUARE, tile_map_layer: TileMapLayer = null) -> Array[Vector2i]:
Parameters
world_pointstile_sizecenter_tiletile_shapetile_map_layer
Returns
is_polygon_convex
static func is_polygon_convex(points: PackedVector2Array) -> bool:
Parameters
points