#ifndef DAYDREAM_PHYSICSSYSTEM_H #define DAYDREAM_PHYSICSSYSTEM_H #include #include #include "Core/System.h" #include "Core/World.h" #include "Core/EventBroker.h" #include "Core/CTemplate.h" #include "Core/CTransform.h" #include "Core/CTemplate.h" #include "Physics/EContact.h" #include "Physics/ESetImpulse.h" #include "Physics/CRectangleShape.h" #include "Physics/CCircleShape.h" #include "Physics/CPhysics.h" #include "Physics/CWaterVolume.h" #include "Physics/CPhysics.h" #include "Physics/CParticle.h" #include "Physics/CCircleShape.h" #include "Physics/CParticleEmitter.h" #include "Transform/TransformSystem.h" #include "Transform/TransformSystem.h" #include "CRectangleShape.h" #include "Game/EStageCleared.h" #include "Game/EPause.h" #include "Game/CPad.h" #include "Game/CBrick.h" #include "Game/CBall.h" #include "Rendering/CSprite.h" namespace dd { namespace Systems { class PhysicsSystem : public System { friend class ContractListener; public: PhysicsSystem(World* world, std::shared_ptr eventBroker) : System(world, eventBroker) { } ~PhysicsSystem(); void RegisterComponents(ComponentFactory* cf) override; void Initialize() override; void Update(double dt) override; void UpdateEntity(double dt, EntityID entity, EntityID parent) override; void OnEntityCommit(EntityID entity) override; void OnEntityRemoved(EntityID entity) override; private: struct Impulse { b2Body* Body; b2Vec2 Vector; b2Vec2 Point; }; bool m_Pause = false; b2Vec2 m_Gravity = b2Vec2(0.f, -9.82f); b2World* m_PhysicsWorld = nullptr; float m_TimeStep = 1.f/60.f; float m_Accumulator = 0.f; int m_VelocityIterations = 6; int m_PositionIterations = 2; std::vector m_ParticleSystem; std::vector t_ParticleGroup; std::vector> m_EntitiesToParticleHandle; std::vector> m_ParticleHandleToEntities; std::unordered_map m_EntitiesToBodies; std::unordered_map m_BodiesToEntities; void CreateBody(EntityID entity); void SyncEntitiesWithBodies(); void SyncBodiesWithEntities(); void InitializeWater(); void CreateParticleGroup(EntityID entity); b2ParticleSystem* CreateParticleSystem(float radius, float gravityScale); void CreateParticleEmitter(EntityID entity); void UpdateParticleEmitters(double dt); //TODO: Remove them and particles if needed. EventRelay m_SetImpulse; bool SetImpulse(const Events::SetImpulse &event); dd::EventRelay m_EPause; bool OnPause(const dd::Events::Pause &event); dd::EventRelay m_EStageCleared; bool OnStageCleared(const dd::Events::StageCleared &event); bool m_Travelling = false; float m_DistanceTravelled = 0; //TODO: Fill struct with info needed. struct ParticleEmitter { std::vector System; std::vector Emitter; std::vector Template; }; ParticleEmitter m_ParticleEmitters; std::list m_Impulses; class ContactListener : public b2ContactListener { public: ContactListener(PhysicsSystem* physicsSystem) : m_PhysicsSystem(physicsSystem) { } void BeginContact(b2Contact* contact); void EndContact(b2Contact* contact); void PreSolve(b2Contact* contact, const b2Manifold* oldManifold); void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse); private: PhysicsSystem* m_PhysicsSystem; }; ContactListener* m_ContactListener; }; } } #endif