From 023f49b0ec1738611793f8a2ca70ef79785a8967 Mon Sep 17 00:00:00 2001 From: Stiffly Date: Sun, 27 Apr 2014 00:17:21 +0200 Subject: [PATCH] Implemented support for spread angle for particle emitter. --- src/GameWorld.cpp | 18 ++++++------ src/Systems/ParticleSystem.cpp | 52 +++++++++++++++++++--------------- src/Systems/ParticleSystem.h | 6 ++-- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 17d1a0f..3edaf44 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -40,14 +40,14 @@ void GameWorld::Initialize() physics->Mass = 10; } - { + /*{ auto TankTest = CreateEntity(); auto transform = AddComponent(TankTest, "Transform"); transform->Position = glm::vec3(1.5f, 0.7f, 5.f); auto model = AddComponent(TankTest, "Model"); model->ModelFile = "Models/Placeholders/tank/Chassi.obj"; - } + }*/ /*for(int i = 0; i < 2; i++) { @@ -67,7 +67,7 @@ void GameWorld::Initialize() model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; }*/ - for(int i = 0; i < 3; i++) + /*for(int i = 0; i < 3; i++) { auto ball = CreateEntity(); auto transform = AddComponent(ball, "Transform"); @@ -80,7 +80,7 @@ void GameWorld::Initialize() sphere->Radius = 0.05; auto physics = AddComponent(ball, "Physics"); physics->Mass = 1; - } + }*/ /*{ auto entity = CreateEntity(); @@ -97,15 +97,15 @@ void GameWorld::Initialize() // Particle emitter auto ent = CreateEntity(); auto transform = AddComponent(ent, "Transform"); + transform->Orientation = glm::angleAxis(glm::pi()/4, glm::vec3(0,1,0)); transform->Position = glm::vec3(i * 10, 20, 0); auto emitter = AddComponent(ent, "ParticleEmitter"); - emitter->LifeTime = 2; - emitter->SpawnCount = 3; - emitter->SpreadAngle = 35; - emitter->SpawnFrequency = 0.2; + emitter->LifeTime = 4; + emitter->SpawnCount = 4; + emitter->SpreadAngle = glm::pi()/6; + emitter->SpawnFrequency = 0.08; auto model = AddComponent(ent, "Model"); model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; - //emitter-> } } } diff --git a/src/Systems/ParticleSystem.cpp b/src/Systems/ParticleSystem.cpp index 30fb6c1..a5479f2 100644 --- a/src/Systems/ParticleSystem.cpp +++ b/src/Systems/ParticleSystem.cpp @@ -28,21 +28,18 @@ void Systems::ParticleSystem::UpdateEntity(double dt, EntityID entity, EntityID auto transformComponent = m_World->GetComponent(entity, "Transform"); if(emitterComponent->TimeSinceLastSpawn > emitterComponent->SpawnFrequency) { - SpawnParticles(entity, transformComponent->Position, emitterComponent->SpawnCount, emitterComponent->SpreadAngle, emitterComponent->LifeTime); + SpawnParticles(entity, transformComponent->Position, emitterComponent->SpawnCount, emitterComponent->SpreadAngle, emitterComponent->LifeTime, dt); emitterComponent->TimeSinceLastSpawn = 0; } - std::cout<<"Number of particles in list for emitter "<::iterator it; for(it = m_ParticleEmitter[entity].begin(); it != m_ParticleEmitter[entity].end();) { EntityID particleID = (it)->ParticleID; auto transformComponent = m_World->GetComponent(particleID, "Transform"); - float speed = 20 * dt; - //ERROR: Direction seems to be 0 for first particle in the list... - transformComponent->Position.x += it->Direction.x * speed; - transformComponent->Position.y += it->Direction.y * speed; - transformComponent->Position.z += it->Direction.z * speed; + transformComponent->Position += transformComponent->Velocity; + auto particleComponent = m_World->GetComponent(particleID, "Particle"); double timeLived = glfwGetTime() - it->SpawnTime; if(timeLived > particleComponent->LifeTime) @@ -57,9 +54,6 @@ void Systems::ParticleSystem::UpdateEntity(double dt, EntityID entity, EntityID it++; } - - - // Interpolates the color for each color channel by the start and end value. Decides how much the color should be interpolated based on time. /*// How big fraction the color is multiplied with float timeProgress = timeLived / particleComponent->LifeTime; @@ -92,20 +86,30 @@ void Systems::ParticleSystem::RegisterComponents(ComponentFactory* cf) cf->Register("Particle", []() { return new Components::Particle(); }); } -void Systems::ParticleSystem::SpawnParticles(EntityID emitterID, glm::vec3 pos, float spawnCount, float spreadAngle, double lifeTime) +void Systems::ParticleSystem::SpawnParticles(EntityID emitterID, glm::vec3 pos, float spawnCount, float spreadAngle, double lifeTime, double dt) { + auto emitterTransform = m_World->GetComponent(emitterID, "Transform"); + glm::quat emitterOrientation = emitterTransform->Orientation; + float tempSpeed = 5 * dt; + glm::vec3 speed = glm::vec3(tempSpeed); for(int i = 0; i < spawnCount; i++) { auto ent = m_World->CreateEntity(); - auto transform = m_World->AddComponent(ent, "Transform"); - transform->Position.x = pos.x; - transform->Position.y = pos.y; - transform->Position.z = pos.z; - transform->Scale = glm::vec3(1, 1, 0); - + auto particleTransform = m_World->AddComponent(ent, "Transform"); + particleTransform->Position.x = pos.x; + particleTransform->Position.y = pos.y; + particleTransform->Position.z = pos.z; + particleTransform->Scale = glm::vec3(1, 1, 1); + //The emitter's orientation as "start value" times the default direction for quaternion. Times the speed, and then rotate on x and y axis with the randomized spread angle. + particleTransform->Velocity = emitterOrientation * glm::vec3(0, 0, -1) * speed * + glm::normalize(glm::angleAxis(RandomizeAngle(spreadAngle), glm::vec3(1, 0, 0))) * + glm::normalize(glm::angleAxis(RandomizeAngle(spreadAngle), glm::vec3(0, 1, 0))); + + auto particle = m_World->AddComponent(ent, "Particle"); particle->LifeTime = lifeTime; + /*Color startColor = {.4f, .45f, .2f}; particle->ColorSpectrum.push_back(startColor); Color endColor = {0.f, 45.f, 23.f}; @@ -116,15 +120,15 @@ void Systems::ParticleSystem::SpawnParticles(EntityID emitterID, glm::vec3 pos, particle->VelocitySpectrum.push_back(glm::vec3(0, -3, 0));*/ auto model = m_World->AddComponent(ent, "Model"); - model->ModelFile = "Models/Placeholders/PhysicsTest/Cube.obj"; + model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; - auto light = m_World->AddComponent(ent, "PointLight"); + /*auto light = m_World->AddComponent(ent, "PointLight"); light->Specular = glm::vec3(0.1f, 0.1f, 0.1f); light->Diffuse = glm::vec3(1.f, 1.f, 0.f); light->constantAttenuation = 0.03f; light->linearAttenuation = 0.00009f; light->quadraticAttenuation = 0.07f; - light->spotExponent = 0.0f; + light->spotExponent = 0.0f;*/ /*auto physics = m_World->AddComponent(ent, "Physics"); @@ -140,10 +144,12 @@ void Systems::ParticleSystem::SpawnParticles(EntityID emitterID, glm::vec3 pos, data.SpawnTime = glfwGetTime(); // data.color = particle->ColorSpectrum[0]; // data.Scale = particle->ScaleSpectrum[0]; - //Random between [-1,1] on every axis - data.Direction = glm::vec3(((double)rand() / ((double)RAND_MAX + 1) * 2) -1, ((double)rand() / ((double)RAND_MAX + 1) * 2) -1, ((double)rand() / ((double)RAND_MAX + 1) * 2) -1); - data.Direction = glm::normalize(data.Direction); m_ParticleEmitter[emitterID].push_back(data); } } + +float Systems::ParticleSystem::RandomizeAngle(float spreadAngle) +{ + return ((float)rand() / ((float)RAND_MAX + 1) * spreadAngle) - spreadAngle/2; +} \ No newline at end of file diff --git a/src/Systems/ParticleSystem.h b/src/Systems/ParticleSystem.h index 5b0ae2e..059eb2f 100644 --- a/src/Systems/ParticleSystem.h +++ b/src/Systems/ParticleSystem.h @@ -21,8 +21,6 @@ namespace Systems double SpawnTime; float Scale; Color color; - glm::vec3 Velocity; - glm::vec3 Direction; }; class ParticleSystem : public System @@ -34,9 +32,11 @@ public: void Update(double dt) override; void UpdateEntity(double dt, EntityID entity, EntityID parent) override; private: - void SpawnParticles(EntityID emitterID, glm::vec3 pos, float spawnCount, float spreadAngle, double lifeTime); + void SpawnParticles(EntityID emitterID, glm::vec3 pos, float spawnCount, float spreadAngle, double lifeTime, double dt); std::map> m_ParticleEmitter; std::map m_TimeSinceLastSpawn; + + float RandomizeAngle(float spreadAngle); };