7const CollisionPipeline = preload(
"res://scripts/systems/physicsEngine/collision_pipeline.gd")
9var collision_pipeline = CollisionPipeline.new()
13func point_query(bodies:Array, point:Vector2) -> Array:
16 if _contains_point(body, point):
17 results.append(body.duplicate(true))
22func aabb_query(bodies:Array, area:Rect2) -> Array:
25 if collision_pipeline.get_aabb(body).intersects(area):
26 results.append(body.duplicate(true))
31func raycast(bodies:Array,
from:Vector2, to:Vector2) -> Dictionary:
33 var best_distance := INF
35 var hit = _ray_body(body,
from, to)
38 var distance = from.distance_to(hit.get(
"point",
from))
39 if distance < best_distance:
40 best_distance = distance
45func _contains_point(body:Dictionary, point:Vector2) -> bool:
46 var shape = body.get(
"shape", {})
47 if str(shape.get(
"type",
"aabb")) ==
"circle":
48 return point.distance_to(body.get(
"position", Vector2.ZERO)) <= float(shape.get(
"radius", 8.0))
49 return collision_pipeline.get_aabb(body).has_point(point)
52func _ray_body(body:Dictionary,
from:Vector2, to:Vector2) -> Dictionary:
53 var shape = body.get(
"shape", {})
54 if str(shape.get(
"type",
"aabb")) ==
"circle":
55 return _ray_circle(body,
from, to)
56 return _ray_aabb(body,
from, to)
59func _ray_circle(body:Dictionary,
from:Vector2, to:Vector2) -> Dictionary:
60 var center = body.get(
"position", Vector2.ZERO)
61 var radius = float(body.get(
"shape", {}).get(
"radius", 8.0))
62 var direction = to -
from
63 var length = direction.length()
66 var dir = direction / length
67 var to_center = center -
from
68 var projection = clamp(to_center.dot(dir), 0.0, length)
69 var closest =
from + dir * projection
70 if closest.distance_to(center) <= radius:
71 return {
"body": body.duplicate(true),
"point": closest,
"distance": from.distance_to(closest)}
75func _ray_aabb(body:Dictionary,
from:Vector2, to:Vector2) -> Dictionary:
76 var rect = collision_pipeline.get_aabb(body)
77 var direction = to -
from
80 for axis
in [
"x",
"y"]:
81 var origin = from.x
if axis ==
"x" else from.y
82 var dir = direction.x
if axis ==
"x" else direction.y
83 var min_value = rect.position.x
if axis ==
"x" else rect.position.y
84 var max_value = rect.end.x
if axis ==
"x" else rect.end.y
86 if origin < min_value
or origin > max_value:
89 var inv_dir = 1.0 / dir
90 var t1 = (min_value - origin) * inv_dir
91 var t2 = (max_value - origin) * inv_dir
96 t_min = max(t_min, t1)
97 t_max = min(t_max, t2)
100 var point =
from + direction * t_min
101 return {
"body": body.duplicate(true),
"point": point,
"distance": from.distance_to(point)}