Fixed precision loss in physics accumulator
This commit is contained in:
@@ -57,8 +57,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
b2Vec2 m_Gravity;
|
b2Vec2 m_Gravity;
|
||||||
b2World* m_PhysicsWorld;
|
b2World* m_PhysicsWorld;
|
||||||
float m_TimeStep;
|
double m_TimeStep;
|
||||||
float m_Accumulator;
|
double m_Accumulator;
|
||||||
|
|
||||||
int m_VelocityIterations, m_PositionIterations;
|
int m_VelocityIterations, m_PositionIterations;
|
||||||
|
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
#ifndef DAYDREAM_PHYSICSSYSTEM_H
|
|
||||||
#define DAYDREAM_PHYSICSSYSTEM_H
|
|
||||||
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include "Core/System.h"
|
|
||||||
#include "Core/World.h"
|
|
||||||
#include "CRectangleShape.h"
|
|
||||||
#include "Physics/CPhysics.h"
|
|
||||||
#include <Box2D/Box2D.h>
|
|
||||||
#include "Core/CTransform.h"
|
|
||||||
#include "Transform/TransformSystem.h"
|
|
||||||
#include "Physics/EContact.h"
|
|
||||||
#include "Physics/ESetImpulse.h"
|
|
||||||
#include "Physics/CCircleShape.h"
|
|
||||||
#include "Core/EventBroker.h"
|
|
||||||
#include "Game/CPad.h"
|
|
||||||
<<<<<<< HEAD
|
|
||||||
#include "Game/CBall.h"
|
|
||||||
=======
|
|
||||||
#include "Physics/CWaterVolume.h"
|
|
||||||
#include "Rendering/CSprite.h"
|
|
||||||
>>>>>>> origin/master
|
|
||||||
|
|
||||||
|
|
||||||
namespace dd
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace Systems
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class PhysicsSystem : public System
|
|
||||||
{
|
|
||||||
friend class ContractListener;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PhysicsSystem(World* world, std::shared_ptr<dd::EventBroker> eventBroker)
|
|
||||||
: System(world, eventBroker) {}
|
|
||||||
|
|
||||||
~PhysicsSystem();
|
|
||||||
|
|
||||||
EventRelay<PhysicsSystem, Events::SetImpulse> m_SetImpulse;
|
|
||||||
bool SetImpulse(const Events::SetImpulse &event);
|
|
||||||
|
|
||||||
void RegisterComponents(ComponentFactory* cf) override;
|
|
||||||
void Initialize() override;
|
|
||||||
|
|
||||||
// Called once per system every tick
|
|
||||||
void Update(double dt) override;
|
|
||||||
// Called once for every entity in the world every tick
|
|
||||||
void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
|
|
||||||
|
|
||||||
// Called when components are committed to an entity
|
|
||||||
void OnEntityCommit(EntityID entity) override;
|
|
||||||
|
|
||||||
// Called when an entity is removed
|
|
||||||
void OnEntityRemoved(EntityID entity) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
b2Vec2 m_Gravity;
|
|
||||||
b2World* m_PhysicsWorld;
|
|
||||||
float m_TimeStep;
|
|
||||||
float m_Accumulator;
|
|
||||||
|
|
||||||
int m_VelocityIterations, m_PositionIterations;
|
|
||||||
|
|
||||||
std::unordered_map<EntityID, b2Body*> m_EntitiesToBodies;
|
|
||||||
std::unordered_map<b2Body*, EntityID> m_BodiesToEntities;
|
|
||||||
|
|
||||||
void CreateBody(EntityID entity);
|
|
||||||
|
|
||||||
b2ParticleSystem *m_ParticleSystem;
|
|
||||||
b2ParticleGroup* t_watergroup;
|
|
||||||
|
|
||||||
std::unordered_map<EntityID, const b2ParticleHandle*> m_EntitiesToParticleHandle;
|
|
||||||
std::unordered_map<const b2ParticleHandle*, EntityID> m_ParticleHandleToEntities;
|
|
||||||
|
|
||||||
void InitializeWater();
|
|
||||||
void SyncWater(); //TODO: Probably remove this
|
|
||||||
void CreateParticleGroup(EntityID entity);
|
|
||||||
|
|
||||||
struct Impulse
|
|
||||||
{
|
|
||||||
b2Body* Body;
|
|
||||||
b2Vec2 Impulse;
|
|
||||||
b2Vec2 Point;
|
|
||||||
};
|
|
||||||
std::list<Impulse> m_Impulses;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ContactListener : public b2ContactListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ContactListener(PhysicsSystem* physicsSystem)
|
|
||||||
: m_PhysicsSystem(physicsSystem) { }
|
|
||||||
|
|
||||||
void BeginContact(b2Contact* contact)
|
|
||||||
{
|
|
||||||
b2WorldManifold worldManifold;
|
|
||||||
|
|
||||||
contact->GetWorldManifold(&worldManifold);
|
|
||||||
|
|
||||||
Events::Contact e;
|
|
||||||
e.Entity1 = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureA()->GetBody()];
|
|
||||||
e.Entity2 = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureB()->GetBody()];
|
|
||||||
e.Normal = glm::normalize(glm::vec2(contact->GetManifold()->localNormal.x, contact->GetManifold()->localNormal.y));
|
|
||||||
e.SignificantNormal = glm::normalize((glm::abs(e.Normal.x) > glm::abs(e.Normal.y)) ? glm::vec2(e.Normal.x, 0) : glm::vec2(0, e.Normal.y));
|
|
||||||
|
|
||||||
m_PhysicsSystem->EventBroker->Publish(e);
|
|
||||||
}
|
|
||||||
void EndContact(b2Contact* contact)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
|
|
||||||
{
|
|
||||||
EntityID entityA = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureA()->GetBody()];
|
|
||||||
EntityID entityB = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureB()->GetBody()];
|
|
||||||
|
|
||||||
auto physicsComponentA = m_PhysicsSystem->m_World->GetComponent<Components::Physics>(entityA);
|
|
||||||
auto physicsComponentB = m_PhysicsSystem->m_World->GetComponent<Components::Physics>(entityB);
|
|
||||||
|
|
||||||
if (physicsComponentA != nullptr && physicsComponentB != nullptr) {
|
|
||||||
if (physicsComponentA->Calculate || physicsComponentB->Calculate) {
|
|
||||||
// Turn of collisions
|
|
||||||
contact->SetEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PhysicsSystem* m_PhysicsSystem;
|
|
||||||
};
|
|
||||||
|
|
||||||
ContactListener* m_ContactListener;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //DAYDREAM_PHYSICSSYSTEM_H
|
|
||||||
@@ -15,10 +15,10 @@ void dd::Systems::PhysicsSystem::Initialize()
|
|||||||
m_Gravity = b2Vec2(0.f, -9.82f);
|
m_Gravity = b2Vec2(0.f, -9.82f);
|
||||||
m_PhysicsWorld = new b2World(m_Gravity);
|
m_PhysicsWorld = new b2World(m_Gravity);
|
||||||
|
|
||||||
m_TimeStep = 1.f/60.f;
|
m_TimeStep = 1.0/60.0;
|
||||||
m_VelocityIterations = 6;
|
m_VelocityIterations = 6;
|
||||||
m_PositionIterations = 2;
|
m_PositionIterations = 2;
|
||||||
m_Accumulator = 0.f;
|
m_Accumulator = 0.0;
|
||||||
|
|
||||||
m_PhysicsWorld->SetContactListener(m_ContactListener);
|
m_PhysicsWorld->SetContactListener(m_ContactListener);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user