Skip to content

Commit

Permalink
feat: #102 add culling system for particle
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Sep 8, 2020
1 parent 8b6b1c2 commit f8764e2
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ This file is part of the "Skylicht Engine".
#include "GameObject/CGameObject.h"
#include "Entity/CEntityManager.h"

#include "Culling/CCullingData.h"
#include "Culling/CCullingBBoxData.h"
#include "Transform/CWorldInverseTransformData.h"

namespace Skylicht
{
namespace Particle
Expand All @@ -49,8 +53,15 @@ namespace Skylicht

void CParticleComponent::initComponent()
{
CEntity *entity = m_gameObject->getEntity();

// add particle buffer data
m_data = m_gameObject->getEntity()->addData<CParticleBufferData>();
m_data = entity->addData<CParticleBufferData>();

// add culling
entity->addData<CCullingData>();
entity->addData<CCullingBBoxData>();
entity->addData<CWorldInverseTransformData>();

// add renderer system
m_gameObject->getEntityManager()->addRenderSystem<CParticleRenderer>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ namespace Skylicht
{
m_particles.set_used(0);
m_transforms.set_used(0);
m_cullings.set_used(0);
}

void CParticleRenderer::onQuery(CEntityManager *entityManager, CEntity *entity)
Expand All @@ -58,6 +59,26 @@ namespace Skylicht
{
m_particles.push_back(particleData);
m_transforms.push_back(transform);

// update bbox for culling
// use last frame data
CCullingBBoxData *box = entity->getData<CCullingBBoxData>();
CWorldInverseTransformData *worldInverse = entity->getData<CWorldInverseTransformData>();

CGroup** groups = particleData->Groups.pointer();
for (u32 i = 0, n = particleData->Groups.size(); i < n; i++)
{
CGroup *g = groups[i];
if (i == 0)
box->BBox = g->getBBox();
else
box->BBox.addInternalBox(g->getBBox());
}

// convert world bbox to local
worldInverse->WorldInverse.transformBoxEx(box->BBox);

m_cullings.push_back(entity->getData<CCullingData>());
}
}
}
Expand Down Expand Up @@ -89,6 +110,7 @@ namespace Skylicht

CParticleBufferData** particles = m_particles.pointer();
CWorldTransformData** transforms = m_transforms.pointer();
CCullingData** cullings = m_cullings.pointer();

for (u32 i = 0, n = m_particles.size(); i < n; i++)
{
Expand All @@ -97,7 +119,7 @@ namespace Skylicht
for (u32 j = 0, m = data->Groups.size(); j < m; j++)
{
data->Groups[j]->setWorldMatrix(transforms[i]->World);
data->Groups[j]->update();
data->Groups[j]->update(cullings[i]->Visible);
}
}
}
Expand All @@ -112,9 +134,12 @@ namespace Skylicht
getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix);

CParticleBufferData** particles = m_particles.pointer();
CCullingData** cullings = m_cullings.pointer();

for (u32 i = 0, n = m_particles.size(); i < n; i++)
{
renderParticleGroup(particles[i]);
if (cullings[i]->Visible == true)
renderParticleGroup(particles[i]);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ This file is part of the "Skylicht Engine".
#include "Entity/IEntityData.h"
#include "Entity/IRenderSystem.h"

#include "Culling/CCullingBBoxData.h"
#include "Culling/CCullingData.h"
#include "Transform/CWorldTransformData.h"
#include "Transform/CWorldInverseTransformData.h"
#include "ParticleSystem/CParticleBufferData.h"

namespace Skylicht
Expand All @@ -39,6 +42,7 @@ namespace Skylicht
protected:
core::array<CParticleBufferData*> m_particles;
core::array<CWorldTransformData*> m_transforms;
core::array<CCullingData*> m_cullings;

public:
CParticleRenderer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ namespace Skylicht
return p;
}

void CGroup::update()
void CGroup::update(bool updateBuffer)
{
if (m_zone == NULL)
return;
Expand Down Expand Up @@ -114,20 +114,31 @@ namespace Skylicht
for (ISystem *s : m_systems)
s->update(particles, numParticles, this, dt);

// remove die particle
if (numParticles > 0)
m_bbox.reset(particles[0].Position);

// remove die particle & update box
for (u32 i = 0; i < numParticles; i++)
{
CParticle& p = particles[i];

if (p.Life < 0)
{
// remove dead particle
remove(i);
--i;
--numParticles;
}
else
{
// add bbox
m_bbox.addInternalPoint(p.Position);
}
}

m_bufferSystem->update(particles, numParticles, this, dt);
// update instancing buffer
if (updateBuffer == true)
m_bufferSystem->update(particles, numParticles, this, dt);

u32 emiterId = 0;
u32 emiterLaunch = m_launch.size();
Expand All @@ -149,8 +160,6 @@ namespace Skylicht
}
}
}

// printf("Particle update: %d\n", m_particles.size());
}

bool CGroup::launchParticle(CParticle& p, SLaunchParticle& launch)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,14 @@ namespace Skylicht

protected:
core::matrix4 m_world;
core::aabbox3df m_bbox;

public:
CGroup();

virtual ~CGroup();

void update();
void update(bool updateBuffer);

inline void setWorldMatrix(const core::matrix4& m)
{
Expand All @@ -107,6 +108,16 @@ namespace Skylicht
return m_zone;
}

inline const core::aabbox3df& getBBox()
{
return m_bbox;
}

inline u32 getNumParticles()
{
return m_particles.size();
}

inline CEmitter* addEmitter(CEmitter *e)
{
m_emitters.push_back(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ namespace Skylicht
u32 totalFrames = frameX * frameY;
float frameW = 1.0f / frameX;
float frameH = 1.0f / frameY;
u32 frame, row, col;

#pragma omp parallel for private(p, params, data)
#pragma omp parallel for private(p, params, data, frame, row, col)
for (int i = 0; i < num; i++)
{
p = particles + i;
Expand All @@ -93,12 +94,12 @@ namespace Skylicht
);
data->Rotation = p->Rotation;

u32 frame = (u32)params[FrameIndex];
frame = (u32)params[FrameIndex];
frame = frame < 0 ? 0 : frame;
frame = frame >= totalFrames ? totalFrames - 1 : frame;

u32 row = frame / frameX;
u32 col = frame - (row * frameX);
row = frame / frameX;
col = frame - (row * frameX);

data->UVScale.set(frameW, frameH);
data->UVOffset.set(col * frameW, row * frameH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ namespace Skylicht
// update position
p->LastPosition = p->Position;

p->Position = p->Position + p->Velocity * dt;
p->Position += p->Velocity * dt;

// update gravity
p->Velocity = p->Velocity + gravity;
p->Velocity += gravity;

// update rotation
if (p->HaveRotate == true)
Expand Down
39 changes: 39 additions & 0 deletions Projects/Skylicht/Engine/Source/Culling/CCullingBBoxData.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
!@
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 "CCullingBBoxData.h"

namespace Skylicht
{
CCullingBBoxData::CCullingBBoxData()
{

}

CCullingBBoxData::~CCullingBBoxData()
{

}
}
43 changes: 43 additions & 0 deletions Projects/Skylicht/Engine/Source/Culling/CCullingBBoxData.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
!@
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 "Entity/IEntityData.h"
#include "Material/CMaterial.h"

namespace Skylicht
{
class CCullingBBoxData : public IEntityData
{
public:
core::aabbox3df BBox;
ArrayMaterial Materials;

public:
CCullingBBoxData();

virtual ~CCullingBBoxData();
};
}
Loading

0 comments on commit f8764e2

Please sign in to comment.