Untitled Game engine no.5  1.0
Components.hpp
1 #ifndef COMPONENTS_HPP
2 #define COMPONENTS_HPP
3 
4 #include <utility>
5 #include "pch.hpp"
6 #include "PhysicsParam.hpp"
7 #include "Types.hpp"
8 #include "Entity.hpp"
9 
10 namespace Engine {
11 
12  struct Transform;
13  struct Collider;
14  struct RigidBody;
15  struct PhysicsEntity;
16 
17  //<editor-fold desc="Physics">
23  struct CollisionHook {
24  virtual void processCollision(const Ref<PhysicsEntity>& other) {};
25  };
26 
32  struct Collider {
33  bool trigger = false;
35 
40  void processCollision(const Ref<PhysicsEntity>& other) { if (hook != nullptr) hook->processCollision(other);};
41  [[nodiscard]] virtual glm::vec3 furthestInDir(const Ref<PhysicsEntity> &pe, const glm::vec3 &norm) const {return {0, 0, 0};}
42  };
43 
45  struct PhysicsEntity {
46  PhysicsEntity(Ref<Entity>& e, Ref<Transform>& transform, Ref<Collider>& collider, Ref<RigidBody>& rigidBody):
47  entity(e), tf(transform), c(collider), rb(rigidBody) {};
48 
52  Ref<Transform> tf = nullptr;
54  Ref<Collider> c = nullptr;
55  Ref<Collider> cuse = nullptr;
57  Ref<RigidBody> rb = nullptr;
58 
59  glm::vec3 v{0};
60  glm::vec3 w{0};
61  glm::vec3 x{0};
62  glm::vec3 xPrev{0};
63 
64 
65  glm::qua<float> q{};
66  glm::qua<float> qPrev{};
67  glm::qua<float> dQ{};
68 
70  bool matUpdated = true;
71  bool itmatUpdated = true;
72 
73 
78  glm::mat4 getMat() {
79  if (matUpdated) {
80  calcMat();
81  }
82  return mat;
83  }
84 
89  glm::mat4 getIMat() {
90  if (itmatUpdated) {
91  calcITMat();
92  }
93  return imat;
94  }
95 
99  void clearMat() {
100  itmatUpdated = true;
101  matUpdated = true;
102  }
103 
104  private:
105  void calcMat() {
106  mat = (glm::translate(x) * glm::toMat4(q));
107  matUpdated = false;
108  }
109 
110  void calcITMat() {
111  imat = glm::affineInverse(getMat());
112  itmatUpdated = false;
113  }
114 
115  glm::mat4 mat {};
116  glm::mat4 imat {};
117  };
118 
122  struct Shape {
123  explicit Shape(Ref<PhysicsEntity>& pe): pe(pe){};
125  [[nodiscard]] glm::vec3 furthestInDir(const glm::vec3 &norm) const {
126  return pe->c->furthestInDir(pe, norm);
127  }
128  };
129 
136  struct Support : public glm::vec3 {
137  glm::vec3 supportA;
138  glm::vec3 supportB;
139 
140  Support &operator=(glm::vec3 support) {
141  x = support.x;
142  y = support.y;
143  z = support.z;
144  return *this;
145  }
146 
147  Support &operator=(const Support& support) {
148  x = support.x;
149  y = support.y;
150  z = support.z;
151  supportA = support.supportA;
152  supportB = support.supportB;
153  return *this;
154  }
155  };
156 
160  struct CollisionPoint {
162  glm::vec3 Normal;
164  std::vector<glm::vec3> contacts;
169  };
170 
177  struct Simplex {
178  std::vector<Support> supports = std::vector<Support>(SIMPLEX_COUNT);
179  size_t index = 0;
180 
181  Simplex &operator=(std::initializer_list<Support> ilist) {
182  int i = 0;
183  for (auto item : ilist) {
184  supports[i] = item;
185  i++;
186  }
187  index = ilist.size();
188 
189  return *this;
190  }
191 
192  Support &operator[](const int &i) {
193  return supports[i];
194  }
195 
196  void operator+=(const Support &support) {
197  supports[index] = support;
198  index++;
199  }
200 
201  void add(glm::vec3 p, glm::vec3 a, glm::vec3 b) {
202  supports[index] = p;
203  supports[index].supportA = a;
204  supports[index].supportB = b;
205  index++;
206  }
207 
208  void set(int i, glm::vec3 p, glm::vec3 a, glm::vec3 b) {
209  supports[i] = p;
210  supports[i].supportA = a;
211  supports[i].supportB = b;
212  }
213 
214  void push(Support p) {
215  for (size_t i = index; i >= 1; i--) {
216  supports[i] = supports[i - 1];
217  }
218 
219  supports[0] = p;
220  index++;
221  }
222 
223  void push(glm::vec3 p, glm::vec3 a, glm::vec3 b) {
224  for (int i = SIMPLEX_COUNT - 1; i >= 1; i--) {
225  supports[i] = supports[i - 1];
226  }
227 
228  supports[0] = p;
229  supports[0].supportA = a;
230  supports[0].supportB = b;
231  index++;
232  }
233  };
234 
240  struct FacePoint {
241  std::vector<Support> verts = std::vector<Support>(FACE_VERTS);
242  glm::vec3 normal{};
243 
244  Support &operator[](const int &i) {
245  return verts[i];
246  }
247 
248  FacePoint &operator=(FacePoint support) {
249  for (int i = 0; i < FACE_VERTS; ++i) {
250  verts[i] = support[i];
251  }
252  normal = support.normal;
253  return *this;
254  }
255 
256  FacePoint &operator=(std::initializer_list<Support> list) {
257  int i = 0;
258  for (Support elem : list) {
259  verts[i] = elem;
260  ++i;
261  }
262  return *this;
263  }
264  };
265 
270  struct Joint {
271  glm::vec3 positionA = {0,0,0}, positionB{};
272  Ref<RigidBody> connectedRigidBody = nullptr;
273  float minLength = 0;
274  float maxLength = 0;
275  float springConstant = 0;
276  Ref<RigidBody> rigidBody = nullptr;
277 
283  explicit Joint(Ref<RigidBody>& otherRigidBody, float maxLength) {
284  connectedRigidBody = otherRigidBody;
285  this->maxLength = maxLength;
286  }
287 
293  Joint(glm::vec3 selfPosition, glm::vec3 globalPosition) {
294  positionA = selfPosition;
295  positionB = globalPosition;
296  }
297 
303  explicit Joint(glm::vec3 globalPosition, float maxLength = 0) {
304  positionA = {0, 0, 0};
305  positionB = globalPosition;
306  this->maxLength = maxLength;
307  }
308  };
309  //</editor-fold>
310 
312  struct Transform {
314  glm::vec3 position = {0.f, 0.f, 0.f};
316  glm::qua<float> rotation = {1.f, 0.f, 0.f, 0.f};
318  glm::vec3 scale = {1.f, 1.f, 1.f};
319 
324  Transform(glm::vec3 p, glm::vec3 r, glm::vec3 s):
325  position(p),
326  rotation(glm::radians(r)),
327  scale(s) {
328 
329  };
330 
332  Transform(const Transform&) = default;
335  Transform() = default;
336 
338  glm::mat4 GetMatrix() const{
339  glm::mat4 t(1.f);
340  auto positionM = glm::translate(t, position);
341  auto rotationM = glm::toMat4(rotation);
342  auto scaleM = glm::scale(t, scale);
343 
344  return positionM * rotationM * scaleM;
345  }
346 
347  };
348 
351  struct ForceApplier {
352  public:
354  glm::vec3 force;
355  };
356 
358  enum Allignment {
359  TOP_LEFT, TOP, TOP_RIGHT,
360  LEFT, CENTER, RIGHT,
361  BOTTOM_LEFT, BOTTOM, BOTTOM_RIGHT
362  };
363 
364 
366  struct ForceGenerator {
367  public:
368  glm::vec3 force;
369  };
370 
376  struct RigidBody {
377  RigidBody() = default;
378  RigidBody(float height, float width, float depth, float m) {
379  setMomentCube(height, width, depth, m);
380  }
381 
383  glm::vec3 velocity = glm::vec3(0, 0, 0);
385  glm::vec3 force = glm::vec3(0, 0, 0);
386 
388  float airDrag = 0.1f;
390  float angularDrag = 1.f;
391 
393  bool kinematic = true;
394 
396  glm::mat3 moment;
398  glm::mat3 invMoment;
399 
401  glm::vec3 w = glm::vec3(0, 0, 0);
403  glm::vec3 t = glm::vec3(0, 0.f, 0);
404 
407 
417  void setMomentCube(float height, float width, float depth, float m) {
418  if (m == 0) {
419  moment = glm::mat4{0};
420  iMass = 0;
421  } else {
422  moment = {{I12 * ((height * height) + (depth * depth)), 0, 0},
423  {0, I12 * ((width * width) + (depth * depth)), 0},
424  {0, 0, I12 * ((width * width) + (height * height))}};
425  moment *= m;
426  invMoment = glm::inverse(moment);
427  iMass = 1 / m;
428  }
429  }
430 
432  float iMass = 1;
434  float drag = 2.98f;
436  bool grounded = true;
437  };
438 
442  struct VertexCollider : virtual Collider {
443  VertexCollider() = default;
444  explicit VertexCollider(std::vector<glm::vec3> verts) : verts(std::move(verts)) {}
445  std::vector<glm::vec3> verts;
446 
447  [[nodiscard]] glm::vec3 furthestInDir(const Ref<PhysicsEntity>& pe, const glm::vec3 &norm) const override {
448  // convert to model space
449  glm::mat4 mat = pe->getMat();
450  glm::vec3 out;
451 
452  bool found = false;
453  float f, o;
454 
455  for (glm::vec3 v : verts) {
456  v = glm::vec3{mat * glm::vec4{v, 1.0f}};
457  o = glm::dot(norm, v);
458  if (!found || o > f) {
459  f = o;
460  out = v;
461  found = true;
462  }
463  }
464  // convert back to global space
465  return out;
466  }
467 
476  static Ref<VertexCollider> boxCollider(float width = 64, float height = 64, float depth = 64) {
477  Ref<VertexCollider> vertexCollider = CreateRef<VertexCollider>();
478  float back = depth / 2.0f;
479  float front = depth / 2.0f;
480  float up = height / 2.0f;
481  float down = height / 2.0f;
482  float left = width / 2.0f;
483  float right = width / 2.0f;
484  vertexCollider->verts = std::vector<glm::vec3> {{-left, -down, back}, {-left, up, back},
485  {right, up, back}, {right, -down, back},
486  {-left, -down, -front}, {-left, up, -front},
487  {right, up, -front}, {right, -down, -front}};
488  return vertexCollider;
489  }
490  };
491 
496  struct Collider2D: virtual Collider {
497  };
498 
504  VertexCollider2D() = default;
505  explicit VertexCollider2D(std::vector<glm::vec3> verts) : VertexCollider(std::move(verts)) {
506  trigger = true;
507  };
508  };
509 
510 }
511 
512 #endif
Engine::Collider
Generic type storage for a GJK enabled collider.
Definition: Components.hpp:32
Engine::ForceApplier::force
glm::vec3 force
force to apply
Definition: Components.hpp:354
Engine::PhysicsEntity::qPrev
glm::qua< float > qPrev
rotation quat
Definition: Components.hpp:66
Engine::Collider2D
Wrapper for 2D collisions. Tells the physics system that you want to process a 2D collision and not a...
Definition: Components.hpp:496
Engine::CollisionPoint::PenetrationDepth
float PenetrationDepth
delta x of the contact
Definition: Components.hpp:166
Engine::PhysicsEntity::q
glm::qua< float > q
previous position (needed for XPBD)
Definition: Components.hpp:65
Engine::Simplex
Storage wrapper for support points.
Definition: Components.hpp:177
Engine::PhysicsEntity::xPrev
glm::vec3 xPrev
position
Definition: Components.hpp:62
Engine::PhysicsEntity::entity
Ref< Entity > entity
Entitiy reference.
Definition: Components.hpp:47
Engine::Transform
Location, orientation, and scale of an entity.
Definition: Components.hpp:312
Engine::RigidBody::drag
float drag
drag co-efficient
Definition: Components.hpp:434
Engine::PhysicsEntity::getIMat
glm::mat4 getIMat()
Get the inverse matrix transformation.
Definition: Components.hpp:89
Engine::Collider::hook
Ref< CollisionHook > hook
does the collider physically interact with other objects (def not stolen from unity)
Definition: Components.hpp:34
Engine::VertexCollider2D
VertexCollider but in 2D. by default, all 2D colliders are non-kinematic triggers.
Definition: Components.hpp:503
Engine::Shape
Definition: Components.hpp:122
Engine::VertexCollider::boxCollider
static Ref< VertexCollider > boxCollider(float width=64, float height=64, float depth=64)
Generate a box collider with given dimensions. centered at 0,0,0.
Definition: Components.hpp:476
Engine::Simplex::index
size_t index
support point list (max 4)
Definition: Components.hpp:179
Engine::ForceGenerator
Generates a force.
Definition: Components.hpp:366
Engine::RigidBody::grounded
bool grounded
grounded flag
Definition: Components.hpp:436
Engine::Ref
std::shared_ptr< T > Ref
Has stuff for making references a lot more easily shared smart pointer.
Definition: Base.hpp:21
Engine::ForceApplier
Applies a force! to a colliding body or connected object.
Definition: Components.hpp:351
Engine::PhysicsEntity::w
glm::vec3 w
velocity
Definition: Components.hpp:60
Engine::PhysicsEntity::getMat
glm::mat4 getMat()
Get the matrix transformation made up of q and x.
Definition: Components.hpp:78
Engine::RigidBody::setMomentCube
void setMomentCube(float height, float width, float depth, float m)
Set the moment of inertia of this rigidbody to that of a solid cube.
Definition: Components.hpp:417
Engine::CollisionHook
Wrapper for processing collisions between physics entities.
Definition: Components.hpp:23
Engine::Transform::GetMatrix
glm::mat4 GetMatrix() const
extract a matrix from three vectors
Definition: Components.hpp:338
Engine::PhysicsEntity::tf
Ref< Transform > tf
transform reference
Definition: Components.hpp:52
Engine::RigidBody::force
glm::vec3 force
force vector
Definition: Components.hpp:385
Engine::Support
GJK support point structure. stores the resulting support point and the components that made it up....
Definition: Components.hpp:136
Engine::Allignment
Allignment
enumeration representing alignment of text in a string of text.
Definition: Components.hpp:358
Engine::CollisionPoint::HasCollision
bool HasCollision
does the point actually represent a collision
Definition: Components.hpp:168
Engine::RigidBody::t
glm::vec3 t
Torque.
Definition: Components.hpp:403
Engine::Transform::rotation
glm::qua< float > rotation
Rotation of entity in degrees.
Definition: Components.hpp:316
Engine::Joint::Joint
Joint(glm::vec3 globalPosition, float maxLength=0)
tether entity to a global coordinate
Definition: Components.hpp:303
Engine::Collider::processCollision
void processCollision(const Ref< PhysicsEntity > &other)
collision hook storage
Definition: Components.hpp:40
Engine::RigidBody::angularDrag
float angularDrag
air drag co-efficient
Definition: Components.hpp:390
Engine::PhysicsEntity::c
Ref< Collider > c
collider reference
Definition: Components.hpp:54
Engine::Transform::position
glm::vec3 position
Position of entity.
Definition: Components.hpp:314
Engine::PhysicsEntity::x
glm::vec3 x
angular momentum
Definition: Components.hpp:61
Engine::Transform::Transform
Transform(glm::vec3 p, glm::vec3 r, glm::vec3 s)
Definition: Components.hpp:324
Engine::FacePoint
Storage for the expanding polytope algorithm.
Definition: Components.hpp:240
Engine::Transform::Transform
Transform()=default
Engine::RigidBody::iMass
float iMass
inverse mass
Definition: Components.hpp:432
Engine::CollisionPoint::contacts
std::vector< glm::vec3 > contacts
contact points in global space
Definition: Components.hpp:164
Engine::VertexCollider
A Collider represented by a set of (convex) vertices.
Definition: Components.hpp:442
Engine::RigidBody::moment
glm::mat3 moment
moment of inertia
Definition: Components.hpp:396
Engine::PhysicsEntity::matUpdated
bool matUpdated
storage for a delta quat
Definition: Components.hpp:70
Engine::CollisionPoint::Normal
glm::vec3 Normal
normal vector
Definition: Components.hpp:162
Engine::RigidBody::velocity
glm::vec3 velocity
velocity vector
Definition: Components.hpp:383
Engine
Definition: Animation.hpp:14
Engine::Joint
Physics Component that represents a joint between rigidbodies. Intended to be connected to a Entity a...
Definition: Components.hpp:270
Engine::PhysicsEntity::clearMat
void clearMat()
Clear the matrix flags when the position or rotation is updated.
Definition: Components.hpp:99
Engine::Joint::Joint
Joint(glm::vec3 selfPosition, glm::vec3 globalPosition)
tether local entity position to a global coordinate position
Definition: Components.hpp:293
Engine::RigidBody::kinematic
bool kinematic
is the object affected by physics
Definition: Components.hpp:393
Engine::RigidBody::w
glm::vec3 w
Angular velocity.
Definition: Components.hpp:401
Engine::Transform::scale
glm::vec3 scale
Scale of enetity.
Definition: Components.hpp:318
Engine::RigidBody::invMoment
glm::mat3 invMoment
inverse moment of inertia
Definition: Components.hpp:398
Engine::Joint::Joint
Joint(Ref< RigidBody > &otherRigidBody, float maxLength)
Connect two rigid-bodies at their respective centers at a given distance apart.
Definition: Components.hpp:283
Engine::RigidBody
Physics rigidbody component. Stores the physical parameters of an object. Such as moment of inertia,...
Definition: Components.hpp:376
Engine::CollisionPoint
Definition: Components.hpp:160
Engine::RigidBody::physicsEntity
Ref< PhysicsEntity > physicsEntity
Reference to an active physics entity.
Definition: Components.hpp:406
Engine::RigidBody::airDrag
float airDrag
air drag co-efficient
Definition: Components.hpp:388
Engine::PhysicsEntity::dQ
glm::qua< float > dQ
previous quat
Definition: Components.hpp:67
Engine::PhysicsEntity::rb
Ref< RigidBody > rb
rigidbody reference
Definition: Components.hpp:57
Engine::PhysicsEntity
Links all the data necessary to compute physics calculations.
Definition: Components.hpp:45