LCOV - code coverage report
Current view: top level - source/graphics - ParticleEmitter.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 0 17 0.0 %
Date: 2023-01-19 00:18:29 Functions: 0 9 0.0 %

          Line data    Source code
       1             : /* Copyright (C) 2023 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #ifndef INCLUDED_PARTICLEEMITTER
      19             : #define INCLUDED_PARTICLEEMITTER
      20             : 
      21             : #include "graphics/ModelAbstract.h"
      22             : #include "graphics/ParticleEmitterType.h"
      23             : #include "maths/Quaternion.h"
      24             : #include "renderer/backend/IDeviceCommandContext.h"
      25             : #include "renderer/backend/IShaderProgram.h"
      26             : #include "renderer/VertexArray.h"
      27             : 
      28             : #include <map>
      29             : 
      30             : /**
      31             :  * Simulation state for a single particle.
      32             :  */
      33           0 : struct SParticle
      34             : {
      35             :     CVector3D pos;
      36             :     CVector3D velocity;
      37             :     float angle;
      38             :     float angleSpeed;
      39             :     float size;
      40             :     float sizeGrowthRate;
      41             :     SColor4ub color;
      42             :     float age;
      43             :     float maxAge;
      44             : };
      45             : 
      46             : typedef std::shared_ptr<CParticleEmitter> CParticleEmitterPtr;
      47             : 
      48             : /**
      49             :  * Particle emitter.
      50             :  *
      51             :  * Emitters store particle data in two forms:
      52             :  *  * m_Particles contains the raw data used for the CPU particle simulation.
      53             :  *  * m_VertexArray contains the data required for rendering.
      54             :  * Particles are rendered as billboard quads, so the vertex array contains four vertices
      55             :  * per particle with different UV coordinates. The billboard position computation is
      56             :  * performed by a vertex shader.
      57             :  *
      58             :  * The number of particles is a constant for the entire life of the emitter,
      59             :  * to simplify the updating and rendering.
      60             :  * m_Particles acts like a ring buffer, so we don't have to worry about dynamically
      61             :  * allocating particles. If particles have variable lifetimes, they'll exist in the
      62             :  * array with alpha=0 until they're overwritten by a new particle after the maximum
      63             :  * lifetime.
      64             :  *
      65             :  * (It's quite likely this could be made more efficient, if the overhead of any added
      66             :  * complexity is not high.)
      67             :  */
      68           0 : class CParticleEmitter
      69             : {
      70             : public:
      71             :     CParticleEmitter(const CParticleEmitterTypePtr& type);
      72             : 
      73             :     /**
      74             :      * Set the position to be used for emission of new particles.
      75             :      */
      76           0 :     void SetPosition(const CVector3D& pos)
      77             :     {
      78           0 :         m_Pos = pos;
      79           0 :     }
      80             : 
      81           0 :     CVector3D GetPosition() const
      82             :     {
      83           0 :         return m_Pos;
      84             :     }
      85             : 
      86             :     /**
      87             :      * Set the rotation to be used for emission of new particles (note: depends on particles).
      88             :      */
      89           0 :     void SetRotation(const CQuaternion& rot)
      90             :     {
      91           0 :         m_Rot = rot;
      92           0 :     }
      93             : 
      94           0 :     const CQuaternion& GetRotation() const
      95             :     {
      96           0 :         return m_Rot;
      97             :     }
      98             : 
      99             :     /**
     100             :      * Get the bounding box of the center points of particles at their current positions.
     101             :      */
     102           0 :     const CBoundingBoxAligned& GetParticleBounds() const { return m_ParticleBounds; }
     103             : 
     104             :     /**
     105             :      * Push a new particle onto the ring buffer. (May overwrite an old particle.)
     106             :      */
     107             :     void AddParticle(const SParticle& particle);
     108             : 
     109             :     /**
     110             :      * Update particle and vertex array data. Must be called before RenderArray.
     111             :      *
     112             :      * If frameNumber is the same as the previous call to UpdateArrayData,
     113             :      * then the function will do no work and return immediately.
     114             :      */
     115             :     void UpdateArrayData(int frameNumber);
     116             : 
     117             :     /**
     118             :      * Make the vertex data available for subsequent binding and rendering.
     119             :      */
     120             :     void PrepareForRendering();
     121             : 
     122             :     /**
     123             :      * Upload the vertex data to the backend.
     124             :      */
     125             :     void UploadData(
     126             :         Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
     127             : 
     128             :     /**
     129             :      * Bind rendering state (textures and blend modes).
     130             :      */
     131             :     void Bind(
     132             :         Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
     133             :         Renderer::Backend::IShaderProgram* shader);
     134             : 
     135             :     /**
     136             :      * Draw the vertex array.
     137             :      */
     138             :     void RenderArray(
     139             :         Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
     140             : 
     141             :     /**
     142             :      * Stop this emitter emitting new particles, and pass responsibility for rendering
     143             :      * to the CParticleManager. This should be called before dropping the last std::shared_ptr
     144             :      * to this object so that it will carry on rendering (until all particles have dissipated)
     145             :      * even when it's no longer attached to a model.
     146             :      * @param self the std::shared_ptr you're about to drop
     147             :      */
     148             :     void Unattach(const CParticleEmitterPtr& self);
     149             : 
     150             :     void SetEntityVariable(const std::string& name, float value);
     151             : 
     152             :     CParticleEmitterTypePtr m_Type;
     153             : 
     154             :     /// Whether this emitter is still emitting new particles
     155             :     bool m_Active;
     156             : 
     157             :     CVector3D m_Pos;
     158             :     CQuaternion m_Rot;
     159             : 
     160             :     std::map<std::string, float> m_EntityVariables;
     161             : 
     162             :     std::vector<SParticle> m_Particles;
     163             :     size_t m_NextParticleIdx;
     164             : 
     165             :     float m_LastUpdateTime;
     166             :     float m_EmissionRoundingError;
     167             : 
     168             : private:
     169             :     /// Bounding box of the current particle center points
     170             :     CBoundingBoxAligned m_ParticleBounds;
     171             : 
     172             :     VertexIndexArray m_IndexArray;
     173             : 
     174             :     VertexArray m_VertexArray;
     175             :     VertexArray::Attribute m_AttributePos;
     176             :     VertexArray::Attribute m_AttributeAxis;
     177             :     VertexArray::Attribute m_AttributeUV;
     178             :     VertexArray::Attribute m_AttributeColor;
     179             : 
     180             :     Renderer::Backend::IVertexInputLayout* m_VertexInputLayout = nullptr;
     181             : 
     182             :     int m_LastFrameNumber;
     183             : };
     184             : 
     185             : /**
     186             :  * Particle emitter model, for attaching emitters as props on other models.
     187             :  */
     188             : class CModelParticleEmitter : public CModelAbstract
     189             : {
     190             : public:
     191             :     CModelParticleEmitter(const CParticleEmitterTypePtr& type);
     192             :     ~CModelParticleEmitter();
     193             : 
     194             :     /// Dynamic cast
     195           0 :     virtual CModelParticleEmitter* ToCModelParticleEmitter()
     196             :     {
     197           0 :         return this;
     198             :     }
     199             : 
     200             :     virtual CModelAbstract* Clone() const;
     201             : 
     202           0 :     virtual void SetTerrainDirty(ssize_t UNUSED(i0), ssize_t UNUSED(j0), ssize_t UNUSED(i1), ssize_t UNUSED(j1))
     203             :     {
     204           0 :     }
     205             : 
     206             :     virtual void SetEntityVariable(const std::string& name, float value);
     207             : 
     208             :     virtual void CalcBounds();
     209             :     virtual void ValidatePosition();
     210             :     virtual void InvalidatePosition();
     211             :     virtual void SetTransform(const CMatrix3D& transform);
     212             : 
     213             :     CParticleEmitterTypePtr m_Type;
     214             :     CParticleEmitterPtr m_Emitter;
     215             : };
     216             : 
     217             : #endif // INCLUDED_PARTICLEEMITTER

Generated by: LCOV version 1.13