-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathphysics_system.h
249 lines (223 loc) · 6.67 KB
/
physics_system.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
////////////////////////////////////////////////////////////////////////////////
// Distributed under the Boost Software License, Version 1.0. //
// (See accompanying file LICENSE or copy at //
// https://www.boost.org/LICENSE_1_0.txt) //
////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <chrono>
#include <memory>
#include <optional>
#include <set>
#include <vector>
#include "core/quaternion.h"
#include "core/vector3.h"
#include "graphics/scene.h"
#include "physics/character_controller.h"
#include "physics/collision_shape.h"
#include "physics/contact_point.h"
#include "physics/ray_cast_result.h"
#include "physics/rigid_body.h"
namespace iris
{
class RenderEntity;
class Mesh;
class Texture;
/**
* Interface for a class which stores the current state of a PhysicsSystem.
*/
struct PhysicsState
{
virtual ~PhysicsState() = default;
};
/**
* Interface for a class which can manage and simulate a physics world.
*/
class PhysicsSystem
{
public:
PhysicsSystem() = default;
virtual ~PhysicsSystem() = default;
// disabled
PhysicsSystem(const PhysicsSystem &) = delete;
PhysicsSystem &operator=(const PhysicsSystem &) = delete;
/**
* Step the physics system by the supplied time.
*
* @param time_step
* The amount of time to simulate.
*/
virtual void step(std::chrono::milliseconds time_step) = 0;
/**
* Create a RigidBody and add it to the simulation.
*
* @param position
* Position in world space.
*
* @param collision_shape
* The shape that defined the rigid body, this is used for collision
* detection/response.
*
* @param type
* The type of rigid body, this effects how this body interacts with
* others.
*
* @returns
* A pointer to the newly created RigidBody.
*/
virtual RigidBody *create_rigid_body(
const Vector3 &position,
const CollisionShape *collision_shape,
RigidBodyType type) = 0;
/**
* Create a CollisionShape for a box.
*
* @param half_size
* The extends from the center of the box which define its size.
*
* @returns
* Pointer to newly created CollisionShape.
*/
virtual const CollisionShape *create_box_collision_shape(const Vector3 &half_size) = 0;
/**
* Create a CollisionShape for a capsule.
*
* @param width
* Diameter of capsule.
*
* @param height
* Height of capsule.
*
* @returns
* Pointer to newly created CollisionShape.
*/
virtual const CollisionShape *create_capsule_collision_shape(float width, float height) = 0;
/**
* Create a CollisionShape from a Mesh.
*
* @param mesh
* Mesh to create collision shape from.
*
* @param scale
* Scale of mesh as it will be rendered.
*
* @returns
* Pointer to newly created CollisionShape.
*/
virtual const CollisionShape *create_mesh_collision_shape(const Mesh *mesh, const Vector3 &scale) = 0;
/**
* Create a CollisionShape from a Texture (reads height data from r component).
*
* @param heightmap
* Texture containing height data.
*
* @param scale
* Scale of mesh as it will be rendered.
*
* @returns
* Pointer to newly created CollisionShape.
*/
virtual const CollisionShape *create_heightmap_collision_shape(const Texture *heightmap, const Vector3 &scale) = 0;
/**
* Add a character controller.
*
* @param character_controller
* Character controller to add.
*
* @return
* Pointer to added character controller.
*/
virtual CharacterController *add(std::unique_ptr<CharacterController> character_controller) = 0;
/**
* Create a CharacterController object.
*
* @param args
* Arguments to forward to CharacterController constructor.
*
* @returns
* Pointer to newly added CharacterController.
*/
template <class T, class... Args>
T *create_character_controller(Args &&...args)
{
return static_cast<T *>(add(std::make_unique<T>(std::forward<Args>(args)...)));
}
/**
* Remove a body from the physics system.
*
* This will release all resources for the body, using the handle after this
* call is undefined.
*
* @param body
* Body to remove.
*/
virtual void remove(RigidBody *body) = 0;
/**
* Character controller a body from the physics system.
*
* This will release all resources for the character, using the handle after
* this call is undefined.
*
* @param character
* Character to remove.
*/
virtual void remove(CharacterController *character) = 0;
/**
* Cast a ray into physics engine world and get all hits.
*
* @param origin
* Origin of ray.
*
* @param direction.
* Direction of ray.
*
* @param ignore
* Collection of rigid bodies that should be ignored from ray cast results.
*
* @returns
* Collection of RayCastResult objects for all intersection with ray. These will be sorted from distance to origin
* (closest first).
*/
virtual std::vector<RayCastResult> ray_cast(
const Vector3 &origin,
const Vector3 &direction,
const std::set<const RigidBody *> &ignore) = 0;
/**
* Query all contacts with a body.
*
* @param body
* The body to test, note that this will be contact_a in all the returned ContactPoint objects.
*
* @returns
* Collection of ContactPoint objects for all bodies colliding with body.
*/
virtual std::vector<ContactPoint> contacts(RigidBody *body) = 0;
/**
* Save the current state of the simulation.
*
* Note that depending on the implementation this may be a "best guess"
* state save. Restoring isn't guaranteed to produce identical results
* although it should be close enough.
*
* @returns
* Saved state.
*/
virtual std::unique_ptr<PhysicsState> save() = 0;
/**
* Load saved state. This will restore the simulation to that of the
* supplied state.
*
* See save() comments for details of limitations.
*
* @param state
* State to restore from.
*/
virtual void load(const PhysicsState *state) = 0;
/**
* Enable debug rendering. This should only be called once.
*
* @param entity.
* The RenderEntity to store debug render data in.
*/
virtual void enable_debug_draw(Scene *scene) = 0;
};
}