Physics now running on multiple threads
This commit is contained in:
+54
-32
@@ -32,6 +32,18 @@ void GameWorld::Initialize()
|
||||
CommitEntity(ground);
|
||||
}
|
||||
|
||||
{
|
||||
auto camera = CreateEntity();
|
||||
auto transform = AddComponent<Components::Transform>(camera, "Transform");
|
||||
transform->Position.z = 20.f;
|
||||
transform->Position.y = 10.f;
|
||||
transform->Orientation = glm::quat(glm::vec3(-glm::pi<float>() / 8.f, 0.f, 0.f));
|
||||
auto cameraComp = AddComponent<Components::Camera>(camera, "Camera");
|
||||
cameraComp->FarClip = 2000.f;
|
||||
AddComponent(camera, "Input");
|
||||
auto freeSteering = AddComponent<Components::FreeSteering>(camera, "FreeSteering");
|
||||
CommitEntity(camera);
|
||||
}
|
||||
|
||||
{
|
||||
auto jeep = CreateEntity();
|
||||
@@ -60,20 +72,6 @@ void GameWorld::Initialize()
|
||||
|
||||
AddComponent<Components::Input>(jeep, "Input");
|
||||
|
||||
|
||||
{
|
||||
auto camera = CreateEntity();
|
||||
auto transform = AddComponent<Components::Transform>(camera, "Transform");
|
||||
transform->Position.z = 20.f;
|
||||
transform->Position.y = 10.f;
|
||||
transform->Orientation = glm::quat(glm::vec3(-glm::pi<float>() / 8.f, 0.f, 0.f));
|
||||
auto cameraComp = AddComponent<Components::Camera>(camera, "Camera");
|
||||
cameraComp->FarClip = 2000.f;
|
||||
AddComponent(camera, "Input");
|
||||
auto freeSteering = AddComponent<Components::FreeSteering>(camera, "FreeSteering");
|
||||
CommitEntity(camera);
|
||||
}
|
||||
|
||||
{
|
||||
auto chassis = CreateEntity(jeep);
|
||||
auto transform = AddComponent<Components::Transform>(chassis, "Transform");
|
||||
@@ -160,24 +158,48 @@ void GameWorld::Initialize()
|
||||
CommitEntity(jeep);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 0; i++)
|
||||
{
|
||||
auto cube = CreateEntity();
|
||||
auto transform = AddComponent<Components::Transform>(cube, "Transform");
|
||||
transform->Position = glm::vec3(20, 10 + i*2, 0);
|
||||
transform->Scale = glm::vec3(1);
|
||||
transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
auto model = AddComponent<Components::Model>(cube, "Model");
|
||||
model->ModelFile = "Models/cardboardBox/BoxFixed.obj";
|
||||
|
||||
auto physics = AddComponent<Components::Physics>(cube, "Physics");
|
||||
physics->Mass = 100;
|
||||
auto box = AddComponent<Components::BoxShape>(cube, "BoxShape");
|
||||
box->Width = 0.5f;
|
||||
box->Height = 0.5f;
|
||||
box->Depth = 0.5f;
|
||||
CommitEntity(cube);
|
||||
}
|
||||
|
||||
for (int x = 0; x < 5; x++)
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
auto cube = CreateEntity();
|
||||
auto transform = AddComponent<Components::Transform>(cube, "Transform");
|
||||
transform->Position = glm::vec3(3 * x + 0.1f + 20.f, 3 * y + 0.1f + 1.f, 0);
|
||||
transform->Scale = glm::vec3(3);
|
||||
transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
auto model = AddComponent<Components::Model>(cube, "Model");
|
||||
model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj";
|
||||
|
||||
auto physics = AddComponent<Components::Physics>(cube, "Physics");
|
||||
physics->Mass = 100;
|
||||
auto box = AddComponent<Components::BoxShape>(cube, "BoxShape");
|
||||
box->Width = 1.5f;
|
||||
box->Height = 1.5f;
|
||||
box->Depth = 1.5f;
|
||||
CommitEntity(cube);
|
||||
}
|
||||
|
||||
/*for (int x = 0; x < 5; x++)
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
auto cube = CreateEntity();
|
||||
auto transform = AddComponent<Components::Transform>(cube, "Transform");
|
||||
transform->Position = glm::vec3(3 * x + 0.1f + -20.f, 3 * y + 0.1f + 1.f, 0);
|
||||
transform->Scale = glm::vec3(3);
|
||||
transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
auto model = AddComponent<Components::Model>(cube, "Model");
|
||||
model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj";
|
||||
|
||||
auto physics = AddComponent<Components::Physics>(cube, "Physics");
|
||||
physics->Mass = 100;
|
||||
auto box = AddComponent<Components::BoxShape>(cube, "BoxShape");
|
||||
box->Width = 1.5f;
|
||||
box->Height = 1.5f;
|
||||
box->Depth = 1.5f;
|
||||
CommitEntity(cube);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*{
|
||||
auto entity = CreateEntity();
|
||||
|
||||
@@ -28,36 +28,81 @@
|
||||
Systems::PhysicsSystem::PhysicsSystem(World* world) : System(world)
|
||||
{
|
||||
m_Accumulator = 0;
|
||||
|
||||
hkMemorySystem::FrameInfo finfo(500 * 1024); // Allocate 500KB of Physics solver buffer
|
||||
hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, finfo);
|
||||
hkBaseSystem::init(memoryRouter, HavokErrorReport);
|
||||
|
||||
|
||||
// Get the number of physical threads available on the system
|
||||
hkHardwareInfo hwInfo;
|
||||
hkGetHardwareInfo(hwInfo);
|
||||
m_TotalNumThreadsUsed = hwInfo.m_numThreads;
|
||||
|
||||
// We use one less than this for our thread pool, because we must also use this thread for our simulation
|
||||
hkCpuJobThreadPoolCinfo threadPoolCinfo;
|
||||
threadPoolCinfo.m_numThreads = m_TotalNumThreadsUsed - 1;
|
||||
|
||||
// This line enables timers collection, by allocating 200 Kb per thread. If you leave this at its default (0),
|
||||
// timer collection will not be enabled.
|
||||
threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;
|
||||
m_ThreadPool = new hkCpuJobThreadPool(threadPoolCinfo);
|
||||
|
||||
hkJobQueueCinfo info;
|
||||
info.m_jobQueueHwSetup.m_numCpuThreads = m_TotalNumThreadsUsed;
|
||||
m_JobQueue = new hkJobQueue(info);
|
||||
|
||||
//
|
||||
// Enable monitors for this thread.
|
||||
//
|
||||
|
||||
// Monitors have been enabled for thread pool threads already (see above comment).
|
||||
hkMonitorStream::getInstance().resize(200000);
|
||||
|
||||
{
|
||||
hkMemorySystem::FrameInfo finfo(500 * 1024); // Allocate 500KB of Physics solver buffer
|
||||
hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, finfo);
|
||||
hkBaseSystem::init(memoryRouter, HavokErrorReport);
|
||||
|
||||
|
||||
hkpWorldCinfo worldInfo;
|
||||
|
||||
// Set the simulation type of the world to multi-threaded.
|
||||
worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;
|
||||
|
||||
worldInfo.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM);
|
||||
worldInfo.m_gravity = hkVector4(0.0f, -9.8f, 0.0f);
|
||||
worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_FIX_ENTITY; // just fix the entity if the object falls off too far
|
||||
worldInfo.m_gravity = hkVector4(0.0f, -9.82f, 0.0f);
|
||||
worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_REMOVE_ENTITY; // just fix the entity if the object falls off too far
|
||||
|
||||
// You must specify the size of the broad phase - objects should not be simulated outside this region
|
||||
worldInfo.setBroadPhaseWorldSize(1000.0f);
|
||||
m_PhysicsWorld = new hkpWorld(worldInfo);
|
||||
}
|
||||
// Register all collision agents, even though only box - box will be used in this particular example.
|
||||
// It's important to register collision agents before adding any entities to the world.
|
||||
hkpAgentRegisterUtil::registerAllAgents(m_PhysicsWorld->getCollisionDispatcher());
|
||||
|
||||
//
|
||||
// Initialize the visual debugger so we can connect remotely to the simulation
|
||||
// The context must exist beyond the use of the VDB instance, and you can make
|
||||
// whatever contexts you like for your own viewer types.
|
||||
//
|
||||
hkpPhysicsContext* context = new hkpPhysicsContext;
|
||||
hkpPhysicsContext::registerAllPhysicsProcesses(); // all the physics viewers
|
||||
context->addWorld(m_PhysicsWorld); // add the physics world so the viewers can see it
|
||||
SetupVisualDebugger(context);
|
||||
|
||||
//SetupPhysics(m_PhysicsWorld);
|
||||
|
||||
|
||||
|
||||
// When the simulation type is SIMULATION_TYPE_MULTITHREADED, in the debug build, the sdk performs checks
|
||||
// to make sure only one thread is modifying the world at once to prevent multithreaded bugs. Each thread
|
||||
// must call markForRead / markForWrite before it modifies the world to enable these checks.
|
||||
m_PhysicsWorld->markForWrite();
|
||||
|
||||
// Register all collision agents, even though only box - box will be used in this particular example.
|
||||
// It's important to register collision agents before adding any entities to the world.
|
||||
hkpAgentRegisterUtil::registerAllAgents(m_PhysicsWorld->getCollisionDispatcher());
|
||||
|
||||
// We need to register all modules we will be running multi-threaded with the job queue
|
||||
m_PhysicsWorld->registerWithJobQueue(m_JobQueue);
|
||||
|
||||
|
||||
//
|
||||
// Initialize the visual debugger so we can connect remotely to the simulation
|
||||
// The context must exist beyond the use of the VDB instance, and you can make
|
||||
// whatever contexts you like for your own viewer types.
|
||||
//
|
||||
m_Context = new hkpPhysicsContext;
|
||||
hkpPhysicsContext::registerAllPhysicsProcesses(); // all the physics viewers
|
||||
m_Context->addWorld(m_PhysicsWorld); // add the physics world so the viewers can see it
|
||||
|
||||
SetupVisualDebugger(m_Context);
|
||||
|
||||
m_PhysicsWorld->unmarkForWrite();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Systems::PhysicsSystem::RegisterComponents(ComponentFactory* cf)
|
||||
@@ -86,9 +131,11 @@ void Systems::PhysicsSystem::Update(double dt)
|
||||
|
||||
if(m_RigidBodies[entity]->isActive())
|
||||
{
|
||||
m_PhysicsWorld->markForWrite();
|
||||
hkVector4 position(transformComponent->Position.x, transformComponent->Position.y, transformComponent->Position.z);
|
||||
hkQuaternion rotation(transformComponent->Orientation.x, transformComponent->Orientation.y, transformComponent->Orientation.z, transformComponent->Orientation.w);
|
||||
m_RigidBodies[entity]->setPositionAndRotation(position, rotation);
|
||||
m_PhysicsWorld->unmarkForWrite();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -100,12 +147,18 @@ void Systems::PhysicsSystem::Update(double dt)
|
||||
m_Accumulator += dt;
|
||||
while (m_Accumulator >= timestep)
|
||||
{
|
||||
m_PhysicsWorld->stepDeltaTime(timestep);
|
||||
m_PhysicsWorld->stepMultithreaded(m_JobQueue, m_ThreadPool, timestep);
|
||||
m_Accumulator -= timestep;
|
||||
}
|
||||
|
||||
// Step the visual debugger
|
||||
StepVisualDebugger();
|
||||
m_Context->syncTimers(m_ThreadPool);
|
||||
// Step the visual debugger
|
||||
StepVisualDebugger();
|
||||
}
|
||||
|
||||
|
||||
// Clear accumulated timer data in this thread and all slave threads
|
||||
hkMonitorStream::getInstance().reset();
|
||||
m_ThreadPool->clearTimerData();
|
||||
}
|
||||
|
||||
void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent)
|
||||
@@ -120,6 +173,7 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p
|
||||
EntityID car = m_World->GetEntityParent(entity);
|
||||
if(m_Vehicles.find(car) != m_Vehicles.end())
|
||||
{
|
||||
m_PhysicsWorld->markForWrite();
|
||||
m_Vehicles[car]->getChassis()->activate();
|
||||
|
||||
hkVector4 hardPoint = m_Vehicles[car]->m_suspension->m_wheelParams[wheelComponent->ID].m_hardpointChassisSpace;
|
||||
@@ -132,22 +186,26 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p
|
||||
hkReal spinAngle = -m_Vehicles[car]->m_wheelsInfo[wheelComponent->ID].m_spinAngle;
|
||||
glm::quat orientation = glm::quat(steeringOrientation(3), steeringOrientation(0), steeringOrientation(1), steeringOrientation(2)) * glm::angleAxis<float>(spinAngle, glm::vec3(1, 0, 0));
|
||||
transformComponent->Orientation = orientation * wheelComponent->OriginalOrientation;
|
||||
m_PhysicsWorld->unmarkForWrite();
|
||||
}
|
||||
}
|
||||
else if(m_Vehicles.find(entity) != m_Vehicles.end())
|
||||
{
|
||||
m_PhysicsWorld->markForWrite();
|
||||
hkVector4 position = m_RigidBodies[entity]->getPosition();
|
||||
transformComponent->Position = glm::vec3(position(0), position(1), position(2));
|
||||
hkQuaternion orientation = m_RigidBodies[entity]->getRotation();
|
||||
transformComponent->Orientation = glm::quat(orientation(3),orientation(0), orientation(1), orientation(2));
|
||||
|
||||
transformComponent->Orientation = glm::quat(orientation(3), orientation(0), orientation(1), orientation(2));
|
||||
m_PhysicsWorld->unmarkForWrite();
|
||||
}
|
||||
else if(m_RigidBodies.find(entity) != m_RigidBodies.end())
|
||||
{
|
||||
m_PhysicsWorld->markForWrite();
|
||||
hkVector4 position = m_RigidBodies[entity]->getPosition();
|
||||
transformComponent->Position = glm::vec3(position(0), position(1), position(2));
|
||||
hkQuaternion orientation = m_RigidBodies[entity]->getRotation();
|
||||
transformComponent->Orientation = glm::quat(orientation(3),orientation(0), orientation(1), orientation(2));
|
||||
m_PhysicsWorld->unmarkForWrite();
|
||||
}
|
||||
|
||||
|
||||
@@ -156,10 +214,12 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p
|
||||
auto inputComponent = m_World->GetComponent<Components::Input>(entity, "Input");
|
||||
if (vehicleComponent && inputComponent)
|
||||
{
|
||||
m_PhysicsWorld->markForWrite();
|
||||
hkpVehicleDriverInputAnalogStatus* deviceStatus = (hkpVehicleDriverInputAnalogStatus*)m_Vehicles[entity]->m_deviceStatus;
|
||||
deviceStatus->m_positionY = inputComponent->KeyState[GLFW_KEY_UP] * -1 + inputComponent->KeyState[GLFW_KEY_DOWN] * 1;
|
||||
deviceStatus->m_positionX = inputComponent->KeyState[GLFW_KEY_LEFT] * -1 + inputComponent->KeyState[GLFW_KEY_RIGHT] * 1;
|
||||
deviceStatus->m_handbrakeButtonPressed = inputComponent->KeyState[GLFW_KEY_RIGHT_CONTROL];
|
||||
m_PhysicsWorld->unmarkForWrite();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,13 +304,7 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity )
|
||||
{
|
||||
for (auto &faceDef : face.Definitions)
|
||||
{
|
||||
/*hkReal x, y, z;
|
||||
std::tie(x, y, z) = meshShape->Vertices.at(faceDef.VertexIndex - 1);
|
||||
vertices.push_back(x);
|
||||
vertices.push_back(y);
|
||||
vertices.push_back(z);*/
|
||||
vertexIndices->push_back(faceDef.VertexIndex - 1);
|
||||
//vertexIndices.push_back(i++);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,8 +369,9 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity )
|
||||
i--;
|
||||
}
|
||||
}
|
||||
VehicleSetup vehicleSetup;
|
||||
m_PhysicsWorld->markForWrite();
|
||||
|
||||
VehicleSetup vehicleSetup;
|
||||
// Create the basic vehicle.
|
||||
m_Vehicles[entity] = new hkpVehicleInstance(rigidBody);
|
||||
vehicleSetup.buildVehicle(m_World, m_PhysicsWorld, *m_Vehicles[entity], entity, m_Wheels);
|
||||
@@ -327,6 +382,7 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity )
|
||||
|
||||
// The vehicle is an action
|
||||
m_PhysicsWorld->addAction(m_Vehicles[entity]);
|
||||
m_PhysicsWorld->unmarkForWrite();
|
||||
|
||||
//m_Vehicles[entity]->m_rpm = 0.0f; // Not sure why this one should be here
|
||||
m_Wheels.clear();
|
||||
@@ -335,9 +391,11 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity )
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PhysicsWorld->markForWrite();
|
||||
m_PhysicsWorld->addEntity(rigidBody);
|
||||
m_RigidBodies[entity] = rigidBody;
|
||||
|
||||
m_PhysicsWorld->unmarkForWrite();
|
||||
|
||||
shape->removeReference();
|
||||
rigidBody->removeReference();
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
|
||||
#include <Physics2012/Collide/Shape/Compound/Collection/ExtendedMeshShape/hkpExtendedMeshShape.h>
|
||||
|
||||
#include <Common/Base/Thread/JobQueue/hkJobQueue.h>
|
||||
#include <Common/Base/Thread/Job/ThreadPool/Cpu/hkCpuJobThreadPool.h>
|
||||
#include <Common/Base/DebugUtil/MultiThreadCheck/hkMultiThreadCheck.h>
|
||||
|
||||
#include "Physics/VehicleSetup.h"
|
||||
|
||||
#include <unordered_map>
|
||||
@@ -71,6 +75,10 @@ private:
|
||||
|
||||
std::unordered_map<EntityID, hkpRigidBody*> m_RigidBodies;
|
||||
|
||||
hkJobThreadPool* m_ThreadPool;
|
||||
hkJobQueue* m_JobQueue;
|
||||
int m_TotalNumThreadsUsed;
|
||||
hkpPhysicsContext* m_Context;
|
||||
|
||||
std::unordered_map<EntityID, hkpVehicleInstance*> m_Vehicles;
|
||||
std::vector<EntityID> m_Wheels;
|
||||
|
||||
Reference in New Issue
Block a user