diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CFactory.cpp b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CFactory.cpp index eab5ff167..f37bd9a94 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CFactory.cpp +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CFactory.cpp @@ -25,13 +25,6 @@ This file is part of the "Skylicht Engine". #include "pch.h" #include "CFactory.h" -#include "Renderers/IRenderer.h" -#include "Zones/CZone.h" -#include "Emitters/CEmitter.h" - -#include "Emitters/CRandomEmitter.h" -#include "Zones/CPoint.h" - namespace Skylicht { namespace Particle @@ -57,23 +50,10 @@ namespace Skylicht m_emitters.clear(); } - CEmitter* CFactory::createEmitter(EEmitter type) + CRandomEmitter* CFactory::createRandomEmitter() { - CEmitter *e = NULL; - - switch (type) - { - case EEmitter::Random: - e = new CRandomEmitter(); - break; - default: - e = NULL; - break; - } - - if (e != NULL) - m_emitters.push_back(e); - + CRandomEmitter *e = new CRandomEmitter(); + m_emitters.push_back(e); return e; } @@ -87,9 +67,11 @@ namespace Skylicht } } - IRenderer* CFactory::createRenderer(ERenderer type) + CQuadRenderer* CFactory::createQuadRenderer() { - return NULL; + CQuadRenderer *r = new CQuadRenderer(); + m_renderers.push_back(r); + return r; } void CFactory::deleteRenderer(IRenderer* r) @@ -102,23 +84,10 @@ namespace Skylicht } } - CZone* CFactory::createZone(EZone type) + CPoint* CFactory::createPointZone() { - CZone *z = NULL; - - switch (type) - { - case EZone::Point: - z = new CPoint(); - break; - default: - z = NULL; - break; - } - - if (z != NULL) - m_zones.push_back(z); - + CPoint *z = new CPoint(); + m_zones.push_back(z); return z; } diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CFactory.h b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CFactory.h index 8dbddb887..81dfaaabb 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CFactory.h +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CFactory.h @@ -24,36 +24,18 @@ This file is part of the "Skylicht Engine". #pragma once +#include "Renderers/IRenderer.h" +#include "Zones/CZone.h" +#include "Emitters/CEmitter.h" + +#include "Renderers/CQuadRenderer.h" +#include "Zones/CPoint.h" +#include "Emitters/CRandomEmitter.h" + namespace Skylicht { namespace Particle { - class CEmitter; - class CZone; - class IRenderer; - - enum EZone - { - Sphere, - Point, - AABox, - Plane, - Line, - Ring, - Cylinder - }; - - enum EEmitter - { - Random, - }; - - enum ERenderer - { - Quad, - Mesh, - }; - class CFactory { protected: @@ -66,15 +48,15 @@ namespace Skylicht virtual ~CFactory(); - CEmitter* createEmitter(EEmitter type = Random); + CRandomEmitter* createRandomEmitter(); void deleteEmitter(CEmitter *e); - IRenderer* createRenderer(ERenderer type = Quad); + CQuadRenderer* createQuadRenderer(); void deleteRenderer(IRenderer* r); - CZone* createZone(EZone type = Sphere); + CPoint* createPointZone(); void deleteZone(CZone *z); }; diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CGroup.h b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CGroup.h index 2a9068b8c..10c811639 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CGroup.h +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/CGroup.h @@ -67,7 +67,7 @@ namespace Skylicht void update(); - CZone* setZone(CZone *z) + inline CZone* setZone(CZone *z) { m_zone = z; return m_zone; @@ -78,13 +78,13 @@ namespace Skylicht return m_zone; } - CEmitter* addEmitter(CEmitter *e) + inline CEmitter* addEmitter(CEmitter *e) { m_emitters.push_back(e); return e; } - std::vector& getEmitters() + inline std::vector& getEmitters() { return m_emitters; } @@ -96,12 +96,12 @@ namespace Skylicht m_emitters.erase(i); } - void addSystem(ISystem *s) + inline void addSystem(ISystem *s) { m_systems.push_back(s); } - std::vector& getSystems() + inline std::vector& getSystems() { return m_systems; } @@ -113,6 +113,17 @@ namespace Skylicht m_systems.erase(i); } + inline IRenderer* setRenderer(IRenderer *r) + { + m_renderer = r; + return r; + } + + inline IRenderer* getRenderer() + { + return m_renderer; + } + protected: bool launchParticle(CParticle& p, SLaunchParticle& launch); diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CEmitter.cpp b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CEmitter.cpp index 4b66daebc..ef8ce395c 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CEmitter.cpp +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CEmitter.cpp @@ -32,13 +32,14 @@ namespace Skylicht { namespace Particle { - CEmitter::CEmitter() : + CEmitter::CEmitter(EEmitter type) : m_tank(0), m_flow(0.0f), m_forceMin(0.0f), m_forceMax(0.0f), m_active(true), - m_emitFullZone(true) + m_emitFullZone(true), + m_type(type) { m_fraction = os::Randomizer::frand(); } diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CEmitter.h b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CEmitter.h index beace929a..c7115ee20 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CEmitter.h +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CEmitter.h @@ -31,6 +31,11 @@ namespace Skylicht class CZone; class CParticle; + enum EEmitter + { + Random + }; + class CEmitter { protected: @@ -42,8 +47,9 @@ namespace Skylicht bool m_active; bool m_emitFullZone; + EEmitter m_type; public: - CEmitter(); + CEmitter(EEmitter type); virtual ~CEmitter(); @@ -113,6 +119,11 @@ namespace Skylicht return m_emitFullZone; } + inline EEmitter getType() + { + return m_type; + } + virtual u32 updateNumber(float deltaTime); void generateVelocity(CParticle& particle, CZone* zone); diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CRandomEmitter.cpp b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CRandomEmitter.cpp index 0d73331f1..4fd19ea37 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CRandomEmitter.cpp +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Emitters/CRandomEmitter.cpp @@ -34,7 +34,8 @@ namespace Skylicht namespace Particle { - CRandomEmitter::CRandomEmitter() + CRandomEmitter::CRandomEmitter() : + CEmitter(Random) { } diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/CQuadRenderer.cpp b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/CQuadRenderer.cpp new file mode 100644 index 000000000..7213b8b9c --- /dev/null +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/CQuadRenderer.cpp @@ -0,0 +1,122 @@ +/* +!@ +MIT License + +Copyright (c) 2020 Skylicht Technology CO., LTD + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +This file is part of the "Skylicht Engine". +https://github.com/skylicht-lab/skylicht-engine +!# +*/ + +#include "pch.h" +#include "CQuadRenderer.h" + +namespace Skylicht +{ + namespace Particle + { + CQuadRenderer::CQuadRenderer() : + IRenderer(Quad), + m_atlasNx(1), + m_atlasNy(1) + { + + } + + CQuadRenderer::~CQuadRenderer() + { + + } + + void CQuadRenderer::getParticleBuffer(IMeshBuffer *buffer) + { + IVertexBuffer *vtx = buffer->getVertexBuffer(); + IIndexBuffer *idx = buffer->getIndexBuffer(); + + vtx->set_used(NB_VERTICES_PER_QUAD); + idx->set_used(NB_INDICES_PER_QUAD); + + // setup indices + if (idx->getType() == irr::video::EIT_32BIT) + { + irr::u32* indices = reinterpret_cast(idx->getIndices()); + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; + + indices[3] = 0; + indices[4] = 2; + indices[5] = 3; + } + else if (idx->getType() == irr::video::EIT_16BIT) + { + irr::u16* indices = reinterpret_cast(idx->getIndices()); + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; + + indices[3] = 0; + indices[4] = 2; + indices[5] = 3; + } + + // setup vertices + irr::video::S3DVertex* vertices = (irr::video::S3DVertex*)vtx->getVertices(); + vertices[0].TCoords = core::vector2df(0.0f, 0.0f); + vertices[1].TCoords = core::vector2df(1.0f, 0.0f); + vertices[2].TCoords = core::vector2df(1.0f, 1.0f); + vertices[3].TCoords = core::vector2df(0.0f, 1.0f); + + core::vector3df quadUp(0.0f, 1.0f, 0.0f); + core::vector3df quadSide(-1.0f, 0.0f, 0.0f); + float x = 0.0f, y = 0.0f, z = 0.0f; + + video::SColor black(0x00000000); + + // top left vertex + vertices[0].Pos.set( + x + quadSide.X + quadUp.X, + y + quadSide.Y + quadUp.Y, + z + quadSide.Z + quadUp.Z); + vertices[0].Color = black; + + // top right vertex + vertices[1].Pos.set( + x - quadSide.X + quadUp.X, + y - quadSide.Y + quadUp.Y, + z - quadSide.Z + quadUp.Z); + vertices[1].Color = black; + + // bottom right vertex + vertices[2].Pos.set( + x - quadSide.X - quadUp.X, + y - quadSide.Y - quadUp.Y, + z - quadSide.Z - quadUp.Z); + vertices[2].Color = black; + + // bottom left vertex + vertices[3].Pos.set( + x + quadSide.X - quadUp.X, + y + quadSide.Y - quadUp.Y, + z + quadSide.Z - quadUp.Z); + vertices[3].Color = black; + + // optimize stream on GPU + buffer->setHardwareMappingHint(EHM_STREAM); + } + } +} \ No newline at end of file diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/CQuadRenderer.h b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/CQuadRenderer.h new file mode 100644 index 000000000..9c6a383f6 --- /dev/null +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/CQuadRenderer.h @@ -0,0 +1,66 @@ +/* +!@ +MIT License + +Copyright (c) 2020 Skylicht Technology CO., LTD + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +This file is part of the "Skylicht Engine". +https://github.com/skylicht-lab/skylicht-engine +!# +*/ + +#pragma once + +#include "IRenderer.h" + +namespace Skylicht +{ + namespace Particle + { + class CQuadRenderer : public IRenderer + { + protected: + u32 m_atlasNx; + u32 m_atlasNy; + + static const u32 NB_INDICES_PER_QUAD = 6; + static const u32 NB_VERTICES_PER_QUAD = 4; + + public: + CQuadRenderer(); + + virtual ~CQuadRenderer(); + + virtual void getParticleBuffer(IMeshBuffer *buffer); + + void setAtlas(u32 x, u32 y) + { + m_atlasNx = x; + m_atlasNy = y; + } + + inline u32 getAtlasX() + { + return m_atlasNx; + } + + inline u32 getAtlasY() + { + return m_atlasNy; + } + }; + } +} \ No newline at end of file diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/IRenderer.h b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/IRenderer.h index bf6976eaf..154261878 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/IRenderer.h +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Renderers/IRenderer.h @@ -30,10 +30,19 @@ namespace Skylicht { namespace Particle { + enum ERenderer + { + Quad + }; + class IRenderer { + protected: + ERenderer m_type; + public: - IRenderer() + IRenderer(ERenderer type) : + m_type(type) { } @@ -43,6 +52,11 @@ namespace Skylicht } + inline ERenderer getType() + { + return m_type; + } + virtual void getParticleBuffer(IMeshBuffer *buffer) = 0; }; } diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CPoint.cpp b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CPoint.cpp index f3c2c352d..a0a457306 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CPoint.cpp +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CPoint.cpp @@ -30,7 +30,8 @@ namespace Skylicht { namespace Particle { - CPoint::CPoint() + CPoint::CPoint() : + CZone(Point) { } diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CZone.cpp b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CZone.cpp index 0bbf8bf5d..e840a38f9 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CZone.cpp +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CZone.cpp @@ -34,7 +34,8 @@ namespace Skylicht return from * (to - from) * os::Randomizer::frand(); } - CZone::CZone() + CZone::CZone(EZone type) : + m_type(type) { } diff --git a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CZone.h b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CZone.h index 0177326bb..47ffb8bc0 100644 --- a/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CZone.h +++ b/Projects/Skylicht/Components/Source/ParticleSystem/Particles/Zones/CZone.h @@ -32,13 +32,26 @@ namespace Skylicht float random(float from, float to); + enum EZone + { + Sphere, + Point, + AABox, + Plane, + Line, + Ring, + Cylinder + }; + class CZone { protected: core::vector3df m_position; + EZone m_type; + public: - CZone(); + CZone(EZone type); virtual ~CZone(); @@ -52,6 +65,11 @@ namespace Skylicht return m_position; } + inline EZone getType() + { + return m_type; + } + void normalizeOrRandomize(core::vector3df& v); core::vector3df getTransformPosition(const core::vector3df& pos); diff --git a/Samples/Particles/Source/SampleParticles.cpp b/Samples/Particles/Source/SampleParticles.cpp index 829ea248b..58a2d7a86 100644 --- a/Samples/Particles/Source/SampleParticles.cpp +++ b/Samples/Particles/Source/SampleParticles.cpp @@ -71,13 +71,16 @@ void SampleParticles::initFireParticle(Particle::CParticleComponent *particleCom Particle::CGroup *group = particleComponent->createParticleGroup(); // create start point - Particle::CZone *zone = group->setZone(factory->createZone(Particle::Point)); + Particle::CZone *zone = group->setZone(factory->createPointZone()); zone->setPosition(core::vector3df(0.0f, 0.0f, 0.0f)); // create emitter - Particle::CEmitter *emitter = group->addEmitter(factory->createEmitter(Particle::Random)); + Particle::CEmitter *emitter = group->addEmitter(factory->createRandomEmitter()); emitter->setTank(100); emitter->setFlow(3.0f); + + // create renderer + Particle::IRenderer *renderer = group->setRenderer(factory->createQuadRenderer()); } void SampleParticles::onUpdate()