CoriEngine
Loading...
Searching...
No Matches
WorldSystem/Systems/Physics.cpp
Go to the documentation of this file.
1#include "Physics.hpp"
2#include "Physics/Physics.hpp"
5
6#ifndef CORI_MAX_PHYSICS_THREADS
7 #define CORI_MAX_PHYSICS_THREADS 4
8#endif
9
10namespace Cori {
11 namespace World {
12 namespace Systems {
16 m_CurrentTaskIndex.store(0, std::memory_order_relaxed);
17 }
18 m_World.Step(gameTimer.GetTimestep(), 4);
19 //m_Owner.GetContextComponent<Components::Scene::PhysicsWorld>().Step(gameTimer.GetTimestep(), 4);
20 }
21
22 bool PhysicsSystem::Create(Cori::Physics::World::Params params) {
25 m_WorkerCount = 1;
27 m_WorkerCount = CORI_MAX_PHYSICS_THREADS;
28 } else {
29 m_WorkerCount = Core::Application::GetWorkerCount() - 1;
30 }
31
32 params.workerCount = m_WorkerCount;
33 params.enqueueTask = EnqueueTask;
34 params.finishTask = FinishTask;
35 params.userTaskContext = this;
36 //m_Owner.AddContextComponent<Components::Scene::PhysicsWorld>(params);
37 }
38
39 m_World = Cori::Physics::World(params);
40
41 m_Owner.GetRegistry().on_construct<Components::Entity::RigidBody>().connect<&PhysicsSystem::OnRigidBodyCreate>(this);
42 return true;
43 }
44
45 void* PhysicsSystem::EnqueueTask(b2TaskCallback* task, int32_t itemCount, int32_t minRange, void* taskContext, void* userContext) {
46 auto* physicsSystem = static_cast<PhysicsSystem*>(userContext);
47 const uint16_t workerCount = physicsSystem->m_WorkerCount;
48
49 if (workerCount <= 1 || itemCount < minRange) {
50 task(0, itemCount, 0, taskContext);
51 return nullptr;
52 }
53
54 const uint16_t taskIndex = physicsSystem->m_CurrentTaskIndex.fetch_add(1, std::memory_order_relaxed);
55 CORI_CORE_ASSERT(taskIndex < CORI_PHYSICS_TASK_POOL_SIZE, "Exceeded the pre-allocated Box2D task pool size!");
56
57 Box2DTaskGroup& taskGroup = physicsSystem->m_TaskPool[taskIndex];
58
59 taskGroup.futures.clear();
60
61 int32_t itemsPerThread = (itemCount + workerCount - 1) / workerCount;
62 itemsPerThread = std::max(itemsPerThread, minRange);
63
64 int32_t startIndex = 0;
65 for (uint16_t i = 0; i < workerCount && startIndex < itemCount; ++i) {
66 const int32_t endIndex = std::min(startIndex + itemsPerThread, itemCount);
67
68 taskGroup.futures.push_back(Core::Application::SubmitWorkerTask(
69 [=]() {
70 task(startIndex, endIndex, i, taskContext);
71 }
72 ));
73 startIndex = endIndex;
74 }
75
76 return &taskGroup;
77 }
78
79 void PhysicsSystem::FinishTask(void* taskPtr, void* userContext) {
80 if (taskPtr == nullptr) {
81 return;
82 }
83
84 auto* taskGroup = static_cast<Box2DTaskGroup*>(taskPtr);
85
86 for (auto& future : taskGroup->futures) {
87 future.get();
88 }
89 }
90
91 void PhysicsSystem::OnRigidBodyCreate(entt::registry& registry, entt::entity entity) {
92 Entity e = entt::handle{ registry, entity };
94 const auto type = rb.GetType();
95 if (type == b2_kinematicBody || type == b2_dynamicBody) {
97 rb.SetUserData(&ud);
98 }
99 }
100 }
101 }
102}
#define CORI_MULTITHREADED_PHYSICS
#define CORI_PHYSICS_TASK_POOL_SIZE
#define CORI_MAX_PHYSICS_THREADS
#define CORI_CORE_ASSERT(x,...)
Definition Logger.hpp:1029
#define CORI_PROFILE_FUNCTION()
Definition Profiler.hpp:9
static std::future< std::invoke_result_t< F, Args... > > SubmitWorkerTask(F &&f, Args &&... args)
Submits a task to be executed on the worker thread.
static uint16_t GetWorkerCount()
Returns a number of available worker threads.
A GameTimer is responsible for managing everything that is connected with time, ticks,...
Definition Time.hpp:8
float GetTimestep() const
Returns the current timeStep, scale is in seconds.
Definition Time.hpp:31
Entities are the essential part of WorldSystem.
Definition Entity.hpp:25
T & AddComponent(Args &&... args)
Adds a component to the entity.
Definition Entity.hpp:39
decltype(auto) GetComponents()
Retries the references to the requested components of the entity.
Definition Entity.hpp:74
SceneHandle m_Owner
Definition System.hpp:38
static void FinishTask(void *taskPtr, void *userContext)
bool Create(Physics::World::Params params)
void OnTickUpdate(Core::GameTimer &gameTimer) override
static void * EnqueueTask(b2TaskCallback *task, int32_t itemCount, int32_t minRange, void *taskContext, void *userContext)
Global engine namespace.