From 8ac57685948a9aa20e7ec5afbf9206ee693530b9 Mon Sep 17 00:00:00 2001
From: Sebastian Gaida <gaida@ca-digit.com>
Date: Mon, 14 Jun 2021 17:54:55 +0200
Subject: [PATCH] [#69] add moving and respawning particles

---
 projects/particle_simulation/CMakeLists.txt   |   2 +-
 projects/particle_simulation/shaders/frag.spv | Bin 1540 -> 1064 bytes
 projects/particle_simulation/src/Particle.cpp |  32 ++++++++++++++++++
 projects/particle_simulation/src/Particle.hpp |  26 +++++++++-----
 .../src/ParticleSystem.cpp                    |  20 +++++++++--
 .../src/ParticleSystem.hpp                    |   6 +++-
 projects/particle_simulation/src/main.cpp     |  27 +++++++--------
 7 files changed, 85 insertions(+), 28 deletions(-)
 create mode 100644 projects/particle_simulation/src/Particle.cpp

diff --git a/projects/particle_simulation/CMakeLists.txt b/projects/particle_simulation/CMakeLists.txt
index 43dfb169..2e62c66e 100644
--- a/projects/particle_simulation/CMakeLists.txt
+++ b/projects/particle_simulation/CMakeLists.txt
@@ -11,7 +11,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 # adding source files to the project
 add_executable(particle_simulation src/main.cpp
 		src/ParticleSystem.hpp src/ParticleSystem.cpp
-		src/Particle.hpp)
+		src/Particle.hpp src/Particle.cpp)
 
 # this should fix the execution path to load local files from the project (for MSVC)
 if(MSVC)
diff --git a/projects/particle_simulation/shaders/frag.spv b/projects/particle_simulation/shaders/frag.spv
index fdf98514955a63d0e54791970d2f1867ca3c5375..1b3a6f369887d3cad66e2f93316261c9c94202ac 100644
GIT binary patch
delta 260
zcmZqSS;4`}%%sfDz`)4B#lXv;IFZ*>n2mvjfdPzj6EpLGOa`fmk$;6*803J=Qs?}f
z{2~ShHU?G(xyg-;!i)-&r!q#HdVu&KwLqW@p%~m5n89L9K)yTBKm{PJ1eXKyH=8oC
zGp1?-rPzSN(oiWFUk1!?u-9Q=XOIB0Wua<7;vlskEC;m$B(DH8M;=IntOGg48p>Ay
ZiA{dVJYU2Ps9Flh1DW&}=w%Ba1^|G$7P|ld

literal 1540
zcmYk5%Wl&^7=@?JrEPkrH?GBLfC4Sy))piLD2>1@BBg={utIDVqco0e2Z<fL0Pn#Y
zuwucAM`DA-`5X`RL`U=g=RY%Z<{zgt-Iy_E%GAuFd15AG)l7>qX5Lh@+3mdRG?UbC
z9vnVEv1Ce_5Y4igF=fr*tQQU`To$ehE7HO107WJ3YRoS!Dw{ducD&ZxV=oCty||YK
zUh<*m2eB8u{}}Ys1WgT%+wHoYS6+WK@{;uPAn*p^F!1~^mMZ)dpqnk|!eM_f_KSjw
z6h&|3bMkQ(jT0?575!?O$0tz|reVYds`|k(M(1><T@Y80W*qm8#%VhmL@{eBTF?DY
z2j1(rciN7k*q`uab6>$YS5~DYXY}*M_<N|_ZuUkR>!pz?jd9gWIQr>IkEfmgwMkxA
z&ihcu-*%ynw|QY%V1MhOxIdiTA3w$Y$=RQ=CKbAR_QI1jn~JOA9AQi6^Zw-M9Obi`
z;lOr&7h-DoLdX4{<vI6*+fcr!*%79My*yu1%%IMl91;!c<SSV=*?(0rd*R2{*A=rL
zUN7b~z8U;n(#+Qmj~{aS2}k{kX4cv|IsJuWf6l23#{52B*U3AIEPo^8&-0sE{^jMq
zI>Uau0vbS#nSSv$)H$C&B=>>CA35&>NBvPAqd(GH!<PjHclaZwqM5b43;zw?q9y0_
z>ViQ3=`nqLE**DT6R26;hGMIupH{c2nA(X>Vc#u*weT<Gfb-zc<MEn6|GHA6=evai
z4El<e+I4~T3(D~12-MpG>!|<Gx%9jtI6__cE;agF0=(_*H)-*3Ti6w-TVHn+7k%AT
z4hI;VYklo0F8bQf>-b_F^`E(~dy1(SeKnQCTVE|{dB?{BZ_8U)Uk5pFy&o!vV~?--
UeU21!Cu;PZ?-%Z`Tt5~50TYvMx&QzG

diff --git a/projects/particle_simulation/src/Particle.cpp b/projects/particle_simulation/src/Particle.cpp
new file mode 100644
index 00000000..cdb69f7b
--- /dev/null
+++ b/projects/particle_simulation/src/Particle.cpp
@@ -0,0 +1,32 @@
+
+#include "Particle.hpp"
+
+Particle::Particle(glm::vec3 position, glm::vec3 velocity, float lifeTime)
+: m_position(position),
+m_velocity(velocity),
+m_lifeTime(lifeTime)
+{}
+
+const glm::vec3& Particle::getPosition()const{
+    return m_position;
+}
+
+const bool Particle::isAlive()const{
+    return m_lifeTime > 0.f;
+}
+
+void Particle::setPosition( const glm::vec3 pos ){
+    m_position = pos;
+}
+
+void Particle::update( const float delta ){
+    m_position += m_velocity * delta;
+}
+
+void Particle::setLifeTime( const float lifeTime ){
+    m_lifeTime = lifeTime;
+}
+
+const float& Particle::getLifeTime()const{
+    return m_lifeTime;
+}
\ No newline at end of file
diff --git a/projects/particle_simulation/src/Particle.hpp b/projects/particle_simulation/src/Particle.hpp
index b392d543..9c08631e 100644
--- a/projects/particle_simulation/src/Particle.hpp
+++ b/projects/particle_simulation/src/Particle.hpp
@@ -1,20 +1,28 @@
 #pragma once
 
+#include <glm/glm.hpp>
+
 class Particle {
 
 public:
-    Particle(glm::vec3 position, glm::vec3 velocity)
-    noexcept
-            : m_position(position),
-              m_velocity(velocity) {}
-
-    const glm::vec3& getPosition()const{
-        return m_position;
-    };
+    Particle(glm::vec3 position, glm::vec3 velocity, float lifeTime = 1.f);
+
+    const glm::vec3& getPosition()const;
+
+    void setPosition( const glm::vec3 pos );
+
+    void update( const float delta );
+
+    const bool isAlive()const;
+
+    void setLifeTime( const float lifeTime );
+
+    const float& getLifeTime()const;
+
 private:
     // all properties of the Particle
     glm::vec3 m_position;
-    float padding = 0.f;
+    float m_lifeTime;
     glm::vec3 m_velocity;
     float padding_2 = 0.f;
 };
\ No newline at end of file
diff --git a/projects/particle_simulation/src/ParticleSystem.cpp b/projects/particle_simulation/src/ParticleSystem.cpp
index 5428b02b..4c3a9286 100644
--- a/projects/particle_simulation/src/ParticleSystem.cpp
+++ b/projects/particle_simulation/src/ParticleSystem.cpp
@@ -1,6 +1,6 @@
 #include "ParticleSystem.hpp"
 
-const std::vector<Particle>& ParticleSystem::getParticles() const {
+const std::vector<Particle>& ParticleSystem::getParticles() const{
     return m_particles;
 }
 
@@ -9,4 +9,20 @@ void ParticleSystem::addParticle( const Particle particle ){
 }
 void ParticleSystem::addParticles( const std::vector<Particle> particles ){
     m_particles.insert(m_particles.end(), particles.begin(), particles.end());
-}
\ No newline at end of file
+}
+
+void ParticleSystem::updateParticles( const float deltaTime ){
+    for(Particle& particle :m_particles){
+        bool alive = particle.isAlive();
+        particle.setPosition( particle.getPosition() * static_cast<float>(alive) + static_cast<float>(!alive) * m_respawnPos );
+        particle.setLifeTime( (particle.getLifeTime() * alive + !alive * m_maxLifeTime ) - deltaTime );
+        particle.update(deltaTime);
+    }
+}
+
+void ParticleSystem::setRespawnPos( const glm::vec3 respawnPos){
+    m_respawnPos = respawnPos;
+}
+void ParticleSystem::setMaxLifeTime( const float respawnTime ){
+    m_maxLifeTime = respawnTime;
+}
diff --git a/projects/particle_simulation/src/ParticleSystem.hpp b/projects/particle_simulation/src/ParticleSystem.hpp
index c7e1a2fd..e4ec3b36 100644
--- a/projects/particle_simulation/src/ParticleSystem.hpp
+++ b/projects/particle_simulation/src/ParticleSystem.hpp
@@ -1,6 +1,5 @@
 #pragma once
 
-#include <glm/glm.hpp>
 #include <vector>
 #include "Particle.hpp"
 
@@ -10,7 +9,12 @@ public:
     const std::vector<Particle> &getParticles() const;
     void addParticle( const Particle particle );
     void addParticles( const std::vector<Particle> particles );
+    void updateParticles( const float deltaTime );
+    void setRespawnPos( const glm::vec3 respawnPos );
+    void setMaxLifeTime( const float respawnTime );
 
 private:
     std::vector<Particle> m_particles;
+    glm::vec3 m_respawnPos = glm::vec3(0.f);
+    float m_maxLifeTime = 1.f;
 };
\ No newline at end of file
diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp
index a0db6620..ef718ceb 100644
--- a/projects/particle_simulation/src/main.cpp
+++ b/projects/particle_simulation/src/main.cpp
@@ -57,11 +57,7 @@ int main(int argc, const char** argv) {
     particleShaderProgram.reflectShader(vkcv::ShaderStage::VERTEX);
     particleShaderProgram.reflectShader(vkcv::ShaderStage::FRAGMENT);
 
-    std::vector<vkcv::DescriptorBinding> descriptorBindings = {
-            vkcv::DescriptorBinding(0, vkcv::DescriptorType::UNIFORM_BUFFER,   1, vkcv::ShaderStage::FRAGMENT),
-            vkcv::DescriptorBinding(1, vkcv::DescriptorType::UNIFORM_BUFFER,   1, vkcv::ShaderStage::FRAGMENT)};
-
-    vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings);
+    vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(particleShaderProgram.getReflectedDescriptors()[0]);
 
     vkcv::Buffer<glm::vec3> vertexBuffer = core.createBuffer<glm::vec3>(
             vkcv::BufferType::VERTEX,
@@ -124,22 +120,19 @@ int main(int argc, const char** argv) {
     vkcv::DescriptorSetUsage    descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle);
     //vkcv::DrawcallInfo drawcalls(renderMesh, {vkcv::DescriptorSetUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle)});
 
-    glm::vec3 instancePosition;
-
     glm::vec2 pos = glm::vec2(1.f);
 
     window.e_mouseMove.add([&]( double offsetX, double offsetY) {
         pos = glm::vec2(static_cast<float>(offsetX), static_cast<float>(offsetY));
-        instancePosition.x = static_cast<float>(offsetX);
-        instancePosition.y = static_cast<float>(offsetY);
-        instancePosition.z = -1.f;
     });
 
     ParticleSystem particleSystem;
+    particleSystem.setMaxLifeTime(3.f);
+    glm::vec3 vel = glm::vec3(0.f , 0.1f, 0.0f);
     particleSystem.addParticles({
-                                        Particle(instancePosition, glm::vec3(0.f)),
-                                        Particle(glm::vec3( 0.2f,  0.1f, 0.f), glm::vec3(0.f)),
-                                        Particle(glm::vec3(0.15f,  0.f, 0.1f), glm::vec3(0.f))});
+                                        Particle(glm::vec3(0.f, 1.f, 0.f), vel, 1.f),
+                                        Particle(glm::vec3( 0.2f,  0.1f, 0.f), vel, 2.f),
+                                        Particle(glm::vec3(0.15f,  0.f, 0.1f), vel, 3.f)});
 
     std::vector<glm::mat4> modelMatrices;
     std::vector<vkcv::DrawcallInfo> drawcalls;
@@ -152,8 +145,6 @@ int main(int argc, const char** argv) {
 
     glm::vec4 colorData = glm::vec4(1.0f,1.0f,0.0f,1.0f);
 
-
-
     while (window.isWindowOpen())
     {
         window.pollEvents();
@@ -169,6 +160,12 @@ int main(int argc, const char** argv) {
         auto end = std::chrono::system_clock::now();
         float deltatime = std::chrono::duration<float>(end - start).count();
         start = end;
+        particleSystem.updateParticles( deltatime );
+
+        modelMatrices.clear();
+        for(Particle particle :  particleSystem.getParticles()) {
+            modelMatrices.push_back(glm::translate(glm::mat4(1.f), particle.getPosition()));
+        }
 
         //modelmatrix = glm::rotate(modelmatrix, angle, glm::vec3(0,0,1));
 
-- 
GitLab