#ifndef DAYDREAM_PHYSICSSYSTEM_H #define DAYDREAM_PHYSICSSYSTEM_H #include #include "Core/System.h" #include "Core/World.h" #include "CRectangleShape.h" #include "Physics/CPhysics.h" #include #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 eventBroker) : System(world, eventBroker) {} ~PhysicsSystem(); EventRelay 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 m_EntitiesToBodies; std::unordered_map m_BodiesToEntities; void CreateBody(EntityID entity); b2ParticleSystem *m_ParticleSystem; b2ParticleGroup* t_watergroup; std::unordered_map m_EntitiesToParticleHandle; std::unordered_map m_ParticleHandleToEntities; void InitializeWater(); void SyncWater(); //TODO: Probably remove this void CreateParticleGroup(EntityID entity); struct Impulse { b2Body* Body; b2Vec2 Impulse; b2Vec2 Point; }; std::list 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(entityA); auto physicsComponentB = m_PhysicsSystem->m_World->GetComponent(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