From 3ba1ebb847c056dc94230f1900b2c118ee0b88a7 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 12 Dec 2024 20:41:11 -0600 Subject: [PATCH 1/3] Add rotate position shape as particle module. --- .../Surface/Archetypes/ParticleModules.cs | 19 ++++++++++ ...rticleEmitterGraph.CPU.ParticleModules.cpp | 37 +++++++++++++++++++ ...rticleEmitterGraph.GPU.ParticleModules.cpp | 14 +++++++ 3 files changed, 70 insertions(+) diff --git a/Source/Editor/Surface/Archetypes/ParticleModules.cs b/Source/Editor/Surface/Archetypes/ParticleModules.cs index 9dbfbce77..6ee1270ac 100644 --- a/Source/Editor/Surface/Archetypes/ParticleModules.cs +++ b/Source/Editor/Surface/Archetypes/ParticleModules.cs @@ -924,6 +924,25 @@ namespace FlaxEditor.Surface.Archetypes (int)ModuleType.Initialize, }, }, + new NodeArchetype + { + TypeID = 216, + Create = CreateParticleModuleNode, + Title = "Rotate Position Shape", + Description = "Rotate the shape.", + Flags = DefaultModuleFlags, + Size = new Float2(200, 1 * Surface.Constants.LayoutOffsetY), + DefaultValues = new object[] + { + true, + (int)ModuleType.Initialize, + Quaternion.Identity, + }, + Elements = new [] + { + NodeElementArchetype.Factory.Input(-0.5f, "Rotation", true, typeof(Quaternion), 0, 2), + } + }, GetParticleAttribute(ModuleType.Initialize, 250, "Set Position", "Sets the particle position", typeof(Float3), Float3.Zero), GetParticleAttribute(ModuleType.Initialize, 251, "Set Lifetime", "Sets the particle lifetime (in seconds)", typeof(float), 10.0f), GetParticleAttribute(ModuleType.Initialize, 252, "Set Age", "Sets the particle age (in seconds)", typeof(float), 0.0f), diff --git a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp index 28013b5b9..98642b34f 100644 --- a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp +++ b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp @@ -1150,6 +1150,43 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode* // Not supported break; } + // Rotate Position Shape + case 216: + { + PARTICLE_EMITTER_MODULE("Rotate Position Shape"); + auto& positionAttr = context.Data->Buffer->Layout->Attributes[node->Attributes[0]]; + + byte* positionPtr = start + positionAttr.Offset; + + auto quatBox = node->GetBox(0); + +#define INPUTS_FETCH() \ +const Quaternion quat = (Quaternion)GetValue(quatBox, 2); +#define LOGIC() \ +*(Float3*)positionPtr = quat * *((Float3*)positionPtr); \ +positionPtr += stride; + + if (node->UsePerParticleDataResolve()) + { + for (int32 particleIndex = particlesStart; particleIndex < particlesEnd; particleIndex++) + { + context.ParticleIndex = particleIndex; + INPUTS_FETCH(); + LOGIC(); + } + } + else + { + INPUTS_FETCH(); + for (int32 particleIndex = particlesStart; particleIndex < particlesEnd; particleIndex++) + { + LOGIC(); + } + } +#undef INPUTS_FETCH +#undef LOGIC + break; + } // Helper macros for collision modules to share the code #define COLLISION_BEGIN() \ diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp index bbf4ccdf7..160097b75 100644 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp +++ b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp @@ -632,6 +632,20 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node) ), position.Value, param.ShaderName, wsPos); break; } + // Rotate position shape + case 216: + { + auto positionAttr = AccessParticleAttribute(node, nodeGpu->Attributes[0], AccessMode::Write); + const Value quaternion = tryGetValue(node->GetBox(0), Value::InitForZero(VariantType::Quaternion)).Cast(VariantType::Quaternion); + _writer.Write( + TEXT( + " {{\n" + " // Rotate position shape\n" + " {0} = QuatRotateVector({1}, {0});\n" + " }}\n" + ), positionAttr.Value, quaternion.Value); + break; + } // Helper macros for collision modules to share the code #define COLLISION_BEGIN() \ From 873491eca290e131efb01bb5ab33ad8dab176651 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 12 Dec 2024 21:07:00 -0600 Subject: [PATCH 2/3] Fix CPU particle code. --- .../Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp index 98642b34f..4839151b4 100644 --- a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp +++ b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp @@ -1163,7 +1163,12 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode* #define INPUTS_FETCH() \ const Quaternion quat = (Quaternion)GetValue(quatBox, 2); #define LOGIC() \ -*(Float3*)positionPtr = quat * *((Float3*)positionPtr); \ +Quaternion nq = Quaternion::Invert(quat); \ +Float3 v3 = *((Float3*)positionPtr); \ +Float4 v4 = Float4(v3); \ +Quaternion q = Quaternion(v4); \ +Quaternion rq = quat * (q * nq); \ +*(Float3*)positionPtr = Float3(rq.X, rq.Y, rq.Z); \ positionPtr += stride; if (node->UsePerParticleDataResolve()) From 53ba5968fd12f693e21fc8d41048124aed212a05 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 27 Jan 2025 11:42:59 +0100 Subject: [PATCH 3/3] Fix missing default value usage on GPU particle shape rotation and simplify CPU code #3104 --- .../ParticleEmitterGraph.CPU.ParticleModules.cpp | 15 +++++++-------- .../ParticleEmitterGraph.GPU.ParticleModules.cpp | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp index 4839151b4..42885f3c3 100644 --- a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp +++ b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp @@ -1161,15 +1161,14 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode* auto quatBox = node->GetBox(0); #define INPUTS_FETCH() \ -const Quaternion quat = (Quaternion)GetValue(quatBox, 2); + const Quaternion quat = (Quaternion)GetValue(quatBox, 2); #define LOGIC() \ -Quaternion nq = Quaternion::Invert(quat); \ -Float3 v3 = *((Float3*)positionPtr); \ -Float4 v4 = Float4(v3); \ -Quaternion q = Quaternion(v4); \ -Quaternion rq = quat * (q * nq); \ -*(Float3*)positionPtr = Float3(rq.X, rq.Y, rq.Z); \ -positionPtr += stride; + Quaternion nq = Quaternion::Invert(quat); \ + Float3 v3 = *((Float3*)positionPtr); \ + Quaternion q = Quaternion(v3.X, v3.Y, v3.Z, 0.0f); \ + Quaternion rq = quat * (q * nq); \ + *(Float3*)positionPtr = Float3(rq.X, rq.Y, rq.Z); \ + positionPtr += stride; if (node->UsePerParticleDataResolve()) { diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp index 160097b75..0fb687157 100644 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp +++ b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp @@ -636,7 +636,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node) case 216: { auto positionAttr = AccessParticleAttribute(node, nodeGpu->Attributes[0], AccessMode::Write); - const Value quaternion = tryGetValue(node->GetBox(0), Value::InitForZero(VariantType::Quaternion)).Cast(VariantType::Quaternion); + const Value quaternion = GetValue(node->GetBox(0), 2).Cast(VariantType::Quaternion); _writer.Write( TEXT( " {{\n"