From 807e9c9a9fdfe2ddf6b4f3becd0477e7e5ef19a3 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Wed, 2 Aug 2023 12:40:12 -0400 Subject: [PATCH 1/8] Added particle emitter component --- .../ComponentsPanel/ParticleEmitterPanel.h | 79 +++++++++++++++++++ Editor/src/Windows/EditorSelectionPanel.cpp | 1 + Editor/src/Windows/EditorSelectionPanel.h | 5 +- Nuake/src/Resource/Serializable.h | 3 + .../Components/ParticleEmitterComponent.cpp | 28 +++++++ .../Components/ParticleEmitterComponent.h | 28 +++++++ Nuake/src/Scene/Entities/Entity.cpp | 5 +- 7 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 Editor/src/ComponentsPanel/ParticleEmitterPanel.h create mode 100644 Nuake/src/Scene/Components/ParticleEmitterComponent.cpp create mode 100644 Nuake/src/Scene/Components/ParticleEmitterComponent.h diff --git a/Editor/src/ComponentsPanel/ParticleEmitterPanel.h b/Editor/src/ComponentsPanel/ParticleEmitterPanel.h new file mode 100644 index 00000000..7ef448a4 --- /dev/null +++ b/Editor/src/ComponentsPanel/ParticleEmitterPanel.h @@ -0,0 +1,79 @@ +#pragma once +#include "ComponentPanel.h" + +#include +#include +#include +#include + +class ParticleEmitterPanel : ComponentPanel +{ +public: + ParticleEmitterPanel() {} + + void Draw(Nuake::Entity entity) override + { + if (!entity.HasComponent()) + return; + + auto& component = entity.GetComponent(); + BeginComponentTable(PARTICLE EMITTER, Nuake::ParticleEmitterComponent); + { + { + ImGui::Text("Particle Color"); + ImGui::TableNextColumn(); + + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); + ImGui::ColorEdit3("##lightcolor", &component.ParticleColor.r, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel); + ImGui::PopItemWidth(); + + ImGui::TableNextColumn(); + ComponentTableReset(component.ParticleColor, Nuake::Vector4(1, 1, 1, 1)); + } + ImGui::TableNextColumn(); + { + ImGui::Text("Amount"); + ImGui::TableNextColumn(); + + ImGui::DragFloat("##ParticleAmount", &component.Amount, 0.1f, 0.0f, 500.0f); + ImGui::TableNextColumn(); + ComponentTableReset(component.Amount, 10.0f); + } + ImGui::TableNextColumn(); + { + ImGui::Text("Life"); + ImGui::TableNextColumn(); + + ImGui::DragFloat("##ParticleLife", &component.Life, 0.1f, 0.0f, 100.0f); + ImGui::TableNextColumn(); + ComponentTableReset(component.Life, 5.0f); + } + ImGui::TableNextColumn(); + { + ImGui::Text("Gravity"); + ImGui::TableNextColumn(); + + ImGuiHelper::DrawVec3("Gravity", &component.Gravity); + ImGui::TableNextColumn(); + ComponentTableReset(component.Gravity, Nuake::Vector3(0, -1, 0)); + } + ImGui::TableNextColumn(); + { + ImGui::Text("Gravity Random"); + ImGui::TableNextColumn(); + ImGui::DragFloat("##GravityRandom", &component.GravityRandom, 0.01f, 0.0f, 1.0f); + ImGui::TableNextColumn(); + ComponentTableReset(component.GravityRandom, 0.0f); + } + ImGui::TableNextColumn(); + { + ImGui::Text("Radius"); + ImGui::TableNextColumn(); + ImGui::DragFloat("##ParticleRadius", &component.Radius, 0.01f, 0.0f, 10.0f); + ImGui::TableNextColumn(); + ComponentTableReset(component.Radius, 1.0f); + } + } + EndComponentTable(); + } +}; \ No newline at end of file diff --git a/Editor/src/Windows/EditorSelectionPanel.cpp b/Editor/src/Windows/EditorSelectionPanel.cpp index a5674899..c524ecd6 100644 --- a/Editor/src/Windows/EditorSelectionPanel.cpp +++ b/Editor/src/Windows/EditorSelectionPanel.cpp @@ -93,6 +93,7 @@ void EditorSelectionPanel::DrawEntity(Nuake::Entity entity) mTransformPanel.Draw(entity); mLightPanel.Draw(entity); mScriptPanel.Draw(entity); + mParticleEmitterPanel.Draw(entity); mSpritePanel.Draw(entity); mMeshPanel.Draw(entity); mQuakeMapPanel.Draw(entity); diff --git a/Editor/src/Windows/EditorSelectionPanel.h b/Editor/src/Windows/EditorSelectionPanel.h index 847406ad..703e59bf 100644 --- a/Editor/src/Windows/EditorSelectionPanel.h +++ b/Editor/src/Windows/EditorSelectionPanel.h @@ -19,9 +19,11 @@ #include "../ComponentsPanel/MeshColliderPanel.h" #include "../ComponentsPanel/CharacterControllerPanel.h" #include "../ComponentsPanel/SpritePanel.h" +#include "../ComponentsPanel/ParticleEmitterPanel.h" -class EditorSelectionPanel { +class EditorSelectionPanel +{ private: TransformPanel mTransformPanel; LightPanel mLightPanel; @@ -37,6 +39,7 @@ private: CylinderColliderPanel mCylinderColliderPanel; SpritePanel mSpritePanel; CharacterControllerPanel mCharacterControllerPanel; + ParticleEmitterPanel mParticleEmitterPanel; Ref currentFile; Ref selectedResource; diff --git a/Nuake/src/Resource/Serializable.h b/Nuake/src/Resource/Serializable.h index ac9f2237..d8ce5d2f 100644 --- a/Nuake/src/Resource/Serializable.h +++ b/Nuake/src/Resource/Serializable.h @@ -19,6 +19,9 @@ using json = nlohmann::json; SERIALIZE_VEC3(v) \ j[#v]["w"] = this->v.w; +#define DESERIALIZE_VEC4(v, p) \ + p = Vector4(v["x"], v["y"], v["z"], v["w"]); + #define DESERIALIZE_VEC3(v, p) \ p = Vector3(v["x"], v["y"], v["z"]); diff --git a/Nuake/src/Scene/Components/ParticleEmitterComponent.cpp b/Nuake/src/Scene/Components/ParticleEmitterComponent.cpp new file mode 100644 index 00000000..3c12015c --- /dev/null +++ b/Nuake/src/Scene/Components/ParticleEmitterComponent.cpp @@ -0,0 +1,28 @@ +#include "src/Scene/Components/ParticleEmitterComponent.h" + +namespace Nuake +{ + json ParticleEmitterComponent::Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_VEC4(ParticleColor); + SERIALIZE_VAL(Amount); + SERIALIZE_VAL(Life); + SERIALIZE_VEC3(Gravity); + SERIALIZE_VAL(GravityRandom); + SERIALIZE_VAL(Radius); + END_SERIALIZE(); + } + + bool ParticleEmitterComponent::Deserialize(const std::string& str) + { + BEGIN_DESERIALIZE(); + DESERIALIZE_VEC4(j["ParticleColor"], ParticleColor); + Amount = j["Amount"]; + Life = j["Life"]; + DESERIALIZE_VEC3(j["Gravity"], Gravity); + GravityRandom = j["GravityRandom"]; + Radius = j["Radius"]; + return true; + } +} \ No newline at end of file diff --git a/Nuake/src/Scene/Components/ParticleEmitterComponent.h b/Nuake/src/Scene/Components/ParticleEmitterComponent.h new file mode 100644 index 00000000..7f46ccd2 --- /dev/null +++ b/Nuake/src/Scene/Components/ParticleEmitterComponent.h @@ -0,0 +1,28 @@ +#pragma once +#include "src/Core/Core.h" +#include "src/Resource/Serializable.h" +#include + +namespace Nuake +{ + class ParticleEmitterComponent + { + public: + ParticleEmitterComponent() = default; + ~ParticleEmitterComponent() = default; + + Color ParticleColor; + float Amount; + float Life; + + Vector3 Gravity; + float GravityRandom; + + // For now use a radius, later should use shape. + float Radius; + + public: + json Serialize(); + bool Deserialize(const std::string& str); + }; +} \ No newline at end of file diff --git a/Nuake/src/Scene/Entities/Entity.cpp b/Nuake/src/Scene/Entities/Entity.cpp index 87dbca05..706616d0 100644 --- a/Nuake/src/Scene/Entities/Entity.cpp +++ b/Nuake/src/Scene/Entities/Entity.cpp @@ -15,7 +15,7 @@ #include "src/Scene/Components/BoxCollider.h" #include "src/Scene/Components/CapsuleColliderComponent.h" #include "src/Scene/Components/SpriteComponent.h" - +#include "src/Scene/Components/ParticleEmitterComponent.h" namespace Nuake { @@ -39,6 +39,8 @@ namespace Nuake SERIALIZE_OBJECT_REF_LBL("VisibilityComponent", GetComponent()) if (HasComponent()) SERIALIZE_OBJECT_REF_LBL("CameraComponent", GetComponent()) + if (HasComponent()) + SERIALIZE_OBJECT_REF_LBL("ParticleEmitterComponent", GetComponent()) if (HasComponent()) SERIALIZE_OBJECT_REF_LBL("SpriteComponent", GetComponent()) if (HasComponent()) @@ -82,6 +84,7 @@ namespace Nuake } DESERIALIZE_COMPONENT(NameComponent) DESERIALIZE_COMPONENT(ParentComponent) + DESERIALIZE_COMPONENT(ParticleEmitterComponent) DESERIALIZE_COMPONENT(SpriteComponent) DESERIALIZE_COMPONENT(CameraComponent) DESERIALIZE_COMPONENT(QuakeMapComponent) From 6d992d647510799ae6fbb71c0fd2efca1ac69331 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Wed, 2 Aug 2023 12:44:15 -0400 Subject: [PATCH 2/8] Added particle emitter to add component menu --- Editor/src/Windows/EditorSelectionPanel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Editor/src/Windows/EditorSelectionPanel.cpp b/Editor/src/Windows/EditorSelectionPanel.cpp index c524ecd6..beea8016 100644 --- a/Editor/src/Windows/EditorSelectionPanel.cpp +++ b/Editor/src/Windows/EditorSelectionPanel.cpp @@ -11,6 +11,7 @@ #include #include "src/Scene/Components/WrenScriptComponent.h" +#include "src/Scene/Components/ParticleEmitterComponent.h" EditorSelectionPanel::EditorSelectionPanel() { @@ -125,6 +126,7 @@ void EditorSelectionPanel::DrawAddComponentMenu(Nuake::Entity entity) MenuItemComponent("Light", Nuake::LightComponent) MenuItemComponent("Model", Nuake::ModelComponent) MenuItemComponent("Sprite", Nuake::SpriteComponent) + MenuItemComponent("Particle Emitter", Nuake::ParticleEmitterComponent) ImGui::Separator(); MenuItemComponent("Character Controller", Nuake::CharacterControllerComponent) MenuItemComponent("Rigid body", Nuake::RigidBodyComponent) From 7af3a79b0e62e82b9ace2cdaee3d4b83dfcfb195 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Wed, 2 Aug 2023 12:56:50 -0400 Subject: [PATCH 3/8] Added particle system --- Nuake/src/Scene/Scene.cpp | 2 ++ Nuake/src/Scene/Systems/ParticleSystem.cpp | 37 ++++++++++++++++++++++ Nuake/src/Scene/Systems/ParticleSystem.h | 19 +++++++++++ 3 files changed, 58 insertions(+) create mode 100644 Nuake/src/Scene/Systems/ParticleSystem.cpp create mode 100644 Nuake/src/Scene/Systems/ParticleSystem.h diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 9a93ba75..b740622e 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -3,6 +3,7 @@ #include "src/Scene/Systems/PhysicsSystem.h" #include "src/Scene/Systems/TransformSystem.h" #include "src/Scene/Systems/QuakeMapBuilder.h" +#include "src/Scene/Systems/ParticleSystem.h" #include "src/Rendering/SceneRenderer.h" #include "Scene.h" @@ -45,6 +46,7 @@ namespace Nuake { m_Systems.push_back(CreateRef(this)); m_Systems.push_back(CreateRef(this)); m_Systems.push_back(CreateRef(this)); + m_Systems.push_back(CreateRef(this)); m_SceneRenderer = new SceneRenderer(); m_SceneRenderer->Init(); diff --git a/Nuake/src/Scene/Systems/ParticleSystem.cpp b/Nuake/src/Scene/Systems/ParticleSystem.cpp new file mode 100644 index 00000000..52ca6eff --- /dev/null +++ b/Nuake/src/Scene/Systems/ParticleSystem.cpp @@ -0,0 +1,37 @@ +#include "ParticleSystem.h" + +#include "src/Scene/Scene.h" +#include "src/Scene/Components/QuakeMap.h" + +namespace Nuake +{ + ParticleSystem::ParticleSystem(Scene* scene) + { + m_Scene = scene; + } + + bool ParticleSystem::Init() + { + return true; + } + + void ParticleSystem::Update(Timestep ts) + { + + } + + void ParticleSystem::FixedUpdate(Timestep ts) + { + + } + + void ParticleSystem::EditorUpdate() + { + + } + + void ParticleSystem::Exit() + { + + } +} diff --git a/Nuake/src/Scene/Systems/ParticleSystem.h b/Nuake/src/Scene/Systems/ParticleSystem.h new file mode 100644 index 00000000..6d44f96e --- /dev/null +++ b/Nuake/src/Scene/Systems/ParticleSystem.h @@ -0,0 +1,19 @@ +#pragma once +#include + +namespace Nuake +{ + class ParticleSystem : public System + { + public: + ParticleSystem(Scene* scene); + bool Init() override; + void Update(Timestep ts) override; + void Draw() override {} + void EditorUpdate() override; + void FixedUpdate(Timestep ts) override; + void Exit() override; + + private: + }; +} From eecfd3c375109437733158aefb017ca1e880b020 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Wed, 2 Aug 2023 14:17:33 -0400 Subject: [PATCH 4/8] Added very basic particle system and rendering --- Nuake/Engine.cpp | 24 ++++--- Nuake/src/Rendering/SceneRenderer.cpp | 33 +++++++++- .../Components/ParticleEmitterComponent.h | 7 ++- Nuake/src/Scene/Systems/Particle.h | 13 ++++ Nuake/src/Scene/Systems/ParticleEmitter.cpp | 63 +++++++++++++++++++ Nuake/src/Scene/Systems/ParticleEmitter.h | 34 ++++++++++ Nuake/src/Scene/Systems/ParticleSystem.cpp | 27 +++++++- Nuake/src/Scene/Systems/ParticleSystem.h | 6 +- Nuake/src/Scene/Systems/ScriptingSystem.cpp | 3 + 9 files changed, 192 insertions(+), 18 deletions(-) create mode 100644 Nuake/src/Scene/Systems/Particle.h create mode 100644 Nuake/src/Scene/Systems/ParticleEmitter.cpp create mode 100644 Nuake/src/Scene/Systems/ParticleEmitter.h diff --git a/Nuake/Engine.cpp b/Nuake/Engine.cpp index cea54337..e212817b 100644 --- a/Nuake/Engine.cpp +++ b/Nuake/Engine.cpp @@ -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(); diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index db19889a..bafbe7cc 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -3,9 +3,11 @@ #include "src/Scene/Components/BSPBrushComponent.h" #include "src/Scene/Components/SpriteComponent.h" +#include "src/Scene/Components/ParticleEmitterComponent.h" #include + 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(); - for (auto e : spriteView) + for (auto& e : spriteView) { auto [transform, sprite, visibility] = spriteView.get(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(); + for (auto& e : particleEmitterView) + { + auto [transform, emitterComponent, visibility] = particleEmitterView.get(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); } } diff --git a/Nuake/src/Scene/Components/ParticleEmitterComponent.h b/Nuake/src/Scene/Components/ParticleEmitterComponent.h index 7f46ccd2..f7fc44a6 100644 --- a/Nuake/src/Scene/Components/ParticleEmitterComponent.h +++ b/Nuake/src/Scene/Components/ParticleEmitterComponent.h @@ -1,7 +1,10 @@ #pragma once #include "src/Core/Core.h" +#include "src/Core/Maths.h" #include "src/Resource/Serializable.h" -#include + +#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); diff --git a/Nuake/src/Scene/Systems/Particle.h b/Nuake/src/Scene/Systems/Particle.h new file mode 100644 index 00000000..59f93989 --- /dev/null +++ b/Nuake/src/Scene/Systems/Particle.h @@ -0,0 +1,13 @@ +#pragma once +#include "src/Core/Maths.h" + +namespace Nuake +{ + struct Particle + { + Vector3 Position; + Vector3 Velocity; + Color Color; + float Life; + }; +} diff --git a/Nuake/src/Scene/Systems/ParticleEmitter.cpp b/Nuake/src/Scene/Systems/ParticleEmitter.cpp new file mode 100644 index 00000000..5cf21798 --- /dev/null +++ b/Nuake/src/Scene/Systems/ParticleEmitter.cpp @@ -0,0 +1,63 @@ +#include "ParticleEmitter.h" + +namespace Nuake +{ + ParticleEmitter::ParticleEmitter() + { + m_MT = std::mt19937(std::random_device()()); + m_Random = std::uniform_real_distribution(-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 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(ts); + p.Position += p.Velocity * static_cast(ts); + } + } +} \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/ParticleEmitter.h b/Nuake/src/Scene/Systems/ParticleEmitter.h new file mode 100644 index 00000000..9aa3e0dc --- /dev/null +++ b/Nuake/src/Scene/Systems/ParticleEmitter.h @@ -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 + +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 m_Random; + + public: + ParticleEmitter(); + ~ParticleEmitter() = default; + + void SpawnParticle(); + void Update(Timestep ts); + + std::vector Particles; + }; +} \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/ParticleSystem.cpp b/Nuake/src/Scene/Systems/ParticleSystem.cpp index 52ca6eff..a730f7a6 100644 --- a/Nuake/src/Scene/Systems/ParticleSystem.cpp +++ b/Nuake/src/Scene/Systems/ParticleSystem.cpp @@ -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(); + for (auto& e : view) + { + auto [transformComponent, emitterComponent] = view.get(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(); + for (auto& e : view) + { + auto [transformComponent, emitterComponent] = view.get(e); + Entity ent = Entity({ e, m_Scene }); + emitterComponent.Emitter.Update(ts); + } } void ParticleSystem::EditorUpdate() diff --git a/Nuake/src/Scene/Systems/ParticleSystem.h b/Nuake/src/Scene/Systems/ParticleSystem.h index 6d44f96e..11678299 100644 --- a/Nuake/src/Scene/Systems/ParticleSystem.h +++ b/Nuake/src/Scene/Systems/ParticleSystem.h @@ -1,5 +1,9 @@ #pragma once #include +#include + +#include + namespace Nuake { @@ -13,7 +17,5 @@ namespace Nuake void EditorUpdate() override; void FixedUpdate(Timestep ts) override; void Exit() override; - - private: }; } diff --git a/Nuake/src/Scene/Systems/ScriptingSystem.cpp b/Nuake/src/Scene/Systems/ScriptingSystem.cpp index c41f1bff..4b9d3578 100644 --- a/Nuake/src/Scene/Systems/ScriptingSystem.cpp +++ b/Nuake/src/Scene/Systems/ScriptingSystem.cpp @@ -56,6 +56,9 @@ namespace Nuake { void ScriptingSystem::FixedUpdate(Timestep ts) { + if (!Engine::IsPlayMode()) + return; + auto entities = m_Scene->m_Registry.view(); for (auto& e : entities) { From 1a8f4bd1aadc33b1986b344b1b3209c6cf54441c Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Wed, 2 Aug 2023 15:34:04 -0400 Subject: [PATCH 5/8] Added simple radius gizmo --- .../ComponentsPanel/ParticleEmitterPanel.h | 9 ++++ Editor/src/Misc/GizmoDrawer.cpp | 13 ++++++ .../Components/ParticleEmitterComponent.cpp | 5 ++ .../Components/ParticleEmitterComponent.h | 3 +- Nuake/src/Scene/Scene.cpp | 8 ++-- Nuake/src/Scene/Systems/ParticleEmitter.cpp | 46 ++++++++++++++----- Nuake/src/Scene/Systems/ParticleEmitter.h | 6 +++ Nuake/src/Scene/Systems/ParticleSystem.cpp | 4 +- 8 files changed, 77 insertions(+), 17 deletions(-) diff --git a/Editor/src/ComponentsPanel/ParticleEmitterPanel.h b/Editor/src/ComponentsPanel/ParticleEmitterPanel.h index 7ef448a4..04900ec9 100644 --- a/Editor/src/ComponentsPanel/ParticleEmitterPanel.h +++ b/Editor/src/ComponentsPanel/ParticleEmitterPanel.h @@ -40,6 +40,15 @@ public: ComponentTableReset(component.Amount, 10.0f); } ImGui::TableNextColumn(); + { + ImGui::Text("Rate"); + ImGui::TableNextColumn(); + + ImGui::DragFloat("##ParticleRate", &component.Rate, 0.1f, 0.0f, 10.0f); + ImGui::TableNextColumn(); + ComponentTableReset(component.Rate, 0.0f); + } + ImGui::TableNextColumn(); { ImGui::Text("Life"); ImGui::TableNextColumn(); diff --git a/Editor/src/Misc/GizmoDrawer.cpp b/Editor/src/Misc/GizmoDrawer.cpp index 51edc163..34747958 100644 --- a/Editor/src/Misc/GizmoDrawer.cpp +++ b/Editor/src/Misc/GizmoDrawer.cpp @@ -16,6 +16,7 @@ #include #include #include +#include GizmoDrawer::GizmoDrawer() @@ -217,6 +218,18 @@ void GizmoDrawer::DrawGizmos(Ref scene) Nuake::RenderCommand::DrawLines(0, 264); } + auto particleView = scene->m_Registry.view(); + for (auto e : particleView) + { + auto [transform, particle] = scene->m_Registry.get(e); + mLineShader->Bind(); + mLineShader->SetUniformMat4f("u_View", glm::scale(glm::translate(scene->m_EditorCamera->GetTransform(), transform.Translation), Vector3(particle.Radius))); + mLineShader->SetUniformMat4f("u_Projection", scene->m_EditorCamera->GetPerspective()); + + mCircleBuffer->Bind(); + Nuake::RenderCommand::DrawLines(0, 128); + } + auto meshColliderView = scene->m_Registry.view(); for (auto e : meshColliderView) { diff --git a/Nuake/src/Scene/Components/ParticleEmitterComponent.cpp b/Nuake/src/Scene/Components/ParticleEmitterComponent.cpp index 3c12015c..31cec4af 100644 --- a/Nuake/src/Scene/Components/ParticleEmitterComponent.cpp +++ b/Nuake/src/Scene/Components/ParticleEmitterComponent.cpp @@ -8,6 +8,7 @@ namespace Nuake SERIALIZE_VEC4(ParticleColor); SERIALIZE_VAL(Amount); SERIALIZE_VAL(Life); + SERIALIZE_VAL(Rate); SERIALIZE_VEC3(Gravity); SERIALIZE_VAL(GravityRandom); SERIALIZE_VAL(Radius); @@ -20,6 +21,10 @@ namespace Nuake DESERIALIZE_VEC4(j["ParticleColor"], ParticleColor); Amount = j["Amount"]; Life = j["Life"]; + if (j.contains("Rate")) + { + Rate = j["Rate"]; + } DESERIALIZE_VEC3(j["Gravity"], Gravity); GravityRandom = j["GravityRandom"]; Radius = j["Radius"]; diff --git a/Nuake/src/Scene/Components/ParticleEmitterComponent.h b/Nuake/src/Scene/Components/ParticleEmitterComponent.h index f7fc44a6..f4081ffa 100644 --- a/Nuake/src/Scene/Components/ParticleEmitterComponent.h +++ b/Nuake/src/Scene/Components/ParticleEmitterComponent.h @@ -16,7 +16,8 @@ namespace Nuake Color ParticleColor; float Amount; - float Life; + float Life = 1.0f; + float Rate = 0.0f; Vector3 Gravity; float GravityRandom; diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index b740622e..79e022b8 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -77,10 +77,10 @@ namespace Nuake { Entity Scene::GetEntityByID(int id) { - if (m_EntitiesIDMap.find(id) != m_EntitiesIDMap.end()) - { - return m_EntitiesIDMap[id]; - } + //if (m_EntitiesIDMap.find(id) != m_EntitiesIDMap.end()) + //{ + // return m_EntitiesIDMap[id]; + //} auto idView = m_Registry.view(); for (auto e : idView) diff --git a/Nuake/src/Scene/Systems/ParticleEmitter.cpp b/Nuake/src/Scene/Systems/ParticleEmitter.cpp index 5cf21798..2fb47244 100644 --- a/Nuake/src/Scene/Systems/ParticleEmitter.cpp +++ b/Nuake/src/Scene/Systems/ParticleEmitter.cpp @@ -5,7 +5,12 @@ namespace Nuake ParticleEmitter::ParticleEmitter() { m_MT = std::mt19937(std::random_device()()); - m_Random = std::uniform_real_distribution(-Radius, Radius); + SetRadius(1.0f); + } + + void ParticleEmitter::RecreateRandom() + { + } void ParticleEmitter::SpawnParticle() @@ -16,21 +21,31 @@ namespace Nuake 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; + if (Rate == 0.0f || RateTimer > Rate) + { + const auto initialPosition = Vector3(m_Random(m_MT), m_Random(m_MT), m_Random(m_MT)); + const auto initialVelocity = Vector3(); + const auto initialColor = ParticleColor; + const float initialLife = Life; - Particles.push_back({ - initialPosition, - initialVelocity, - initialColor, - initialLife - }); + Particles.push_back({ + initialPosition, + initialVelocity, + initialColor, + initialLife + }); + + RateTimer = 0.0f; + } } void ParticleEmitter::Update(Timestep ts) { + if (Rate != 0.0f) + { + RateTimer += ts; + } + std::vector deletionQueue; int i = 0; for (auto& p : Particles) @@ -60,4 +75,13 @@ namespace Nuake p.Position += p.Velocity * static_cast(ts); } } + + void ParticleEmitter::SetRadius(float radius) + { + if (Radius != radius) + { + Radius = radius; + m_Random = std::uniform_real_distribution(-Radius, Radius); + } + } } \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/ParticleEmitter.h b/Nuake/src/Scene/Systems/ParticleEmitter.h index 9aa3e0dc..9ed356bf 100644 --- a/Nuake/src/Scene/Systems/ParticleEmitter.h +++ b/Nuake/src/Scene/Systems/ParticleEmitter.h @@ -17,11 +17,16 @@ namespace Nuake Vector3 Gravity = Vector3(0, 0, 0); float GravityRandom = 0.0f; float Radius = 1.0f; + float Rate = 0.0f; + Color ParticleColor; private: + float RateTimer = 0.0f; std::mt19937 m_MT; std::uniform_real_distribution m_Random; + void RecreateRandom(); + public: ParticleEmitter(); ~ParticleEmitter() = default; @@ -29,6 +34,7 @@ namespace Nuake void SpawnParticle(); void Update(Timestep ts); + void SetRadius(float radius); std::vector Particles; }; } \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/ParticleSystem.cpp b/Nuake/src/Scene/Systems/ParticleSystem.cpp index a730f7a6..aa8d0ac0 100644 --- a/Nuake/src/Scene/Systems/ParticleSystem.cpp +++ b/Nuake/src/Scene/Systems/ParticleSystem.cpp @@ -28,10 +28,12 @@ namespace Nuake // Copy emitter settings from component to real emitter auto& emitter = emitterComponent.Emitter; emitter.Amount = emitterComponent.Amount; + emitter.ParticleColor = emitterComponent.ParticleColor; emitter.Gravity = emitterComponent.Gravity; emitter.GravityRandom = emitterComponent.GravityRandom; - emitter.Radius = emitterComponent.Radius; + emitter.SetRadius(emitterComponent.Radius); emitter.Life = emitterComponent.Life; + emitter.Rate = emitterComponent.Rate; // Spawn particle if possible emitterComponent.Emitter.SpawnParticle(); From 30171518a0c824fd2c633d9558a405a0797ce45b Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Wed, 2 Aug 2023 15:34:26 -0400 Subject: [PATCH 6/8] Fixed default material with invalid texture --- Nuake/src/Rendering/Renderer.cpp | 9 ++++++--- Nuake/src/Rendering/SceneRenderer.cpp | 8 ++++++-- Nuake/src/Rendering/Textures/Material.cpp | 4 +--- Nuake/src/Rendering/Textures/MaterialManager.h | 3 +-- Nuake/src/Scene/Systems/ParticleEmitter.h | 2 ++ 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Nuake/src/Rendering/Renderer.cpp b/Nuake/src/Rendering/Renderer.cpp index 92c61628..686ecb5f 100644 --- a/Nuake/src/Rendering/Renderer.cpp +++ b/Nuake/src/Rendering/Renderer.cpp @@ -82,14 +82,17 @@ namespace Nuake m_LightsUniformBuffer = CreateRef(128); - Ref material = MaterialManager::Get()->GetMaterial("default"); + Ref defaultMaterial = CreateRef(Vector3{1, 1, 1}); + defaultMaterial->SetName("white"); + MaterialManager::Get()->RegisterMaterial(defaultMaterial); + CubeMesh = CreateRef(); CubeMesh->AddSurface(CubeVertices, CubeIndices); - CubeMesh->SetMaterial(material); + CubeMesh->SetMaterial(defaultMaterial); QuadMesh = CreateRef(); QuadMesh->AddSurface(QuadVertices, { 0, 1, 2, 3, 4, 5 }); - QuadMesh->SetMaterial(material); + QuadMesh->SetMaterial(defaultMaterial); } void Renderer::LoadShaders() diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index bafbe7cc..c7575baf 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -329,6 +329,7 @@ namespace Nuake if (!visibility.Visible) continue; + Vector3 oldColor = Renderer::QuadMesh->GetMaterial()->data.m_AlbedoColor; auto initialTransform = transform.GetGlobalTransform(); for (auto& p : emitterComponent.Emitter.Particles) { @@ -342,11 +343,14 @@ namespace Nuake // Scale particleTransform = glm::scale(particleTransform, transform.GetGlobalScale()); + Renderer::QuadMesh->GetMaterial()->data.u_HasAlbedo = 0; + Renderer::QuadMesh->GetMaterial()->data.m_AlbedoColor = p.Color; Renderer::SubmitMesh(Renderer::QuadMesh, particleTransform, (uint32_t)e); } - } - Renderer::Flush(gBufferShader, false); + Renderer::Flush(gBufferShader, false); + Renderer::QuadMesh->GetMaterial()->data.m_AlbedoColor = oldColor; + } } } diff --git a/Nuake/src/Rendering/Textures/Material.cpp b/Nuake/src/Rendering/Textures/Material.cpp index 65c14827..66e3f032 100644 --- a/Nuake/src/Rendering/Textures/Material.cpp +++ b/Nuake/src/Rendering/Textures/Material.cpp @@ -68,9 +68,7 @@ namespace Nuake data.m_AlbedoColor = Vector3{ albedoColor.r, albedoColor.g, albedoColor.b }; - m_Name = "New material"; - - m_Albedo = m_DefaultAlbedo; + m_Name = "default"; } Material::~Material() {} diff --git a/Nuake/src/Rendering/Textures/MaterialManager.h b/Nuake/src/Rendering/Textures/MaterialManager.h index 1495512d..c77faf86 100644 --- a/Nuake/src/Rendering/Textures/MaterialManager.h +++ b/Nuake/src/Rendering/Textures/MaterialManager.h @@ -11,8 +11,6 @@ namespace Nuake class MaterialManager { private: - const std::string DEFAULT_MATERIAL = "resources/Textures/default/Default.png"; - static Ref s_Instance; std::map> m_Materials; @@ -24,6 +22,7 @@ namespace Nuake public: + const std::string DEFAULT_MATERIAL = "resources/Textures/default/Default.png"; std::string CurrentlyBoundedMaterial = ""; MaterialManager(); diff --git a/Nuake/src/Scene/Systems/ParticleEmitter.h b/Nuake/src/Scene/Systems/ParticleEmitter.h index 9ed356bf..f7d8609a 100644 --- a/Nuake/src/Scene/Systems/ParticleEmitter.h +++ b/Nuake/src/Scene/Systems/ParticleEmitter.h @@ -5,6 +5,8 @@ #include "src/Core/Maths.h" #include "src/Core/Timestep.h" +#include "src/Rendering/Textures/Material.h" + #include namespace Nuake From 9d5c737cd6b8e772a5856dbe7e20ab4a3394f649 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Wed, 2 Aug 2023 15:34:35 -0400 Subject: [PATCH 7/8] Fixed entity cache not clearing --- Nuake/src/Scene/Scene.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 79e022b8..72a423fe 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -77,10 +77,10 @@ namespace Nuake { Entity Scene::GetEntityByID(int id) { - //if (m_EntitiesIDMap.find(id) != m_EntitiesIDMap.end()) - //{ - // return m_EntitiesIDMap[id]; - //} + if (m_EntitiesIDMap.find(id) != m_EntitiesIDMap.end()) + { + return m_EntitiesIDMap[id]; + } auto idView = m_Registry.view(); for (auto e : idView) @@ -273,11 +273,15 @@ namespace Nuake { for (auto& c : copyChildrens) { - Logger::Log("Deleting entity " + std::to_string(c.GetHandle())); DestroyEntity(c); } - Logger::Log("Deleted entity" + std::to_string(entity.GetHandle()) + " - " + entity.GetComponent().Name); + // Remove from ID to Entity cache + if (m_EntitiesIDMap.find(entity.GetComponent().ID) != m_EntitiesIDMap.end()) + { + m_EntitiesIDMap.erase(entity.GetComponent().ID); + } + entity.Destroy(); m_Registry.shrink_to_fit(); } From 87bac4d7010fdb278fcd8f28591529ea17706eee Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Wed, 2 Aug 2023 15:34:45 -0400 Subject: [PATCH 8/8] Code formatting --- Editor/src/Windows/EditorSelectionPanel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Editor/src/Windows/EditorSelectionPanel.cpp b/Editor/src/Windows/EditorSelectionPanel.cpp index beea8016..729fea74 100644 --- a/Editor/src/Windows/EditorSelectionPanel.cpp +++ b/Editor/src/Windows/EditorSelectionPanel.cpp @@ -13,6 +13,7 @@ #include "src/Scene/Components/WrenScriptComponent.h" #include "src/Scene/Components/ParticleEmitterComponent.h" + EditorSelectionPanel::EditorSelectionPanel() { }