From 1a365bf06990a0276834820e70a4e656d4def2d0 Mon Sep 17 00:00:00 2001 From: Stiffly Date: Wed, 7 May 2014 21:34:19 +0200 Subject: [PATCH] Billboarding on sprites --- src/Components/ParticleEmitter.h | 3 +- src/GameWorld.cpp | 17 ++++--- src/Renderer.cpp | 24 +++++++-- src/Renderer.h | 2 +- src/Systems/ParticleSystem.cpp | 86 +++++++++++++++++++++----------- src/Systems/ParticleSystem.h | 1 - 6 files changed, 90 insertions(+), 43 deletions(-) diff --git a/src/Components/ParticleEmitter.h b/src/Components/ParticleEmitter.h index ae66fca..1b30c8d 100755 --- a/src/Components/ParticleEmitter.h +++ b/src/Components/ParticleEmitter.h @@ -28,7 +28,8 @@ struct ParticleEmitter : Component std::vector ScaleSpectrum; float SpreadAngle; double LifeTime; - std::vector VelocitySpectrum; + bool UseGoalVelocity; + glm::vec3 GoalVelocity; std::vector AngularVelocitySpectrum; std::vector OrientationSpectrum; //Keep? diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 801cd6e..0b19842 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -99,20 +99,23 @@ void GameWorld::Initialize() auto transform = AddComponent(ent, "Transform"); transform->Orientation = glm::angleAxis(glm::pi()/2, glm::vec3(1,0,0)); transform->Position = glm::vec3(i * 10, 20, 0); + auto emitter = AddComponent(ent, "ParticleEmitter"); - emitter->LifeTime = 4; + emitter->LifeTime = 0.3; emitter->SpawnCount = 1; - emitter->SpreadAngle = glm::pi()/20; - emitter->SpawnFrequency = 1.008; - emitter->ScaleSpectrum.push_back(glm::vec3(1)); - emitter->ScaleSpectrum.push_back(glm::vec3(0)); + emitter->SpreadAngle = glm::pi()/4; + emitter->SpawnFrequency = 0.0008; + emitter->ScaleSpectrum.push_back(glm::vec3(0.05f)); + emitter->UseGoalVelocity = false; + emitter->GoalVelocity = glm::vec3(4, -4, 0); +// emitter->OrientationSpectrum.push_back(glm::vec3(0, 1, 0)); +// emitter->OrientationSpectrum.push_back(glm::vec3(0, -1, 0)); + emitter->AngularVelocitySpectrum.push_back(glm::pi() / 100); auto model = AddComponent(ent, "Model"); model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; auto particleEnt = CreateEntity(); AddComponent(particleEnt, "Transform"); -// model = AddComponent(particleEnt, "Model"); -// model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; auto spriteComponent = AddComponent(particleEnt, "Sprite"); spriteComponent->SpriteFile = "Textures/Sprites/SeriousParticle.png"; emitter->ParticleTemplate = particleEnt; diff --git a/src/Renderer.cpp b/src/Renderer.cpp index c8cf06e..f7960d5 100755 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -271,10 +271,13 @@ void Renderer::DrawScene() { Texture* texture; glm::mat4 modelMatrix; - std::tie(texture, modelMatrix) = tuple; - - //MVP = m_Camera->ProjectionMatrix() * glm::translate(glm::mat4(), m_Camera->Position()) * modelMatrix; - MVP = cameraMatrix * glm::inverse(glm::toMat4(m_Camera->Orientation())) * modelMatrix ; + glm::mat4 billboardMatrix; + std::tie(texture, modelMatrix, billboardMatrix) = tuple; + + + //MVP = cameraMatrix * glm::inverse(glm::toMat4(m_Camera->Orientation()) * modelMatrix ); + MVP = cameraMatrix * billboardMatrix * modelMatrix; + depthMVP = depthCameraMatrix * modelMatrix; glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "DepthMVP"), 1, GL_FALSE, glm::value_ptr(depthMVP)); @@ -404,7 +407,18 @@ void Renderer::AddModelToDraw(Model* model, glm::vec3 position, glm::quat orient void Renderer::AddTextureToDraw(Texture* texture, glm::vec3 position, glm::quat orientation, glm::vec3 scale) { glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale); - TexturesToRender.push_back(std::make_tuple(texture, modelMatrix)); + + glm::vec3 camToParticle = glm::normalize(m_Camera->Position() - position); + glm::vec3 up = glm::vec3(0,1,0); + glm::vec3 rightVec = glm::cross(up, camToParticle); + + glm::mat4 billboardMatrix; + billboardMatrix[0] = glm::vec4(rightVec, 0); + billboardMatrix[1] = glm::vec4(up, 0); + billboardMatrix[2] = glm::vec4(camToParticle, 0); + //billboardMatrix[3] = glm::vec4(position, 0); + + TexturesToRender.push_back(std::make_tuple(texture, modelMatrix, billboardMatrix)); } void Renderer::AddPointLightToDraw( diff --git a/src/Renderer.h b/src/Renderer.h index 7d00b13..17485aa 100755 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -23,7 +23,7 @@ public: int HEIGHT, WIDTH; std::list> ModelsToRender; - std::list> TexturesToRender; + std::list> TexturesToRender; int Lights; std::vector Light_position; std::vector Light_specular; diff --git a/src/Systems/ParticleSystem.cpp b/src/Systems/ParticleSystem.cpp index 660e39c..8e384c5 100644 --- a/src/Systems/ParticleSystem.cpp +++ b/src/Systems/ParticleSystem.cpp @@ -31,6 +31,9 @@ void Systems::ParticleSystem::UpdateEntity(double dt, EntityID entity, EntityID emitterComponent->TimeSinceLastSpawn = 0; } + + + std::list::iterator it; for(it = m_ParticleEmitter[entity].begin(); it != m_ParticleEmitter[entity].end();) { @@ -55,19 +58,35 @@ void Systems::ParticleSystem::UpdateEntity(double dt, EntityID entity, EntityID // Velocity interpolation if(particleComponent->VelocitySpectrum.size() > 1) VectorInterpolation(timeProgress, particleComponent->VelocitySpectrum, transformComponent->Velocity); + // Angular velocity interpolation - if(particleComponent->AngularVelocitySpectrum.size() > 1) - ScalarInterpolation(timeProgress, particleComponent->AngularVelocitySpectrum, it->AngularVelocity); + if (particleComponent->AngularVelocitySpectrum.size() != 0) + { + if(particleComponent->AngularVelocitySpectrum.size() > 1) + { + ScalarInterpolation(timeProgress, particleComponent->AngularVelocitySpectrum, it->AngularVelocity); + transformComponent->Orientation = glm::angleAxis(it->AngularVelocity, it->Orientation); + } + else + { + transformComponent->Orientation *= glm::angleAxis(it->AngularVelocity, it->Orientation); + //it->Orientation = glm::angleAxis(it->AngularVelocity, it->Orientation); + } + } + //Angular velocity interpolation if(particleComponent->OrientationSpectrum.size() > 1) + { VectorInterpolation(timeProgress, particleComponent->OrientationSpectrum, it->Orientation); + glm::vec3 v1 = (particleComponent->OrientationSpectrum[0]); + glm::vec3 v2 = (it->Orientation); + glm::vec3 v3 = glm::normalize(glm::cross(v1,v2)); + float angle = glm::acos(glm::dot(v1, v2) / (glm::length(v1) * glm::length(v2))); + + transformComponent->Orientation = glm::angleAxis(angle, v3); + } - glm::vec3 v1 = (particleComponent->OrientationSpectrum[0]); - glm::vec3 v2 = (it->Orientation); - glm::vec3 v3 = glm::normalize(glm::cross(v1,v2)); - float angle = glm::acos(glm::dot(v1, v2) / (glm::length(v1) * glm::length(v2))); - transformComponent->Orientation = glm::angleAxis(angle, v3); transformComponent->Position += transformComponent->Velocity * (float)dt; it++; @@ -98,8 +117,8 @@ void Systems::ParticleSystem::SpawnParticles(EntityID emitterID) auto particleTransform = m_World->GetComponent(ent, "Transform"); particleTransform->Position = emitterTransform->Position; - particleTransform->Scale = glm::vec3(1, 1, 1); + particleTransform->Orientation = emitterOrientation; //The emitter's orientation as "start value" times the default direction for emitter. Times the speed, and then rotate on x and y axis with the randomized spread angle. float spreadAngle = emitterComponent->SpreadAngle; particleTransform->Velocity = emitterOrientation * glm::vec3(0, 0, -1) * speed * @@ -107,33 +126,44 @@ void Systems::ParticleSystem::SpawnParticles(EntityID emitterID) glm::normalize(glm::angleAxis(RandomizeAngle(spreadAngle), glm::vec3(0, 1, 0))) * glm::normalize(glm::angleAxis(RandomizeAngle(spreadAngle), glm::vec3(0, 0, 1))); - glm::vec3 testVel = glm::vec3(particleTransform->Velocity.x, -particleTransform->Velocity.y * 1.5, particleTransform->Velocity.z); //TEMP - auto particle = m_World->AddComponent(ent, "Particle"); particle->LifeTime = emitterComponent->LifeTime; - particle->ScaleSpectrum = emitterComponent->ScaleSpectrum; //TEMP - //particle->ScaleSpectrum.push_back(glm::vec3(1,4,1)); //TEMP - particle->VelocitySpectrum.push_back(particleTransform->Velocity); //TEMP - particle->VelocitySpectrum.push_back(testVel); //TEMP -// particle->AngularVelocitySpectrum.push_back(0.f); -// particle->AngularVelocitySpectrum.push_back(-glm::pi()); - particle->OrientationSpectrum = particle->VelocitySpectrum; -// particle->OrientationSpectrum.push_back(glm::vec3(0,1,0)); -// particle->OrientationSpectrum.push_back(glm::vec3(0,-1,0)); - -// Color startColor = {.4f, .45f, .2f}; -// particle->ColorSpectrum.push_back(startColor); -// Color endColor = {0.f, 45.f, 23.f}; -// particle->ColorSpectrum.push_back(endColor); - + particle->ScaleSpectrum = emitterComponent->ScaleSpectrum; + particle->VelocitySpectrum.push_back(particleTransform->Velocity); + + if (emitterComponent->ScaleSpectrum.size() > 0) + { + if (emitterComponent->ScaleSpectrum.size() > 1) + { + particle->ScaleSpectrum = emitterComponent->ScaleSpectrum; + } + else + { + particleTransform->Scale = emitterComponent->ScaleSpectrum[0]; + } + } + else + { + particleTransform->Scale = glm::vec3(1, 1, 1); + } + + if(emitterComponent->UseGoalVelocity) + particle->VelocitySpectrum.push_back(emitterComponent->GoalVelocity); + particle->OrientationSpectrum = emitterComponent->OrientationSpectrum; + if(particle->OrientationSpectrum.size() != 0) + particleTransform->Orientation = glm::angleAxis(0.f, particle->OrientationSpectrum[0]); + particle->AngularVelocitySpectrum = emitterComponent->AngularVelocitySpectrum; ParticleData data; data.ParticleID = ent; data.SpawnTime = glfwGetTime(); - //data.AngularVelocity = particle->AngularVelocitySpectrum[0]; - data.Orientation = particle->OrientationSpectrum[0]; - + if (particle->AngularVelocitySpectrum.size() != 0) + data.AngularVelocity = particle->AngularVelocitySpectrum[0]; + if (particle->OrientationSpectrum.size() != 0) + data.Orientation = particle->OrientationSpectrum[0]; + else data.Orientation = emitterOrientation * glm::vec3(0,0,-1); + m_ParticleEmitter[emitterID].push_back(data); } } diff --git a/src/Systems/ParticleSystem.h b/src/Systems/ParticleSystem.h index 4dff51e..082c957 100644 --- a/src/Systems/ParticleSystem.h +++ b/src/Systems/ParticleSystem.h @@ -19,7 +19,6 @@ namespace Systems { EntityID ParticleID; double SpawnTime; - float Scale; float AngularVelocity; glm::vec3 Orientation; Color color;