From 62f539d1273525537f9eca9eb1a577b705c51c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Mar=C3=ADn?= <36265613+X0KA@users.noreply.github.com> Date: Thu, 28 May 2020 01:25:03 +0200 Subject: [PATCH 1/8] Play on awake button added --- .../Source/ComponentParticleEmitter.cpp | 20 ++++++++++++++++--- .../Source/ComponentParticleEmitter.h | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Broken Engine/Source/ComponentParticleEmitter.cpp b/Broken Engine/Source/ComponentParticleEmitter.cpp index 7efc68915..c68583d75 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.cpp +++ b/Broken Engine/Source/ComponentParticleEmitter.cpp @@ -165,10 +165,9 @@ void ComponentParticleEmitter::Disable() void ComponentParticleEmitter::UpdateParticles(float dt) { - int currentPlayTime = App->time->GetGameplayTimePassed() * 1000; - // Create particle depending on the time + //Create particle depending on the time if (emisionActive && App->GetAppState() == AppState::PLAY && !App->time->gamePaused) { if ((currentPlayTime - spawnClock > emisionRate )||playNow) { @@ -415,6 +414,8 @@ json ComponentParticleEmitter::Save() const { json node; + node["PlayOnAwake"] = playOnAwake; + node["Active"] = this->active; node["positionX"] = std::to_string(emitterPosition.x); @@ -564,7 +565,7 @@ void ComponentParticleEmitter::Load(json& node) scaleCurve = nullptr; rotateCurve = nullptr; - this->active = node["Active"].is_null() ? true : (bool)node["Active"]; + this->active = node["Active"].is_null() ? false : (bool)node["Active"]; //load the strings std::string LpositionX = node["positionX"].is_null() ? "0" : node["positionX"]; @@ -606,6 +607,9 @@ void ComponentParticleEmitter::Load(json& node) followEmitter = node["followEmitter"].is_null() ? true : node["followEmitter"].get(); + playOnAwake = node["PlayOnAwake"].is_null() ? true : node["PlayOnAwake"].get(); + emisionActive = playOnAwake; + std::string LParticlesSize = node["particlesSize"].is_null() ? "0" : node["particlesSize"]; std::string _animation = node["animation"].is_null() ? "0" : node["animation"]; @@ -853,6 +857,14 @@ void ComponentParticleEmitter::Load(json& node) void ComponentParticleEmitter::CreateInspectorNode() { + //Play on awake + ImGui::NewLine(); + ImGui::Checkbox("##PlayOnAwake", &playOnAwake); + if (App->GetAppState() != AppState::PLAY) + emisionActive = playOnAwake; + ImGui::SameLine(); + ImGui::Text("Play on awake"); + // --- Loop --- ImGui::NewLine(); if (ImGui::Checkbox("##PELoop", &loop)) @@ -868,6 +880,8 @@ void ComponentParticleEmitter::CreateInspectorNode() ImGui::SameLine(); ImGui::DragInt("##PEDuration", &duration); + + //Emitter position ImGui::Text("Position"); diff --git a/Broken Engine/Source/ComponentParticleEmitter.h b/Broken Engine/Source/ComponentParticleEmitter.h index 1a5a814d4..da6637e39 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.h +++ b/Broken Engine/Source/ComponentParticleEmitter.h @@ -112,6 +112,7 @@ class BROKEN_API ComponentParticleEmitter : public Component physx::PxVec3 velocityRandomFactor2 = { 0,0,0 }; bool loop = true; bool emisionActive = true; + bool playOnAwake = false; int duration = 1000; uint emisionStart = 0; From f5054be26081015637a75e999ff89ddd18b7e939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Mar=C3=ADn?= <36265613+X0KA@users.noreply.github.com> Date: Thu, 28 May 2020 02:25:02 +0200 Subject: [PATCH 2/8] Sprite ordering error solved A hotfix in development was implemented in order to avoid a crash, but it caused particle ordering to work wrong again. Now it should all be solved, both the ordering and the crash --- .../Source/ComponentParticleEmitter.cpp | 7 ++++--- .../Source/ComponentParticleEmitter.h | 2 +- Broken Engine/Source/ModuleParticles.cpp | 18 +++++++++--------- Broken Engine/Source/ModuleParticles.h | 2 +- Broken Engine/Source/Particle.h | 2 ++ 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Broken Engine/Source/ComponentParticleEmitter.cpp b/Broken Engine/Source/ComponentParticleEmitter.cpp index a157556c0..1bd514679 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.cpp +++ b/Broken Engine/Source/ComponentParticleEmitter.cpp @@ -73,7 +73,7 @@ ComponentParticleEmitter::~ComponentParticleEmitter() for (int i = 0; i < maxParticles; ++i) { - App->particles->particlesToDraw.erase(particles[i]); + App->particles->particlesToDraw.erase(particles[i]->distanceToCam); delete particles[i]; particles[i] = nullptr; } @@ -314,8 +314,9 @@ void ComponentParticleEmitter::SortParticles() float distance = App->renderer3D->active_camera->frustum.NearPlane().Distance(particles[i]->position); - drawingIndices[1.0f / distance] = i; - App->particles->particlesToDraw[particles[i]] = 1.0f / distance; + //drawingIndices[1.0f / distance] = i; + particles[i]->distanceToCam = 1.0f / distance; + App->particles->particlesToDraw[1.0f / distance] = particles[i]; } } diff --git a/Broken Engine/Source/ComponentParticleEmitter.h b/Broken Engine/Source/ComponentParticleEmitter.h index da6637e39..64969b9a6 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.h +++ b/Broken Engine/Source/ComponentParticleEmitter.h @@ -104,7 +104,7 @@ class BROKEN_API ComponentParticleEmitter : public Component float3 eulerRotation = float3::zero; Quat emitterRotation = Quat::identity; int particlesPerCreation = 1; - physx::PxVec3 size = { 0,0,0 }; + physx::PxVec3 size = { 0.01,0.01,0.01 }; float emisionRate = 500.0f; //in milliseconds physx::PxVec3 externalAcceleration = { 0,10,0 }; physx::PxVec3 particlesVelocity = { 0,0,0 }; diff --git a/Broken Engine/Source/ModuleParticles.cpp b/Broken Engine/Source/ModuleParticles.cpp index fe358e916..28f446f1d 100644 --- a/Broken Engine/Source/ModuleParticles.cpp +++ b/Broken Engine/Source/ModuleParticles.cpp @@ -75,18 +75,18 @@ void ModuleParticles::DrawParticles(bool shadowsPass) Plane cameraPlanes[6]; App->renderer3D->culling_camera->frustum.GetPlanes(cameraPlanes); - std::map::iterator it = particlesToDraw.begin(); + std::map::iterator it = particlesToDraw.begin(); while (it != particlesToDraw.end()) { - if ((*it).first->emitter != nullptr) + if ((*it).second->emitter != nullptr) { //Check if the particles are inside the frustum of the camera bool draw = true; for (int i = 0; i < 6; ++i) { //If the particles is on the positive side of one ore more planes, it's outside the frustum - bool shadowsHandle = ((shadowsPass && (*it).first->emitter->m_CastShadows == false) || (!shadowsPass && (*it).first->emitter->m_OnlyShadows)); - if (cameraPlanes[i].IsOnPositiveSide((*it).first->position) || shadowsHandle) + bool shadowsHandle = ((shadowsPass && (*it).second->emitter->m_CastShadows == false) || (!shadowsPass && (*it).second->emitter->m_OnlyShadows)); + if (cameraPlanes[i].IsOnPositiveSide((*it).second->position) || shadowsHandle) { draw = false; break; @@ -95,19 +95,19 @@ void ModuleParticles::DrawParticles(bool shadowsPass) if (draw) { - if (!shadowsPass && (*it).first->emitter) + if (!shadowsPass && (*it).second->emitter) { - (*it).first->emitter->SetEmitterBlending(); - if ((*it).first->emitter->particlesFaceCulling) + (*it).second->emitter->SetEmitterBlending(); + if ((*it).second->emitter->particlesFaceCulling) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); } - (*it).first->Draw(shadowsPass); + (*it).second->Draw(shadowsPass); if (!shadowsPass) - if ((*it).first->emitter->particlesFaceCulling == false) + if ((*it).second->emitter->particlesFaceCulling == false) glEnable(GL_CULL_FACE); } } diff --git a/Broken Engine/Source/ModuleParticles.h b/Broken Engine/Source/ModuleParticles.h index 8f6993fc9..c268851be 100644 --- a/Broken Engine/Source/ModuleParticles.h +++ b/Broken Engine/Source/ModuleParticles.h @@ -29,7 +29,7 @@ class BROKEN_API ModuleParticles : public Module public: - std::map particlesToDraw; + std::map particlesToDraw; std::vector particleEmitters; }; diff --git a/Broken Engine/Source/Particle.h b/Broken Engine/Source/Particle.h index a5a645a39..dc4e2952d 100644 --- a/Broken Engine/Source/Particle.h +++ b/Broken Engine/Source/Particle.h @@ -33,6 +33,8 @@ class BROKEN_API Particle { float3 rotationSpeed = { 0,0,0 }; float3 scaleSpeed = { 0,0,0 }; float3 emitterSpawnPosition = { 0,0,0 }; + float distanceToCam = 0.0f; + int startFrame = 0; bool h_billboard = false; From de95109eb48fbcf02c30d190a78946d551dae983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Mar=C3=ADn?= <36265613+X0KA@users.noreply.github.com> Date: Thu, 28 May 2020 03:35:22 +0200 Subject: [PATCH 3/8] Update ComponentParticleEmitter.cpp --- .../Source/ComponentParticleEmitter.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Broken Engine/Source/ComponentParticleEmitter.cpp b/Broken Engine/Source/ComponentParticleEmitter.cpp index 1bd514679..52a70b41b 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.cpp +++ b/Broken Engine/Source/ComponentParticleEmitter.cpp @@ -312,11 +312,21 @@ void ComponentParticleEmitter::SortParticles() if (*flagsIt & physx::PxParticleFlag::eVALID) { - float distance = App->renderer3D->active_camera->frustum.NearPlane().Distance(particles[i]->position); + float distance = 1.0f/App->renderer3D->active_camera->frustum.NearPlane().Distance(particles[i]->position); //drawingIndices[1.0f / distance] = i; - particles[i]->distanceToCam = 1.0f / distance; - App->particles->particlesToDraw[1.0f / distance] = particles[i]; + + bool particleSent = false; + while (!particleSent) { + if (App->particles->particlesToDraw.find(distance) == App->particles->particlesToDraw.end()) { + App->particles->particlesToDraw[distance] = particles[i]; + particles[i]->distanceToCam = distance; + particleSent = true; + } + else + distance -= 0.00001; + + } } } From 4532da59fa9aad7362d0221585d36aac09580630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=88ric=20Canela?= Date: Thu, 28 May 2020 12:10:52 +0200 Subject: [PATCH 4/8] Update ComponentParticleEmitter.cpp --- Broken Engine/Source/ComponentParticleEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Broken Engine/Source/ComponentParticleEmitter.cpp b/Broken Engine/Source/ComponentParticleEmitter.cpp index 52a70b41b..0950a5305 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.cpp +++ b/Broken Engine/Source/ComponentParticleEmitter.cpp @@ -621,7 +621,7 @@ void ComponentParticleEmitter::Load(json& node) followEmitter = node["followEmitter"].is_null() ? true : node["followEmitter"].get(); - playOnAwake = node["PlayOnAwake"].is_null() ? true : node["PlayOnAwake"].get(); + playOnAwake = node["PlayOnAwake"].is_null() ? false : node["PlayOnAwake"].get(); emisionActive = playOnAwake; std::string LParticlesSize = node["particlesSize"].is_null() ? "0" : node["particlesSize"]; From 1a12569efac34b543f65bca4a05cf973a0d6d5cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=88ric=20Canela?= Date: Thu, 28 May 2020 12:24:30 +0200 Subject: [PATCH 5/8] Update ComponentParticleEmitter.cpp --- Broken Engine/Source/ComponentParticleEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Broken Engine/Source/ComponentParticleEmitter.cpp b/Broken Engine/Source/ComponentParticleEmitter.cpp index 0950a5305..52a70b41b 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.cpp +++ b/Broken Engine/Source/ComponentParticleEmitter.cpp @@ -621,7 +621,7 @@ void ComponentParticleEmitter::Load(json& node) followEmitter = node["followEmitter"].is_null() ? true : node["followEmitter"].get(); - playOnAwake = node["PlayOnAwake"].is_null() ? false : node["PlayOnAwake"].get(); + playOnAwake = node["PlayOnAwake"].is_null() ? true : node["PlayOnAwake"].get(); emisionActive = playOnAwake; std::string LParticlesSize = node["particlesSize"].is_null() ? "0" : node["particlesSize"]; From be46cc45c41dea87fd543ee3534198c452198122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=88ric=20Canela?= Date: Thu, 28 May 2020 12:41:04 +0200 Subject: [PATCH 6/8] Revert "Update ComponentParticleEmitter.cpp" This reverts commit 1a12569efac34b543f65bca4a05cf973a0d6d5cf. --- Broken Engine/Source/ComponentParticleEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Broken Engine/Source/ComponentParticleEmitter.cpp b/Broken Engine/Source/ComponentParticleEmitter.cpp index 52a70b41b..0950a5305 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.cpp +++ b/Broken Engine/Source/ComponentParticleEmitter.cpp @@ -621,7 +621,7 @@ void ComponentParticleEmitter::Load(json& node) followEmitter = node["followEmitter"].is_null() ? true : node["followEmitter"].get(); - playOnAwake = node["PlayOnAwake"].is_null() ? true : node["PlayOnAwake"].get(); + playOnAwake = node["PlayOnAwake"].is_null() ? false : node["PlayOnAwake"].get(); emisionActive = playOnAwake; std::string LParticlesSize = node["particlesSize"].is_null() ? "0" : node["particlesSize"]; From 14e500fb35fe9873c359a6cbf464de6f55a5048e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Mar=C3=ADn?= <36265613+X0KA@users.noreply.github.com> Date: Thu, 28 May 2020 14:39:57 +0200 Subject: [PATCH 7/8] Particles collisions can be activated/deactivated --- .../Source/ComponentParticleEmitter.cpp | 51 +++++++++++++------ .../Source/ComponentParticleEmitter.h | 3 ++ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/Broken Engine/Source/ComponentParticleEmitter.cpp b/Broken Engine/Source/ComponentParticleEmitter.cpp index 52a70b41b..81cca9ea9 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.cpp +++ b/Broken Engine/Source/ComponentParticleEmitter.cpp @@ -140,13 +140,13 @@ void ComponentParticleEmitter::Enable() particleSystem = App->physics->mPhysics->createParticleSystem(maxParticles, perParticleRestOffset); particleSystem->setMaxMotionDistance(100); - if (collision_active) - { - physx::PxFilterData filterData; - filterData.word0 = (1 << GO->layer); - filterData.word1 = App->physics->layer_list.at(GO->layer).LayerGroup; - particleSystem->setSimulationFilterData(filterData); - } + //if (collision_active) + //{ + // physx::PxFilterData filterData; + // filterData.word0 = (1 << GO->layer); + // filterData.word1 = App->physics->layer_list.at(GO->layer).LayerGroup; + // particleSystem->setSimulationFilterData(filterData); + //} if (particleSystem) App->physics->AddParticleActor(particleSystem, GO); @@ -197,13 +197,13 @@ void ComponentParticleEmitter::UpdateParticles(float dt) } } - if (collision_active) - { - physx::PxFilterData filterData; - filterData.word0 = (1 << GO->layer); // word0 = own ID - filterData.word1 = App->physics->layer_list.at(GO->layer).LayerGroup; // word1 = ID mask to filter pairs that trigger a contact callback; - particleSystem->setSimulationFilterData(filterData); - } + //if (collision_active) + //{ + // physx::PxFilterData filterData; + // filterData.word0 = (1 << GO->layer); // word0 = own ID + // filterData.word1 = App->physics->layer_list.at(GO->layer).LayerGroup; // word1 = ID mask to filter pairs that trigger a contact callback; + // particleSystem->setSimulationFilterData(filterData); + //} //Update particles //lock SDK buffers of *PxParticleSystem* ps for reading @@ -846,7 +846,8 @@ void ComponentParticleEmitter::Load(json& node) // --- Collisions --- collision_active = node.find("CollisionsActivated") == node.end() ? true : node["CollisionsActivated"].get(); - + SetActiveCollisions(collision_active); + // --- Face Culling --- particlesFaceCulling = node.find("ParticlesFaceCulling") == node.end() ? true : node["ParticlesFaceCulling"].get(); @@ -1081,7 +1082,8 @@ void ComponentParticleEmitter::CreateInspectorNode() if (ImGui::TreeNode("Collision Options")) { ImGui::Text("Enable Collisions"); - ImGui::Checkbox("##PE_EnableColl", &collision_active); + if (ImGui::Checkbox("##PE_EnableColl", &collision_active)) + SetActiveCollisions(collision_active); ImGui::TreePop(); } @@ -1623,6 +1625,23 @@ double ComponentParticleEmitter::GetRandomValue(double min, double max) //EREASE return App->RandomNumberGenerator.GetDoubleRNinRange(min, max); } +void ComponentParticleEmitter::SetActiveCollisions(bool collisionsActive) +{ + if (collisionsActive){ + physx::PxFilterData filterData; + filterData.word0 = (1 << GO->layer); + filterData.word1 = App->physics->layer_list.at(GO->layer).LayerGroup; + particleSystem->setSimulationFilterData(filterData); + } + else{ + physx::PxFilterData filterData; + filterData.word0 = 0; + filterData.word1 = 0; + particleSystem->setSimulationFilterData(filterData); + + } +} + void ComponentParticleEmitter::CreateParticles(uint particlesAmount) { uint particlesToCreate = particlesAmount; diff --git a/Broken Engine/Source/ComponentParticleEmitter.h b/Broken Engine/Source/ComponentParticleEmitter.h index 64969b9a6..9d7e01958 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.h +++ b/Broken Engine/Source/ComponentParticleEmitter.h @@ -83,6 +83,9 @@ class BROKEN_API ComponentParticleEmitter : public Component double GetRandomValue(double min, double max); //MUST EREASE IN THE FUTURE void HandleEditorBlendingSelector(); + // -- Decide if particles collide with the envioronment or not -- + void SetActiveCollisions(bool collisionsActive); + private: physx::PxParticleSystem* particleSystem = nullptr; From 2b475478eaa853777b3c744a1f1f74d9dfb19b6e Mon Sep 17 00:00:00 2001 From: lucho1 Date: Thu, 28 May 2020 17:03:19 +0200 Subject: [PATCH 8/8] Visual Changes to ParticlesEmitter Editor --- .../Source/ComponentParticleEmitter.cpp | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/Broken Engine/Source/ComponentParticleEmitter.cpp b/Broken Engine/Source/ComponentParticleEmitter.cpp index d52e388b5..d1c5e6de7 100644 --- a/Broken Engine/Source/ComponentParticleEmitter.cpp +++ b/Broken Engine/Source/ComponentParticleEmitter.cpp @@ -881,20 +881,24 @@ void ComponentParticleEmitter::CreateInspectorNode() ImGui::Text("Play on awake"); // --- Loop --- - ImGui::NewLine(); if (ImGui::Checkbox("##PELoop", &loop)) - if (loop) { - emisionActive = true; - firstEmision = true; - } - - ImGui::SameLine(); - ImGui::Text("Loop"); + if (loop) + { + emisionActive = true; + firstEmision = true; + } + + ImGui::SameLine(); ImGui::Text("Loop"); + //Follow emitter + ImGui::Checkbox("##SFollow emitter", &followEmitter); + ImGui::SameLine(); ImGui::Text("Follow emitter"); + + // Duration + ImGui::NewLine(); ImGui::Text("Duration"); ImGui::SameLine(); ImGui::DragInt("##PEDuration", &duration); - //Emitter position @@ -1014,12 +1018,8 @@ void ComponentParticleEmitter::CreateInspectorNode() if (forceChanged) particleSystem->setExternalAcceleration(externalAcceleration); - - //Follow emitter - ImGui::Text("Follow emitter"); - ImGui::Checkbox("##SFollow emitter", &followEmitter); - //Emision rate + ImGui::NewLine(); ImGui::Text("Emision rate (ms)"); ImGui::SetNextItemWidth(ImGui::GetWindowWidth() * 0.3f); ImGui::DragFloat("##SEmision rate", &emisionRate, 1.0f, 1.0f, 100000.0f); @@ -1076,14 +1076,17 @@ void ComponentParticleEmitter::CreateInspectorNode() int maxParticles = particlesPerCreation / emisionRate * particlesLifeTime; ImGui::Text("Total particles alive: %d", maxParticles); + + ImGui::NewLine(); ImGui::Separator(); // --- Collisions --- if (ImGui::TreeNode("Collision Options")) { - ImGui::Text("Enable Collisions"); if (ImGui::Checkbox("##PE_EnableColl", &collision_active)) SetActiveCollisions(collision_active); + + ImGui::SameLine(); ImGui::Text("Enable Collisions"); ImGui::TreePop(); } @@ -1441,7 +1444,7 @@ void ComponentParticleEmitter::CreateInspectorNode() { // Shadows & Lighting ImGui::NewLine(); - ImGui::SameLine(); + ImGui::NewLine(); ImGui::SameLine(); ImGui::Checkbox("Light Affected ", &m_AffectedByLight); ImGui::SameLine(); ImGui::Checkbox("Scene Color Affected", &m_AffectedBySceneColor);