Engine
Frameworkcreatedbymeusableforthecreationofsimplegames.CurrentlysupportsOpenGL(Verysimple)andVulkan.
CollisionSystem.cpp
Go to the documentation of this file.
2 
3 #include "Engine/engine.hpp"
6 
7 // To cast the int to void* without getting compiler warnings
8 #define INT_TO_VOID_PTR(val) ((void*)(size_t) val)
9 
10 namespace Engine
11 {
12 
13  CollisionSystem::CollisionSystem() : world_(b2Vec2(0, 0)), isRunning_(false)
14  {
15  world_.SetAllowSleeping(false);
16  }
17 
19  {
20  }
21 
22  void CollisionSystem::AddCollisionComponent(eastl::weak_ptr<CollisionComponent> componentToAdd)
23  {
24  collisionComponents_.push_back(componentToAdd);
25 
26  // Generate a Collision Body
27  componentToAdd.lock()->body = world_.CreateBody(&(componentToAdd.lock()->bodyDef));
28  componentToAdd.lock()->body->CreateFixture(&(componentToAdd.lock()->fixtureDef));
29  componentToAdd.lock()->body->GetFixtureList()->SetUserData(INT_TO_VOID_PTR(componentToAdd.lock()->GetOwner().lock()->GetID()));
30  }
31 
32  void CollisionSystem::RemoveCollisionComponent(CollisionComponent* componentToRemove)
33  {
34  if (world_.GetBodyCount() == 0)
35  return;
36  if (componentToRemove == nullptr)
37  return;
38  if (componentToRemove->body == nullptr)
39  return;
40 
41  world_.DestroyBody(componentToRemove->body);
42  }
43 
44  void CollisionSystem::OnLevelLoaded()
45  {
46  if (collisionComponents_.size() > 0)
47  Start();
48  }
49 
50  void CollisionSystem::OnLevelUnloaded()
51  {
52  if (isRunning_ == false)
53  return;
54 
55  Stop();
56  collisionComponents_.clear();
57  }
58 
60  {
61  ClearWorld();
62  isRunning_ = false;
63  }
64 
66  {
67  ClearWorld();
68  isRunning_ = true;
69  }
70 
72  {
73  // m_isRunning = true; // Use this to remove the assert if you're not working with the collision system, just don't submit it
74  if (isRunning_ == false)
75  return; // Call CollisionSystem::Start() before calling CollisionSystem::Update()!
76 
77  world_.SetContactListener(&entityContactCallback_);
78 
79  // Update World Positions with Transform Components positions
80  for (auto colComp : collisionComponents_)
81  {
82  eastl::weak_ptr<TransformComponent> transform = colComp.lock()->GetTransformComponent();
83  if (transform.expired() == false) // Collision Component Requires Transform!
84  continue;
85 
86  const glm::vec3 position = transform.lock()->GetPosition();
87  colComp.lock()->body->SetTransform(b2Vec2(position.x, position.y), colComp.lock()->body->GetAngle());
88  }
89 
90  // Update World
91  const float deltaTime = Engine::GetEngine().lock()->GetTime().lock()->GetDeltaTime();
92  world_.Step(deltaTime, 8, 4);
93 
94  // Update Transform Positions with World Positions
95  for (auto colComp : collisionComponents_)
96  {
97  eastl::weak_ptr<TransformComponent> transform = colComp.lock()->GetTransformComponent();
98  if (transform.expired() == false) // Collision Component Requires Transform!
99  continue;
100 
101  const glm::vec3 oldPosition = transform.lock()->GetPosition();
102  const b2Vec2& position = colComp.lock()->body->GetPosition();
103 
104  transform.lock()->SetPosition(glm::vec3(position.x, position.y, oldPosition.z));
105  }
106  entityContactCallback_ = EntityContact();
107  }
108 
109  eastl::weak_ptr<Entity> CollisionSystem::RayQueryFirstHit(const glm::vec2& start, const glm::vec2& end, CollisionLayer detectionLayers) const
110  {
111  RayCastClosestCallback callback;
112  callback.detectionLayers = detectionLayers;
113 
114  // Raycast of 0 distance causes assert error in Box2D
115  if(start == end)
116  {
117  return eastl::weak_ptr<Entity>();
118  }
119 
120  world_.RayCast(&callback, b2Vec2(start.x, start.y), b2Vec2(end.x, end.y));
121 
122  return callback.entity;
123  }
124 
125  // TODO - Implementation
126  eastl::weak_ptr<Entity> CollisionSystem::RayQueryAllHit(const glm::vec2& start, const glm::vec2& end) const
127  {
128  return eastl::weak_ptr<Entity>();
129  }
130 
132  {
133  return isRunning_;
134  }
135 
136  eastl::vector<eastl::weak_ptr<CollisionComponent>> CollisionSystem::GetActiveCollisionComponents() const
137  {
138  return collisionComponents_;
139  }
140 
141  void CollisionSystem::ClearWorld()
142  {
143  b2Body* body = world_.GetBodyList();
144 
145  while (body != nullptr)
146  {
147  b2Body* nextBody = body->GetNext();
148  world_.DestroyBody(body);
149  body = nextBody;
150  }
151  }
152 
153 }
void Start()
Starts the Collision System, gathering all required component data and generating collision bodies fr...
void Update()
Updates the collision world. Takes transform data of collision components, changes it...
bool IsRunning() const
Returns true if the Collision system is running
eastl::weak_ptr< Entity > RayQueryAllHit(const glm::vec2 &start, const glm::vec2 &end) const
Returns all collision-objects hit by the ray. TODO - Implementation
The Collision component is an entities link to the Collision System and allows for interaction with t...
eastl::vector< eastl::weak_ptr< CollisionComponent > > GetActiveCollisionComponents() const
Gets all of the collision components that are currently active in the world.
Gets the first entity hit by the ray Callback class used to get collision data from ray queries ...
static eastl::weak_ptr< Engine > GetEngine() noexcept
This method allows you to get the instance of the Engine. This method will automatically initialize t...
Definition: engine.cpp:130
CollisionLayer
Bitmask Enum that allows for layered collision checking
eastl::weak_ptr< Entity > RayQueryFirstHit(const glm::vec2 &start, const glm::vec2 &end, CollisionLayer detectionLayers) const
Returns the first collision-body hit by the ray. TODO - Implementation
void Stop()
Stops the Collision System, emptying m_collisionComponents Prevents further calls to Update()...
#define INT_TO_VOID_PTR(val)