Merge remote-tracking branch 'refs/remotes/origin/master' into enet_wip_nothing_to_see_here

This commit is contained in:
Jérôme Leclercq 2017-03-07 09:36:47 +01:00
commit 247186fe55
3 changed files with 73 additions and 6 deletions

View File

@ -11,6 +11,7 @@
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Physics2D/Config.hpp>
#include <Nazara/Physics2D/RigidBody2D.hpp>
#include <memory>
#include <unordered_map>
@ -19,10 +20,10 @@ struct cpSpace;
namespace Nz
{
class RigidBody2D;
class NAZARA_PHYSICS2D_API PhysWorld2D
{
friend RigidBody2D;
using ContactEndCallback = void(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata);
using ContactPreSolveCallback = bool(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata);
using ContactPostSolveCallback = void(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata);
@ -90,7 +91,23 @@ namespace Nz
private:
void InitCallbacks(cpCollisionHandler* handler, const Callback& callbacks);
using PostStep = std::function<void()>;
void OnRigidBodyMoved(RigidBody2D* oldPointer, RigidBody2D* newPointer);
void OnRigidBodyRelease(RigidBody2D* rigidBody);
void RegisterPostStep(RigidBody2D* rigidBody, PostStep&& func);
struct PostStepContainer
{
NazaraSlot(RigidBody2D, OnRigidBody2DMove, onMovedSlot);
NazaraSlot(RigidBody2D, OnRigidBody2DRelease, onReleaseSlot);
std::vector<PostStep> funcs;
};
std::unordered_map<cpCollisionHandler*, std::unique_ptr<Callback>> m_callbacks;
std::unordered_map<RigidBody2D*, PostStepContainer> m_rigidPostSteps;
cpSpace* m_handle;
float m_stepSize;
float m_timestepAccumulator;

View File

@ -164,6 +164,16 @@ namespace Nz
cpSpaceStep(m_handle, m_stepSize);
OnPhysWorld2DPostStep(this);
if (!m_rigidPostSteps.empty())
{
for (const auto& pair : m_rigidPostSteps)
{
for (const auto& step : pair.second.funcs)
step();
}
m_rigidPostSteps.clear();
}
m_timestepAccumulator -= m_stepSize;
}
@ -263,4 +273,41 @@ namespace Nz
};
}
}
void PhysWorld2D::OnRigidBodyMoved(RigidBody2D* oldPointer, RigidBody2D* newPointer)
{
auto it = m_rigidPostSteps.find(oldPointer);
if (it == m_rigidPostSteps.end())
return; //< Shouldn't happen
m_rigidPostSteps.emplace(std::make_pair(newPointer, std::move(it->second)));
m_rigidPostSteps.erase(oldPointer);
}
void PhysWorld2D::OnRigidBodyRelease(RigidBody2D* rigidBody)
{
m_rigidPostSteps.erase(rigidBody);
}
void PhysWorld2D::RegisterPostStep(RigidBody2D* rigidBody, PostStep&& func)
{
// If space isn't locked, no need to wait
if (!cpSpaceIsLocked(m_handle))
{
func();
return;
}
auto it = m_rigidPostSteps.find(rigidBody);
if (it == m_rigidPostSteps.end())
{
PostStepContainer postStep;
postStep.onMovedSlot.Connect(rigidBody->OnRigidBody2DMove, this, &PhysWorld2D::OnRigidBodyMoved);
postStep.onReleaseSlot.Connect(rigidBody->OnRigidBody2DRelease, this, &PhysWorld2D::OnRigidBodyRelease);
it = m_rigidPostSteps.insert(std::make_pair(rigidBody, std::move(postStep))).first;
}
it->second.funcs.emplace_back(std::move(func));
}
}

View File

@ -249,15 +249,18 @@ namespace Nz
cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass));
}
else
cpBodySetType(m_handle, CP_BODY_TYPE_STATIC);
m_world->RegisterPostStep(this, [this]() { cpBodySetType(m_handle, CP_BODY_TYPE_STATIC); } );
}
else if (mass > 0.f)
{
if (cpBodyGetType(m_handle) == CP_BODY_TYPE_STATIC)
{
cpBodySetType(m_handle, CP_BODY_TYPE_DYNAMIC);
cpBodySetMass(m_handle, mass);
cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass));
m_world->RegisterPostStep(this, [this, mass]()
{
cpBodySetType(m_handle, CP_BODY_TYPE_DYNAMIC);
cpBodySetMass(m_handle, mass);
cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass));
});
}
}