Added very basic particle system and rendering
This commit is contained in:
@@ -53,22 +53,20 @@ namespace Nuake
|
||||
s_CurrentWindow->Update(s_TimeStep);
|
||||
|
||||
// Play mode update all the entities, Editor does not.
|
||||
if (Engine::IsPlayMode())
|
||||
{
|
||||
s_FixedUpdateDifference += s_TimeStep;
|
||||
|
||||
// Fixed update
|
||||
while (s_FixedUpdateDifference >= s_FixedUpdateRate)
|
||||
{
|
||||
s_CurrentWindow->FixedUpdate(s_FixedUpdateDifference);
|
||||
|
||||
s_FixedUpdateDifference -= s_FixedUpdateRate;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!Engine::IsPlayMode())
|
||||
{
|
||||
GetCurrentScene()->EditorUpdate(s_TimeStep);
|
||||
}
|
||||
|
||||
s_FixedUpdateDifference += s_TimeStep;
|
||||
|
||||
// Fixed update
|
||||
while (s_FixedUpdateDifference >= s_FixedUpdateRate)
|
||||
{
|
||||
s_CurrentWindow->FixedUpdate(s_FixedUpdateDifference);
|
||||
|
||||
s_FixedUpdateDifference -= s_FixedUpdateRate;
|
||||
}
|
||||
}
|
||||
|
||||
Input::Update();
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
#include "src/Scene/Components/BSPBrushComponent.h"
|
||||
#include "src/Scene/Components/SpriteComponent.h"
|
||||
#include "src/Scene/Components/ParticleEmitterComponent.h"
|
||||
|
||||
#include <GL\glew.h>
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
void SceneRenderer::Init()
|
||||
@@ -231,6 +233,7 @@ namespace Nuake
|
||||
|
||||
Renderer::SubmitMesh(sprite.SpriteMesh, finalQuadTransform, (uint32_t)e);
|
||||
}
|
||||
|
||||
Renderer::Flush(shader, true);
|
||||
}
|
||||
}
|
||||
@@ -286,7 +289,7 @@ namespace Nuake
|
||||
|
||||
// Sprites
|
||||
auto spriteView = scene.m_Registry.view<TransformComponent, SpriteComponent, VisibilityComponent>();
|
||||
for (auto e : spriteView)
|
||||
for (auto& e : spriteView)
|
||||
{
|
||||
auto [transform, sprite, visibility] = spriteView.get<TransformComponent, SpriteComponent, VisibilityComponent>(e);
|
||||
|
||||
@@ -316,6 +319,34 @@ namespace Nuake
|
||||
Renderer::SubmitMesh(sprite.SpriteMesh, finalQuadTransform, (uint32_t)e);
|
||||
}
|
||||
Renderer::Flush(gBufferShader, false);
|
||||
|
||||
// Particles
|
||||
auto particleEmitterView = scene.m_Registry.view<TransformComponent, ParticleEmitterComponent, VisibilityComponent>();
|
||||
for (auto& e : particleEmitterView)
|
||||
{
|
||||
auto [transform, emitterComponent, visibility] = particleEmitterView.get<TransformComponent, ParticleEmitterComponent, VisibilityComponent>(e);
|
||||
|
||||
if (!visibility.Visible)
|
||||
continue;
|
||||
|
||||
auto initialTransform = transform.GetGlobalTransform();
|
||||
for (auto& p : emitterComponent.Emitter.Particles)
|
||||
{
|
||||
Matrix4 particleTransform = initialTransform;
|
||||
particleTransform = glm::inverse(mView);
|
||||
|
||||
// Translation
|
||||
const Vector3& particleGlobalPosition = transform.GetGlobalPosition() + p.Position;
|
||||
particleTransform[3] = Vector4(particleGlobalPosition, 1.0f);
|
||||
|
||||
// Scale
|
||||
particleTransform = glm::scale(particleTransform, transform.GetGlobalScale());
|
||||
|
||||
Renderer::SubmitMesh(Renderer::QuadMesh, particleTransform, (uint32_t)e);
|
||||
}
|
||||
}
|
||||
|
||||
Renderer::Flush(gBufferShader, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/Resource/Serializable.h"
|
||||
#include <src/Core/Maths.h>
|
||||
|
||||
#include "src/Scene/Systems/ParticleEmitter.h"
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
@@ -21,6 +24,8 @@ namespace Nuake
|
||||
// For now use a radius, later should use shape.
|
||||
float Radius;
|
||||
|
||||
ParticleEmitter Emitter;
|
||||
|
||||
public:
|
||||
json Serialize();
|
||||
bool Deserialize(const std::string& str);
|
||||
|
||||
13
Nuake/src/Scene/Systems/Particle.h
Normal file
13
Nuake/src/Scene/Systems/Particle.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "src/Core/Maths.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
struct Particle
|
||||
{
|
||||
Vector3 Position;
|
||||
Vector3 Velocity;
|
||||
Color Color;
|
||||
float Life;
|
||||
};
|
||||
}
|
||||
63
Nuake/src/Scene/Systems/ParticleEmitter.cpp
Normal file
63
Nuake/src/Scene/Systems/ParticleEmitter.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "ParticleEmitter.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
ParticleEmitter::ParticleEmitter()
|
||||
{
|
||||
m_MT = std::mt19937(std::random_device()());
|
||||
m_Random = std::uniform_real_distribution<float>(-Radius, Radius);
|
||||
}
|
||||
|
||||
void ParticleEmitter::SpawnParticle()
|
||||
{
|
||||
const bool canSpawnParticle = Particles.size() < Amount;
|
||||
if (!canSpawnParticle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto initialPosition = Vector3(m_Random(m_MT), m_Random(m_MT), m_Random(m_MT));
|
||||
const auto initialVelocity = Vector3();
|
||||
const auto initialColor = Color(1, 0, 0, 1); // TODO: Use color.
|
||||
const float initialLife = Life;
|
||||
|
||||
Particles.push_back({
|
||||
initialPosition,
|
||||
initialVelocity,
|
||||
initialColor,
|
||||
initialLife
|
||||
});
|
||||
}
|
||||
|
||||
void ParticleEmitter::Update(Timestep ts)
|
||||
{
|
||||
std::vector<uint32_t> deletionQueue;
|
||||
int i = 0;
|
||||
for (auto& p : Particles)
|
||||
{
|
||||
p.Life -= ts;
|
||||
|
||||
if (p.Life <= 0.0f) // The particle has died.
|
||||
{
|
||||
deletionQueue.push_back(i);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
// Delete all dead particles.
|
||||
int shiftOffset = 0;
|
||||
for (int d = deletionQueue.size() - 1; d > 0; d--)
|
||||
{
|
||||
// Erase shifts the elements
|
||||
const auto it = d;
|
||||
Particles.erase(Particles.begin() + it);
|
||||
}
|
||||
|
||||
for (auto& p : Particles)
|
||||
{
|
||||
p.Velocity += Gravity * static_cast<float>(ts);
|
||||
p.Position += p.Velocity * static_cast<float>(ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Nuake/src/Scene/Systems/ParticleEmitter.h
Normal file
34
Nuake/src/Scene/Systems/ParticleEmitter.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "Particle.h"
|
||||
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/Core/Timestep.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class ParticleEmitter
|
||||
{
|
||||
public:
|
||||
float Amount = 0.0f;
|
||||
float Life = 5.0f;
|
||||
Vector3 Gravity = Vector3(0, 0, 0);
|
||||
float GravityRandom = 0.0f;
|
||||
float Radius = 1.0f;
|
||||
|
||||
private:
|
||||
std::mt19937 m_MT;
|
||||
std::uniform_real_distribution<float> m_Random;
|
||||
|
||||
public:
|
||||
ParticleEmitter();
|
||||
~ParticleEmitter() = default;
|
||||
|
||||
void SpawnParticle();
|
||||
void Update(Timestep ts);
|
||||
|
||||
std::vector<Particle> Particles;
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "ParticleSystem.h"
|
||||
|
||||
#include "src/Scene/Scene.h"
|
||||
#include "src/Scene/Components/QuakeMap.h"
|
||||
#include "src/Scene/Entities/Entity.h"
|
||||
#include "src/Scene/Components/ParticleEmitterComponent.h"
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
@@ -17,12 +19,35 @@ namespace Nuake
|
||||
|
||||
void ParticleSystem::Update(Timestep ts)
|
||||
{
|
||||
auto& view = m_Scene->m_Registry.view<TransformComponent, ParticleEmitterComponent>();
|
||||
for (auto& e : view)
|
||||
{
|
||||
auto [transformComponent, emitterComponent] = view.get<TransformComponent, ParticleEmitterComponent>(e);
|
||||
Entity ent = Entity({ e, m_Scene });
|
||||
|
||||
// Copy emitter settings from component to real emitter
|
||||
auto& emitter = emitterComponent.Emitter;
|
||||
emitter.Amount = emitterComponent.Amount;
|
||||
emitter.Gravity = emitterComponent.Gravity;
|
||||
emitter.GravityRandom = emitterComponent.GravityRandom;
|
||||
emitter.Radius = emitterComponent.Radius;
|
||||
emitter.Life = emitterComponent.Life;
|
||||
|
||||
// Spawn particle if possible
|
||||
emitterComponent.Emitter.SpawnParticle();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleSystem::FixedUpdate(Timestep ts)
|
||||
{
|
||||
auto& view = m_Scene->m_Registry.view<TransformComponent, ParticleEmitterComponent>();
|
||||
for (auto& e : view)
|
||||
{
|
||||
auto [transformComponent, emitterComponent] = view.get<TransformComponent, ParticleEmitterComponent>(e);
|
||||
Entity ent = Entity({ e, m_Scene });
|
||||
|
||||
emitterComponent.Emitter.Update(ts);
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleSystem::EditorUpdate()
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
#include <src/Scene/Systems/System.h>
|
||||
#include <src/Core/Maths.h>
|
||||
|
||||
#include <random>
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
@@ -13,7 +17,5 @@ namespace Nuake
|
||||
void EditorUpdate() override;
|
||||
void FixedUpdate(Timestep ts) override;
|
||||
void Exit() override;
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
||||
@@ -56,6 +56,9 @@ namespace Nuake {
|
||||
|
||||
void ScriptingSystem::FixedUpdate(Timestep ts)
|
||||
{
|
||||
if (!Engine::IsPlayMode())
|
||||
return;
|
||||
|
||||
auto entities = m_Scene->m_Registry.view<WrenScriptComponent>();
|
||||
for (auto& e : entities)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user