RapidGameFramework
Reusable Godot managers for data-driven small games
Loading...
Searching...
No Matches
physics_world.gd
Go to the documentation of this file.
1extends RefCounted
2
3
10
11const SpatialState = preload("res://scripts/systems/physicsEngine/spatial_state.gd")
12const MotionIntegrator = preload("res://scripts/systems/physicsEngine/motion_integrator.gd")
13const CollisionPipeline = preload("res://scripts/systems/physicsEngine/collision_pipeline.gd")
14const ConstraintSolver = preload("res://scripts/systems/physicsEngine/constraint_solver.gd")
15const PhysicsQueries = preload("res://scripts/systems/physicsEngine/physics_queries.gd")
16
17var spatial_state = SpatialState.new()
18var motion_integrator = MotionIntegrator.new()
19var collision_pipeline = CollisionPipeline.new()
20var constraint_solver = ConstraintSolver.new()
21var queries = PhysicsQueries.new()
22
23var gravity := Vector2.ZERO
24var damping := 0.0
25var constraints := []
26var last_contacts := []
27
28
29
30func configure(options:Dictionary = {}) -> void:
31 gravity = options.get("gravity", gravity)
32 damping = max(0.0, float(options.get("damping", damping)))
33
34
35
36func create_body(id:String, position:Vector2, options:Dictionary = {}) -> Dictionary:
37 return spatial_state.create_body(id, position, options)
38
39
40
41func add_force(id:String, force:Vector2) -> void:
42 var body = spatial_state.get_body(id)
43 if body.is_empty():
44 return
45 spatial_state.set_body(motion_integrator.add_force(body, force))
46
47
48
49func apply_impulse(id:String, impulse:Vector2) -> void:
50 var body = spatial_state.get_body(id)
51 if body.is_empty():
52 return
53 spatial_state.set_body(motion_integrator.apply_impulse(body, impulse))
54
55
56
57func add_constraint(constraint:Dictionary) -> void:
58 constraints.append(constraint.duplicate(true))
59
60
61
62func step(delta:float, solver_iterations:int = 1) -> Array:
63 for body in spatial_state.get_bodies():
64 spatial_state.set_body(motion_integrator.integrate(body, delta, gravity, damping))
65 var pairs = collision_pipeline.broad_phase(spatial_state.get_bodies(), spatial_state)
66 last_contacts = collision_pipeline.narrow_phase(pairs)
67 var resolved = constraint_solver.resolve_collisions(spatial_state.bodies, last_contacts)
68 resolved = constraint_solver.solve_constraints(resolved, constraints, solver_iterations)
69 spatial_state.bodies = resolved
70 return last_contacts.duplicate(true)
71
72
73
74func get_broad_phase_pairs() -> Array:
75 return collision_pipeline.broad_phase(spatial_state.get_bodies(), spatial_state)
76
77
78
79func get_contacts() -> Array:
80 return collision_pipeline.narrow_phase(get_broad_phase_pairs())
81
82
83func point_query(point:Vector2) -> Array:
84 return queries.point_query(spatial_state.get_bodies(), point)
85
86
87func aabb_query(area:Rect2) -> Array:
88 return queries.aabb_query(spatial_state.get_bodies(), area)
89
90
91func raycast(from:Vector2, to:Vector2) -> Dictionary:
92 return queries.raycast(spatial_state.get_bodies(), from, to)
93
94
95func get_body(id:String) -> Dictionary:
96 return spatial_state.get_body(id)
97
98
99func get_state() -> Dictionary:
100 return {
101 "spatial_state": spatial_state.get_state(),
102 "gravity": gravity,
103 "damping": damping,
104 "constraints": constraints.duplicate(true)
105 }
106
107
108func apply_state(state:Dictionary) -> void:
109 spatial_state.apply_state(state.get("spatial_state", {}))
110 gravity = state.get("gravity", Vector2.ZERO)
111 damping = float(state.get("damping", 0.0))
112 constraints = state.get("constraints", []).duplicate(true)
113
114
115func clear() -> void:
116 spatial_state.clear()
117 constraints.clear()
118 last_contacts.clear()