diff --git a/deps/include/Box2D/Dynamics/b2World.h b/deps/include/Box2D/Dynamics/b2World.h index ce0b8c1..de9d25a 100644 --- a/deps/include/Box2D/Dynamics/b2World.h +++ b/deps/include/Box2D/Dynamics/b2World.h @@ -53,7 +53,8 @@ public: /// Register a destruction listener. The listener is owned by you and must /// remain in scope. - void SetDestructionListener(b2DestructionListener* listener); + void + SetDestructionListener(b2DestructionListener* listener); /// Register a contact filter to provide specific control over collision. /// Otherwise the default filter is used (b2_defaultFilter). The listener is diff --git a/deps/include/Box2D/Particle/b2ParticleSystem.cpp b/deps/include/Box2D/Particle/b2ParticleSystem.cpp index ce1c01e..4863f4d 100644 --- a/deps/include/Box2D/Particle/b2ParticleSystem.cpp +++ b/deps/include/Box2D/Particle/b2ParticleSystem.cpp @@ -654,7 +654,7 @@ int32 b2ParticleSystem::CreateParticle(const b2ParticleDef& def) // If the oldest particle should be destroyed... if (m_def.destroyByAge) { - DestroyOldestParticle(0, false); + DestroyOldestParticle(0, true); // Need to destroy this particle *now* so that it's possible to // create a new particle. SolveZombie(); diff --git a/deps/include/Box2D/Particle/b2ParticleSystem.h b/deps/include/Box2D/Particle/b2ParticleSystem.h index fc27419..117bf33 100644 --- a/deps/include/Box2D/Particle/b2ParticleSystem.h +++ b/deps/include/Box2D/Particle/b2ParticleSystem.h @@ -299,7 +299,7 @@ public: /// b2World::Step()). void DestroyParticle(int32 index) { - DestroyParticle(index, false); + DestroyParticle(index, true); } /// Destroy a particle. @@ -330,7 +330,7 @@ public: /// @return Number of particles destroyed. int32 DestroyParticlesInShape(const b2Shape& shape, const b2Transform& xf) { - return DestroyParticlesInShape(shape, xf, false); + return DestroyParticlesInShape(shape, xf, true); } /// Destroy particles inside a shape. diff --git a/include/Core/Engine.h b/include/Core/Engine.h index 25ee041..aec40de 100755 --- a/include/Core/Engine.h +++ b/include/Core/Engine.h @@ -204,56 +204,55 @@ public: m_World->CommitEntity(background); } - //ParticleTest -// { -// auto Pe = m_World->CreateEntity(); -// auto transform = m_World->AddComponent(Pe); // auto particleEmitter= m_World->AddComponent(Pe); -// -// transform->Position = glm::vec3(0.f, -5.f, -10.f); -// particleEmitter->GravityScale = 0.0f; -// particleEmitter->SpawnRate = 1.0f; -// -// { -// auto Pt = m_World->CreateEntity(Pe); -// auto PtTransform = m_World->AddComponent(Pt); -// auto PtSprite = m_World->AddComponent(Pt); -// //auto PtModel = m_World->AddComponent(Pt); -// auto PtParticle = m_World->AddComponent(Pt); -// auto PtTemplate = m_World->AddComponent(Pt); -// -// PtTransform->Velocity = glm::vec3(1.0f, 0.f, 0.f); -// PtTransform->Position = transform->Position; -// PtSprite->SpriteFile = "Textures/Ball.png"; -// -// //PtModel->ModelFile = "Models/Brick/Brick.obj"; -// PtParticle->LifeTime = 1000.f; -// PtParticle->Flags = ParticleFlags::Type::powderParticle; -// } -// m_World->CommitEntity(Pe); -// } - -// { -// auto Pt = m_World->CreateEntity(); -// auto PtTransform = m_World->AddComponent(Pt); -// auto PtSprite = m_World->AddComponent(Pt); -// -// PtTransform->Position = glm::vec3(2.f, 0.f, -10.f); -// PtSprite->SpriteFile = "Textures/Ball.png"; -// } - //Water test { auto t_waterBody = m_World->CreateEntity(); auto transform = m_World->AddComponent(t_waterBody); - transform->Position = glm::vec3(0.f, -5.5f, -10.f); - transform->Scale = glm::vec3(7.f, 1.5f, 1.f); + transform->Position = glm::vec3(0.f, -3.5f, -10.f); + transform->Scale = glm::vec3(7.0f, 1.5f, 1.f); transform->Sticky = true; auto water = m_World->AddComponent(t_waterBody); auto body = m_World->AddComponent(t_waterBody); m_World->CommitEntity(t_waterBody); } + //ParticleTest + + + /*{ + auto Pe = m_World->CreateEntity(); + auto transform = m_World->AddComponent(Pe); + auto particleEmitter= m_World->AddComponent(Pe); + auto emitteSprite = m_World->AddComponent(Pe); + + transform->Position = glm::vec3(0.f, 0.f, -10.f); + emitteSprite->SpriteFile = "Textures/Test/Brick_Normal.png"; + particleEmitter->GravityScale = 0.0f; + particleEmitter->SpawnRate = 1.f; + particleEmitter->NumberOfTicks = 2; + particleEmitter->Speed = 1.f; + particleEmitter->ParticlesPerTick = 5; + particleEmitter->Spread = glm::pi()*2; + particleEmitter->EmittingAngle = glm::pi(); + particleEmitter->LifeTime = 50; + + { + auto Pt = m_World->CreateEntity(Pe); + auto PtTransform = m_World->AddComponent(Pt); + auto PtSprite = m_World->AddComponent(Pt); + auto PtParticle = m_World->AddComponent(Pt); + auto PtTemplate = m_World->AddComponent(Pt); + + //PtTransform->Velocity = glm::vec3(1.0f, 0.f, 0.f); + PtTransform->Position = transform->Position; + PtSprite->SpriteFile = "Textures/Background.png"; + PtParticle->LifeTime = 3.f; + PtParticle->Flags = static_cast(ParticleFlags::Type::Powder | ParticleFlags::Type::ParticleContactFilter | ParticleFlags::Type::FixtureContactFilter); + } + m_World->CommitEntity(Pe); + }*/ + //TODO: Why does the ball not collide with these bricks? //BottomBox { @@ -338,8 +337,6 @@ public: m_World->CommitEntity(rightWall); } - - //EVENT_SUBSCRIBE_MEMBER(m_EGameStart, &Engine::OnGameStart); m_EGameStart = decltype(m_EGameStart)(std::bind(&Engine::OnGameStart, this, std::placeholders::_1)); m_EventBroker->Subscribe(m_EGameStart); diff --git a/include/Physics/CParticleEmitter.h b/include/Physics/CParticleEmitter.h index af97a9c..565a935 100755 --- a/include/Physics/CParticleEmitter.h +++ b/include/Physics/CParticleEmitter.h @@ -9,10 +9,16 @@ namespace Components struct ParticleEmitter : public Component { - int Amount = 10.f; + int NumberOfTicks = 10.f; float InitialSpeed = 1.f; - double SpawnRate = 1.f; + double SpawnRate = 1; + int ParticlesPerTick = 1; double TimeSinceLastSpawn = 0; + int MaxCount = 0; + float EmittingAngle = 0.f; + float Spread = 0.f; + float Speed = 2.f; + double LifeTime = 100; //System variables float GravityScale = 1.0f; diff --git a/include/Physics/ECreateParticleSequence.h b/include/Physics/ECreateParticleSequence.h new file mode 100644 index 0000000..c6b3c2d --- /dev/null +++ b/include/Physics/ECreateParticleSequence.h @@ -0,0 +1,37 @@ +#ifndef EVENTS_ECREATEPARTICLESEQUENCE_H__ +#define EVENTS_ECREATEPARTICLESEQUENCE_H__ + +#include "Core/EventBroker.h" +#include "Physics/CParticle.h" + +namespace dd +{ +namespace Events +{ + +struct CreateParticleSequence : public Event +{ + //Emitter + double EmitterLifeTime = 100; + glm::vec3 Position = glm::vec3(0); + float GravityScale = 0.f; + float SpawnRate = 1.f; + int NumberOfTicks = 100; + float Speed = 1.f; + int ParticlesPerTick = 1.f; + float Spread = 1.f; + float EmittingAngle = 0.f; + float MaxCount = 0; + + //Particle + std::string SpriteFile = "Texures/Core/ErrorTexture.png"; + double ParticleLifeTime = 3.f; + ParticleFlags::Type Flags = static_cast(ParticleFlags::Powder | ParticleFlags::ParticleContactFilter | ParticleFlags::FixtureContactFilter); + float Radius = 1.f; +}; + +} +} + +#endif + diff --git a/include/Physics/PhysicsSystem.h b/include/Physics/PhysicsSystem.h index 611bbde..70f8776 100755 --- a/include/Physics/PhysicsSystem.h +++ b/include/Physics/PhysicsSystem.h @@ -2,6 +2,7 @@ #define DAYDREAM_PHYSICSSYSTEM_H #include +#include #include @@ -20,6 +21,7 @@ #include "Physics/CWaterVolume.h" #include "Physics/CPhysics.h" #include "Physics/CParticle.h" +#include "Physics/ECreateParticleSequence.h" #include "Physics/CCircleShape.h" #include "Physics/CParticleEmitter.h" @@ -46,6 +48,7 @@ namespace dd class PhysicsSystem : public System { friend class ContractListener; + friend class DestructionListener; public: PhysicsSystem(World* world, std::shared_ptr eventBroker) @@ -53,6 +56,9 @@ namespace dd ~PhysicsSystem(); + EventRelay m_ECreateParticleSequence; + bool CreateParticleSequence(const Events::CreateParticleSequence &event); + void RegisterComponents(ComponentFactory* cf) override; void Initialize() override; void Update(double dt) override; @@ -68,6 +74,8 @@ namespace dd b2Vec2 Point; }; bool m_Pause = false; + + std::mt19937 gen; b2Vec2 m_Gravity = b2Vec2(0.f, -9.82f); @@ -77,9 +85,11 @@ namespace dd int m_VelocityIterations = 6; int m_PositionIterations = 2; - std::vector m_ParticleSystem; + b2ParticleSystem* m_WaterParticleSystem; std::vector t_ParticleGroup; + std::unordered_map m_WaterParticleHandleToEntities; + std::unordered_map m_EntitiesToWaterParticleHandle; std::vector> m_EntitiesToParticleHandle; std::vector> m_ParticleHandleToEntities; std::unordered_map m_EntitiesToBodies; @@ -93,7 +103,7 @@ namespace dd void InitializeWater(); void CreateParticleGroup(EntityID entity); - b2ParticleSystem* CreateParticleSystem(float radius, float gravityScale); + b2ParticleSystem* CreateParticleSystem(float radius, float gravityScale, int maxCount); void CreateParticleEmitter(EntityID entity); void UpdateParticleEmitters(double dt); //TODO: Remove them and particles if needed. @@ -107,34 +117,87 @@ namespace dd float m_DistanceTravelled = 0; //TODO: Fill struct with info needed. - struct ParticleEmitter - { - std::vector System; - std::vector Emitter; - std::vector Template; - }; - ParticleEmitter m_ParticleEmitters; + struct EmitterHandler //TODO CHANGE NAMES + { + std::vector ParticleSystem; + std::vector ParticleEmitter; + std::vector ParticleTemplate; + }; + EmitterHandler m_ParticleEmitters; std::list m_Impulses; + + + class DestructionListener : public b2DestructionListener + { + public: + DestructionListener(PhysicsSystem* physicsSystem) + : m_PhysicsSystem(physicsSystem) { } + + void SayGoodbye(b2Joint*) {LOG_INFO("joint körs");}; + void SayGoodbye(b2Fixture*) {/*LOG_INFO("Fixture körs");*/}; + + void SayGoodbye(b2ParticleSystem* particleSystem, int32 index) override + { + LOG_INFO("Particle ded"); + + + const b2ParticleHandle* handle = particleSystem->GetParticleHandleFromIndex(index); + for (int i = 0; i < m_PhysicsSystem->m_ParticleEmitters.ParticleSystem.size(); i++) { + if(m_PhysicsSystem->m_ParticleEmitters.ParticleSystem[i] == particleSystem) { + std::unordered_map::iterator it = m_PhysicsSystem->m_ParticleHandleToEntities[i].find(handle); + if(it != m_PhysicsSystem->m_ParticleHandleToEntities[i].end()) { + EntityID id = it->second; + m_PhysicsSystem->m_World->RemoveEntity(id); + m_PhysicsSystem->m_ParticleHandleToEntities[i].erase(it); + LOG_INFO("Removing from list"); + } + } + } + } + private: + PhysicsSystem* m_PhysicsSystem; + }; + + class ParticleContactDisabler : public b2ContactFilter + { + public: + ParticleContactDisabler() { }; + + //Particles to particles + virtual bool ShouldCollide(b2ParticleSystem *particleSystem, int32 particleIndexA, int32 particleIndexB) + { + return false; + } + virtual bool ShouldCollide(b2Fixture* fixture, b2ParticleSystem* particleSystem, int32 particleIndex) + { + return false; + } + + }; - 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; - }; + class ContactListener : public b2ContactListener + { + public: + ContactListener(PhysicsSystem* physicsSystem) + : m_PhysicsSystem(physicsSystem) { } - ContactListener* m_ContactListener; + 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; + }; + + DestructionListener* m_DestructionListener; + ParticleContactDisabler m_ParticleContactDisabler; + ContactListener* m_ContactListener; }; } diff --git a/include/Sound/SoundSystem.h b/include/Sound/SoundSystem.h index 89713f5..8892577 100644 --- a/include/Sound/SoundSystem.h +++ b/include/Sound/SoundSystem.h @@ -17,6 +17,7 @@ #include "Game/CBall.h" #include "Game/CBrick.h" #include "Game/CPad.h" +#include "Physics/ECreateParticleSequence.h" namespace dd { diff --git a/src/game/Core/Renderer.cpp b/src/game/Core/Renderer.cpp index f43876f..91799b9 100755 --- a/src/game/Core/Renderer.cpp +++ b/src/game/Core/Renderer.cpp @@ -358,12 +358,10 @@ void dd::Renderer::DrawForward(RenderQueue &objects, RenderQueue &lights) { // Forward-render semi-transparent objects on top of the current framebuffer glDisable(GL_CULL_FACE); - glCullFace(GL_BACK); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); - //glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBindFramebuffer(GL_FRAMEBUFFER, m_FbDeferred3); // glClearColor(1, 0.9, 0.8f, 1); @@ -444,7 +442,6 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program) glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix)); glUniform4fv(glGetUniformLocation(shaderProgramHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, spriteJob->DiffuseTexture); glActiveTexture(GL_TEXTURE1); diff --git a/src/game/Physics/PhysicsSystem.cpp b/src/game/Physics/PhysicsSystem.cpp index 861549f..cd9d0bd 100755 --- a/src/game/Physics/PhysicsSystem.cpp +++ b/src/game/Physics/PhysicsSystem.cpp @@ -10,20 +10,34 @@ void dd::Systems::PhysicsSystem::RegisterComponents(ComponentFactory* cf) void dd::Systems::PhysicsSystem::Initialize() { + std::random_device rd; + gen = std::mt19937(rd()); + m_DestructionListener = new DestructionListener(this); m_ContactListener = new ContactListener(this); m_PhysicsWorld = new b2World(m_Gravity); m_PhysicsWorld->SetContactListener(m_ContactListener); + m_PhysicsWorld->SetContactFilter(&m_ParticleContactDisabler); + m_PhysicsWorld->SetDestructionListener(m_DestructionListener); + InitializeWater(); EVENT_SUBSCRIBE_MEMBER(m_SetImpulse, &PhysicsSystem::SetImpulse); EVENT_SUBSCRIBE_MEMBER(m_EPause, &PhysicsSystem::OnPause); - EVENT_SUBSCRIBE_MEMBER(m_EStageCleared, &PhysicsSystem::OnStageCleared); + EVENT_SUBSCRIBE_MEMBER(m_ECreateParticleSequence, &PhysicsSystem::CreateParticleSequence); + } void dd::Systems::PhysicsSystem::InitializeWater() { float radius = 0.13f; float gravityScale = 1.0f; - CreateParticleSystem(radius, gravityScale); + + b2ParticleSystemDef m_ParticleSystemDef; + m_ParticleSystemDef.radius = radius; + m_ParticleSystemDef.gravityScale = gravityScale; + + m_WaterParticleSystem = m_PhysicsWorld->CreateParticleSystem(&m_ParticleSystemDef); + + } bool dd::Systems::PhysicsSystem::SetImpulse(const Events::SetImpulse &event) @@ -185,9 +199,34 @@ void dd::Systems::PhysicsSystem::Update(double dt) SyncBodiesWithEntities(); + //water + b2Vec2 *positionBuffer = m_WaterParticleSystem->GetPositionBuffer(); + for (auto i : m_EntitiesToWaterParticleHandle){ + EntityID entity = i.first; + const b2ParticleHandle *particleH = i.second; + + + b2Vec2 positionB2 = positionBuffer[particleH->GetIndex()]; + glm::vec2 position = glm::vec2(positionB2.x, positionB2.y); + + EntityID entityParent = m_World->GetEntityParent(entity); + glm::vec3 parentTransform = glm::vec3(0.f); + if(entityParent) { + auto tp = m_World->GetComponent(entityParent); + parentTransform = tp->Position; + } + auto transform = m_World->GetComponent(entity); + + transform->Position = glm::vec3(position.x - parentTransform.x, position.y - parentTransform.y, 0); + } + + //Normal particles for ( int e = 0; e < m_EntitiesToParticleHandle.size(); e++) { - b2Vec2 *positionBuffer = m_ParticleSystem[e]->GetPositionBuffer(); - for (auto i : m_EntitiesToParticleHandle[e]) { + b2Vec2 *positionBuffer = m_ParticleEmitters.ParticleSystem[e]->GetPositionBuffer(); + if(!positionBuffer) { + break; + } + for (auto i : m_EntitiesToParticleHandle[e]){ EntityID entity = i.first; const b2ParticleHandle *particleH = i.second; @@ -196,14 +235,13 @@ void dd::Systems::PhysicsSystem::Update(double dt) EntityID entityParent = m_World->GetEntityParent(entity); glm::vec3 parentTransform = glm::vec3(0.f); - if (entityParent) { + if(entityParent) { auto tp = m_World->GetComponent(entityParent); parentTransform = tp->Position; } auto transform = m_World->GetComponent(entity); - transform->Position = glm::vec3(position.x, position.y, -10) - parentTransform; - + transform->Position = glm::vec3(position.x, position.y, transform->Position.z); } } @@ -212,7 +250,7 @@ void dd::Systems::PhysicsSystem::Update(double dt) } void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) -{ +{ if (m_Travelling) { auto transform = m_World->GetComponent(entity); if (transform != nullptr) { @@ -220,8 +258,29 @@ void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, Entity return; } transform->Position.y -= 6.0f * dt; - } - } + } + } + auto particle = m_World->GetComponent(entity); + auto pTemplate = m_World->GetComponent(entity); + if (particle && !pTemplate) { + particle->LifeTime -= dt; + if (particle->LifeTime <= 0) { + for (int i = 0; i < m_EntitiesToParticleHandle.size(); i++) { + const b2ParticleHandle* handle = m_EntitiesToParticleHandle[i][entity]; + std::unordered_map::iterator iter1; + std::unordered_map::iterator iter2; + iter1 = m_EntitiesToParticleHandle[i].find(entity); + iter2 = m_ParticleHandleToEntities[i].find(handle); + if (iter1 != m_EntitiesToParticleHandle[i].end()) { + m_EntitiesToParticleHandle[i].erase(iter1); + } + if (iter2 != m_ParticleHandleToEntities[i].end()) { + m_ParticleHandleToEntities[i].erase(iter2); + } + m_World->RemoveEntity(entity); + } + } + } } bool dd::Systems::PhysicsSystem::OnPause(const dd::Events::Pause &event) @@ -270,23 +329,12 @@ void dd::Systems::PhysicsSystem::OnEntityCommit(EntityID entity) void dd::Systems::PhysicsSystem::OnEntityRemoved(EntityID entity) { - /* auto physics = m_World->GetComponent(entity); - if (physics == nullptr) { - return; - }*/ - auto it = m_EntitiesToBodies.find(entity); - if(it == m_EntitiesToBodies.end()) { - LOG_ERROR("Trying to remove non-exsisting body, Entity: %i", entity); - return; + if(it != m_EntitiesToBodies.end()) { + it->second->GetWorld()->DestroyBody(it->second); + m_BodiesToEntities.erase(it->second); + m_EntitiesToBodies.erase(entity); } - - //It told me I was removing a lot of objects, and I didn't need that information, so I commented it out. - //LOG_INFO("Removing entity %i", entity); - it->second->GetWorld()->DestroyBody(it->second); - m_BodiesToEntities.erase(it->second); - m_EntitiesToBodies.erase(entity); - //delete body; } @@ -364,6 +412,8 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity) m_EntitiesToBodies.insert(std::make_pair(entity, body)); m_BodiesToEntities.insert(std::make_pair(body, entity)); } + + void dd::Systems::PhysicsSystem::CreateParticleGroup(EntityID e) { auto transform = m_World->GetComponent(e); @@ -379,19 +429,19 @@ void dd::Systems::PhysicsSystem::CreateParticleGroup(EntityID e) pd.shape = &shape; pd.flags = b2_tensileParticle; pd.position.Set(transform->Position.x, transform->Position.y); - t_ParticleGroup.push_back(m_ParticleSystem[0]->CreateParticleGroup(pd)); - b2Vec2* t_ParticlePositions = m_ParticleSystem[0]->GetPositionBuffer(); - for(int i = 0; i < m_ParticleSystem[0]->GetParticleCount(); i++){ + t_ParticleGroup.push_back(m_WaterParticleSystem->CreateParticleGroup(pd)); + b2Vec2* t_ParticlePositions = m_WaterParticleSystem->GetPositionBuffer(); + for(int i = 0; i < m_WaterParticleSystem->GetParticleCount(); i++){ { auto t_waterparticle = m_World->CreateEntity(e); auto transformChild = m_World->AddComponent(t_waterparticle); transformChild->Position = glm::vec3(t_ParticlePositions[i].x - transform->Position.x, t_ParticlePositions[i].y - transform->Position.y, -9.5f); - transformChild->Scale = glm::vec3(m_ParticleSystem[0]->GetRadius())/transform->Scale; + transformChild->Scale = glm::vec3(m_WaterParticleSystem->GetRadius())/transform->Scale; m_World->CommitEntity(t_waterparticle); - m_EntitiesToParticleHandle[0].insert(std::make_pair(t_waterparticle, m_ParticleSystem[0]->GetParticleHandleFromIndex(i))); - m_ParticleHandleToEntities[0].insert(std::make_pair( m_ParticleSystem[0]->GetParticleHandleFromIndex(i), t_waterparticle)); + m_EntitiesToWaterParticleHandle.insert(std::make_pair(t_waterparticle, m_WaterParticleSystem->GetParticleHandleFromIndex(i))); + m_WaterParticleHandleToEntities.insert(std::make_pair(m_WaterParticleSystem->GetParticleHandleFromIndex(i), t_waterparticle)); } } @@ -399,46 +449,139 @@ void dd::Systems::PhysicsSystem::CreateParticleGroup(EntityID e) } } + void dd::Systems::PhysicsSystem::UpdateParticleEmitters(double dt) { - for (int i = 0; i < m_ParticleEmitters.System.size(); i++) { - auto e = m_ParticleEmitters.Emitter[i]; - auto pt = m_ParticleEmitters.Template[i]; - auto ps = m_ParticleEmitters.System[i]; + std::vector emittersToDelete; + int pSizeTest = 0; + for (int i = 0; i < m_ParticleEmitters.ParticleSystem.size(); i++) { + auto e = m_ParticleEmitters.ParticleEmitter[i]; + auto pt = m_ParticleEmitters.ParticleTemplate[i]; + auto ps = m_ParticleEmitters.ParticleSystem[i]; + pSizeTest += ps->GetParticleCount(); auto emitter = m_World->GetComponent(e); auto particleTemplate = m_World->GetComponent(pt); - emitter->TimeSinceLastSpawn += dt; - if(emitter->TimeSinceLastSpawn < emitter->SpawnRate) { + if(!emitter) { + LOG_INFO("ParticleEmitter Component is nil"); continue; } + if(!particleTemplate) { + LOG_INFO("ParticleTemplate Component is nil."); + continue; + } + auto TempTransform = m_World->GetComponent(e); + TempTransform->Orientation = glm::rotate(glm::quat(), 3.f, glm::vec3(0.f, 0.f, -1.f)); + + emitter->TimeSinceLastSpawn += dt; + emitter->LifeTime -= dt; + + if (emitter->LifeTime <= 0 || emitter->NumberOfTicks <= 0) { + emittersToDelete.push_back(e); + continue; + } + if(emitter->TimeSinceLastSpawn < emitter->SpawnRate || emitter->NumberOfTicks < 1) { + continue; + } + emitter->NumberOfTicks--; emitter->TimeSinceLastSpawn -= emitter->SpawnRate; auto templateTransform = m_World->GetComponent(pt); - b2ParticleDef particleDef; - particleDef.flags = particleTemplate->Flags; - //particleDef.color TODO: Implement this if we want color mixing and shit. - particleDef.lifetime = particleTemplate->LifeTime; - particleDef.velocity = b2Vec2(templateTransform->Velocity.x, templateTransform->Velocity.y); - particleDef.position = b2Vec2(templateTransform->Position.x, templateTransform->Position.y); + for ( int j = 0; j < emitter->ParticlesPerTick; j++) { + particleDef.flags = particleTemplate->Flags; + //particleDef.color TODO: Implement this if we want color mixing and shit. + particleDef.lifetime = particleTemplate->LifeTime; + float eAngle = emitter->EmittingAngle; + float halfSpread = emitter->Spread / 2; - auto particle = m_World->CloneEntity(pt, 0); - m_World->RemoveComponent(particle); + std::uniform_real_distribution dis(eAngle - halfSpread, eAngle + halfSpread); + float pAngle = dis(gen); + glm::vec2 unitVec = glm::normalize(glm::vec2(glm::cos(pAngle), glm::sin(pAngle))); + glm::vec2 vel = unitVec * emitter->Speed; + particleDef.velocity = b2Vec2(vel.x, vel.y); + particleDef.position = b2Vec2(templateTransform->Position.x, templateTransform->Position.y); - auto b2Particle = ps->CreateParticle(particleDef); - auto b2ParticleHandle = ps->GetParticleHandleFromIndex(b2Particle); - m_EntitiesToParticleHandle[i].insert(std::make_pair(particle, b2ParticleHandle)); - m_ParticleHandleToEntities[i].insert(std::make_pair(b2ParticleHandle, particle)); - //TODO: Ta bort detta - int particles = 0; - for (auto i : m_EntitiesToParticleHandle) - { - particles += i.size(); + auto particle = m_World->CloneEntity(pt, 0); + m_World->RemoveComponent(particle); + auto transform2 = m_World->GetComponent(particle); + + std::uniform_real_distribution dist(0, 1); + float zDistribution = dist(gen); + transform2->Position = glm::vec3(transform2->Position.x, transform2->Position.y, -9.5f + zDistribution); + transform2->Scale = glm::vec3(particleTemplate->Radius * 2.f, particleTemplate->Radius * 2.f, 1); + + + auto b2Particle = ps->CreateParticle(particleDef); + + auto b2ParticleHandle = ps->GetParticleHandleFromIndex(b2Particle); + m_EntitiesToParticleHandle[i].insert(std::make_pair(particle, b2ParticleHandle)); + m_ParticleHandleToEntities[i].insert(std::make_pair(b2ParticleHandle, particle)); } - LOG_INFO("--I have %i particles.", particles); } + + for (int i = 0; i < emittersToDelete.size(); i++) + { + EntityID ent = emittersToDelete[i]; + int key; + for(key = 0; key < m_ParticleEmitters.ParticleEmitter.size(); key++) { + if (m_ParticleEmitters.ParticleEmitter[key] == ent) { + break; + } + } + + if (m_ParticleEmitters.ParticleSystem[key]->GetParticleCount() == 0 && key <= m_ParticleEmitters.ParticleSystem.size()) { + m_World->RemoveEntity(ent); + m_PhysicsWorld->DestroyParticleSystem(m_ParticleEmitters.ParticleSystem[key]); + m_ParticleEmitters.ParticleSystem.erase(m_ParticleEmitters.ParticleSystem.begin() + key); + m_ParticleEmitters.ParticleEmitter.erase(m_ParticleEmitters.ParticleEmitter.begin() + key); + m_ParticleEmitters.ParticleTemplate.erase(m_ParticleEmitters.ParticleTemplate.begin() + key); + m_EntitiesToParticleHandle.erase(m_EntitiesToParticleHandle.begin() + key); + m_ParticleHandleToEntities.erase(m_ParticleHandleToEntities.begin() + key); + } + } + + int stp = 0; + for (auto ts : m_EntitiesToParticleHandle) + { + stp += ts.size(); + } +} + +bool dd::Systems::PhysicsSystem::CreateParticleSequence(const Events::CreateParticleSequence &event) +{ + //Creating Emitter + auto emitter = m_World->CreateEntity(); + auto emitterTransform = m_World->AddComponent(emitter); + auto particleEmitter= m_World->AddComponent(emitter); + + emitterTransform->Position = event.Position; + particleEmitter->GravityScale = event.GravityScale; + particleEmitter->SpawnRate = event.SpawnRate; + particleEmitter->NumberOfTicks = event.NumberOfTicks; + particleEmitter->Speed = event.Speed; + particleEmitter->ParticlesPerTick = event.ParticlesPerTick; + particleEmitter->Spread = event.Spread; + particleEmitter->EmittingAngle = event.EmittingAngle; + particleEmitter->LifeTime = event.EmitterLifeTime; + + { + //Creating Particle Template + auto particle = m_World->CreateEntity(emitter); + auto particleTransform = m_World->AddComponent(particle); + auto sprite = m_World->AddComponent(particle); + auto particleComponent = m_World->AddComponent(particle); + m_World->AddComponent(particle); + + particleTransform->Position = emitterTransform->Position; + sprite->SpriteFile = event.SpriteFile; + particleComponent->LifeTime = event.ParticleLifeTime; + particleComponent->Flags = event.Flags; + particleComponent->Radius = event.Radius; + } + m_World->CommitEntity(emitter); + return true; } void dd::Systems::PhysicsSystem::CreateParticleEmitter(EntityID entity) @@ -456,14 +599,14 @@ void dd::Systems::PhysicsSystem::CreateParticleEmitter(EntityID entity) auto particleTemplate = m_World->GetComponent(c); if (!p) { continue; - LOG_WARNING("--Emitter's Child is not a particle."); + LOG_WARNING("ParticleEmitter's Child is not a particle."); } if(!particleTemplate) { - LOG_ERROR("Emitter's particleChild is not a template."); + LOG_ERROR("ParticleEmitter's particleChild is not a template."); continue; } if (pf != 0) { - LOG_WARNING("Emitter has more than one child that is a particleTemplate, only the first one is used."); + LOG_WARNING("ParticleEmitter has more than one child that is a particleTemplate, only the first one is used."); break; } childEntity = c; @@ -471,13 +614,14 @@ void dd::Systems::PhysicsSystem::CreateParticleEmitter(EntityID entity) pf++; } //TODO: Skicka med fler flaggor till particlesystemet; - m_ParticleEmitters.System.push_back(CreateParticleSystem(particle->Radius, 0.f)); - m_ParticleEmitters.Emitter.push_back(entity); - m_ParticleEmitters.Template.push_back(childEntity); + + m_ParticleEmitters.ParticleSystem.push_back(CreateParticleSystem(particle->Radius, 0.f, 0)); + m_ParticleEmitters.ParticleEmitter.push_back(entity); + m_ParticleEmitters.ParticleTemplate.push_back(childEntity); } -b2ParticleSystem* dd::Systems::PhysicsSystem::CreateParticleSystem(float radius, float gravityScale) +b2ParticleSystem* dd::Systems::PhysicsSystem::CreateParticleSystem(float radius, float gravityScale, int maxCount) { std::unordered_map m1; std::unordered_map m2; @@ -485,12 +629,12 @@ b2ParticleSystem* dd::Systems::PhysicsSystem::CreateParticleSystem(float radius, m_ParticleHandleToEntities.push_back(m2); b2ParticleSystemDef m_ParticleSystemDef; + m_ParticleSystemDef.maxCount = maxCount; m_ParticleSystemDef.radius = radius; m_ParticleSystemDef.gravityScale = gravityScale; + m_ParticleSystemDef.destroyByAge = true; - m_ParticleSystem.push_back(m_PhysicsWorld->CreateParticleSystem(&m_ParticleSystemDef)); - - return m_ParticleSystem.back(); + return m_PhysicsWorld->CreateParticleSystem(&m_ParticleSystemDef); } diff --git a/src/game/Sound/SoundSystem.cpp b/src/game/Sound/SoundSystem.cpp index 5fca564..c11d84e 100644 --- a/src/game/Sound/SoundSystem.cpp +++ b/src/game/Sound/SoundSystem.cpp @@ -4,7 +4,7 @@ dd::Systems::SoundSystem::~SoundSystem() { alcCloseDevice(m_Device); -}; +} void dd::Systems::SoundSystem::Initialize() { @@ -41,6 +41,8 @@ void dd::Systems::SoundSystem::Initialize() e.IsAmbient = true; EventBroker->Publish(e); } + + } void dd::Systems::SoundSystem::Update(double dt) @@ -165,10 +167,14 @@ bool dd::Systems::SoundSystem::OnContact(const dd::Events::Contact &event) } //Send play-sound event - dd::Events::PlaySound e; - e.FilePath = collisionSound->FilePath; - e.IsAmbient = false; - EventBroker->Publish(e); + + { + dd::Events::PlaySound e; + e.FilePath = collisionSound->FilePath; + e.IsAmbient = false; + EventBroker->Publish(e); + } + return true; }