Add Collision (Global SDF) particle module
This commit is contained in:
BIN
Content/Editor/Primitives/Sphere.flax
(Stored with Git LFS)
BIN
Content/Editor/Primitives/Sphere.flax
(Stored with Git LFS)
Binary file not shown.
@@ -1357,7 +1357,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
true,
|
||||
(int)ModuleType.Update,
|
||||
false, // Invert
|
||||
0.0f, // Radius
|
||||
5.0f, // Radius
|
||||
0.0f, // Roughness
|
||||
0.1f, // Elasticity
|
||||
0.0f, // Friction
|
||||
@@ -1400,6 +1400,34 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
NodeElementArchetype.Factory.Input(-0.5f + 3.0f, "Stick Force", true, typeof(float), 3, 5),
|
||||
},
|
||||
},
|
||||
new NodeArchetype
|
||||
{
|
||||
TypeID = 336,
|
||||
Create = CreateParticleModuleNode,
|
||||
Title = "Collision (Global SDF)",
|
||||
Description = "Collides particles with the scene Global SDF",
|
||||
Flags = DefaultModuleFlags,
|
||||
Size = new Vector2(200, 5 * Surface.Constants.LayoutOffsetY),
|
||||
DefaultValues = new object[]
|
||||
{
|
||||
true,
|
||||
(int)ModuleType.Update,
|
||||
false, // Invert
|
||||
5.0f, // Radius
|
||||
0.4f, // Roughness
|
||||
0.1f, // Elasticity
|
||||
0.0f, // Friction
|
||||
0.0f, // Lifetime Loss
|
||||
},
|
||||
Elements = new[]
|
||||
{
|
||||
NodeElementArchetype.Factory.Input(-0.5f + 0, "Radius", true, typeof(float), 0, 3),
|
||||
NodeElementArchetype.Factory.Input(-0.5f + 1, "Roughness", true, typeof(float), 1, 4),
|
||||
NodeElementArchetype.Factory.Input(-0.5f + 2, "Elasticity", true, typeof(float), 2, 5),
|
||||
NodeElementArchetype.Factory.Input(-0.5f + 3, "Friction", true, typeof(float), 3, 6),
|
||||
NodeElementArchetype.Factory.Input(-0.5f + 4, "Lifetime Loss", true, typeof(float), 4, 7),
|
||||
},
|
||||
},
|
||||
GetParticleAttribute(ModuleType.Update, 350, "Set Position", "Sets the particle position", typeof(Vector3), Vector3.Zero),
|
||||
GetParticleAttribute(ModuleType.Update, 351, "Set Lifetime", "Sets the particle lifetime (in seconds)", typeof(float), 10.0f),
|
||||
GetParticleAttribute(ModuleType.Update, 352, "Set Age", "Sets the particle age (in seconds)", typeof(float), 0.0f),
|
||||
|
||||
@@ -1475,6 +1475,12 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode*
|
||||
// Not supported
|
||||
break;
|
||||
}
|
||||
// Collision (Global SDF)
|
||||
case 336:
|
||||
{
|
||||
// Not supported
|
||||
break;
|
||||
}
|
||||
|
||||
#undef COLLISION_BEGIN
|
||||
#undef COLLISION_INPUTS_FETCH
|
||||
|
||||
@@ -616,7 +616,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
||||
auto position = AccessParticleAttribute(node, nodeGpu->Attributes[0], AccessMode::ReadWrite);
|
||||
auto param = findOrAddGlobalSDF();
|
||||
String wsPos = position.Value;
|
||||
if (((ParticleEmitterGraphGPU*)_graphStack.Peek())->SimulationSpace == ParticlesSimulationSpace::Local)
|
||||
if (IsLocalSimulationSpace())
|
||||
wsPos = String::Format(TEXT("mul(float4({0}, 1), WorldMatrix).xyz"), wsPos);
|
||||
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
||||
_writer.Write(
|
||||
@@ -666,13 +666,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
||||
case 330:
|
||||
{
|
||||
COLLISION_BEGIN();
|
||||
|
||||
auto planePositionBox = node->GetBox(5);
|
||||
auto planeNormalBox = node->GetBox(6);
|
||||
|
||||
const Value planePosition = GetValue(planePositionBox, 8).AsVector3();
|
||||
const Value planeNormal = GetValue(planeNormalBox, 9).AsVector3();
|
||||
|
||||
const Value planePosition = GetValue(node->GetBox(5), 8).AsVector3();
|
||||
const Value planeNormal = GetValue(node->GetBox(6), 9).AsVector3();
|
||||
_writer.Write(
|
||||
TEXT(
|
||||
" {{\n"
|
||||
@@ -699,13 +694,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
||||
case 331:
|
||||
{
|
||||
COLLISION_BEGIN();
|
||||
|
||||
auto spherePositionBox = node->GetBox(5);
|
||||
auto sphereRadiusBox = node->GetBox(6);
|
||||
|
||||
const Value spherePosition = GetValue(spherePositionBox, 8).AsVector3();
|
||||
const Value sphereRadius = GetValue(sphereRadiusBox, 9).AsFloat();
|
||||
|
||||
const Value spherePosition = GetValue(node->GetBox(5), 8).AsVector3();
|
||||
const Value sphereRadius = GetValue(node->GetBox(6), 9).AsFloat();
|
||||
_writer.Write(
|
||||
TEXT(
|
||||
" {{\n"
|
||||
@@ -735,13 +725,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
||||
case 332:
|
||||
{
|
||||
COLLISION_BEGIN();
|
||||
|
||||
auto boxPositionBox = node->GetBox(5);
|
||||
auto boxSizeBox = node->GetBox(6);
|
||||
|
||||
const Value boxPosition = GetValue(boxPositionBox, 8).AsVector3();
|
||||
const Value boxSize = GetValue(boxSizeBox, 9).AsVector3();
|
||||
|
||||
const Value boxPosition = GetValue(node->GetBox(5), 8).AsVector3();
|
||||
const Value boxSize = GetValue(node->GetBox(6), 9).AsVector3();
|
||||
_writer.Write(
|
||||
TEXT(
|
||||
" {{\n"
|
||||
@@ -786,15 +771,9 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
||||
case 333:
|
||||
{
|
||||
COLLISION_BEGIN();
|
||||
|
||||
auto cylinderPositionBox = node->GetBox(5);
|
||||
auto cylinderHeightBox = node->GetBox(6);
|
||||
auto cylinderRadiusBox = node->GetBox(7);
|
||||
|
||||
const Value cylinderPosition = GetValue(cylinderPositionBox, 8).AsVector3();
|
||||
const Value cylinderHeight = GetValue(cylinderHeightBox, 9).AsFloat();
|
||||
const Value cylinderRadius = GetValue(cylinderRadiusBox, 10).AsFloat();
|
||||
|
||||
const Value cylinderPosition = GetValue(node->GetBox(5), 8).AsVector3();
|
||||
const Value cylinderHeight = GetValue(node->GetBox(6), 9).AsFloat();
|
||||
const Value cylinderRadius = GetValue(node->GetBox(7), 10).AsFloat();
|
||||
_writer.Write(
|
||||
TEXT(
|
||||
" {{\n"
|
||||
@@ -842,13 +821,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
||||
case 334:
|
||||
{
|
||||
COLLISION_BEGIN();
|
||||
|
||||
auto surfaceThicknessBox = node->GetBox(5);
|
||||
|
||||
const Value surfaceThickness = GetValue(surfaceThicknessBox, 8).AsFloat();
|
||||
|
||||
const Value surfaceThickness = GetValue(node->GetBox(5), 8).AsFloat();
|
||||
const auto sceneDepthTexture = findOrAddSceneTexture(MaterialSceneTextures::SceneDepth);
|
||||
|
||||
_writer.Write(
|
||||
TEXT(
|
||||
" {{\n"
|
||||
@@ -929,7 +903,51 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
||||
" }}\n"
|
||||
), position.Value, velocity.Value, mass.Value, param.ShaderName, attractionSpeed.Value, attractionForce.Value, stickDistance.Value, stickForce.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Collision (Global SDF)
|
||||
case 336:
|
||||
{
|
||||
COLLISION_BEGIN();
|
||||
auto param = findOrAddGlobalSDF();
|
||||
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
||||
const Char* format = IsLocalSimulationSpace()
|
||||
? TEXT(
|
||||
" {{\n"
|
||||
" // Collision (Global SDF)\n"
|
||||
" float3 nextPos = {0} + {1} * DeltaTime;\n"
|
||||
" nextPos = mul(float4(nextPos, 1), WorldMatrix).xyz;\n"
|
||||
" float dist = SampleGlobalSDF({10}, {10}_Tex, nextPos);\n"
|
||||
" if (dist < {5})\n"
|
||||
" {{\n"
|
||||
" {0} = mul(float4({0}, 1), WorldMatrix).xyz;\n"
|
||||
" float3 n = normalize(SampleGlobalSDFGradient({10}, {10}_Tex, {0}, dist));\n"
|
||||
" {0} += n * -dist;\n"
|
||||
" {0} = mul(float4({0}, 1), InvWorldMatrix).xyz;\n"
|
||||
COLLISION_LOGIC()
|
||||
" }}\n"
|
||||
)
|
||||
: TEXT(
|
||||
" {{\n"
|
||||
" // Collision (Global SDF)\n"
|
||||
" float3 nextPos = {0} + {1} * DeltaTime;\n"
|
||||
" float dist = SampleGlobalSDF({10}, {10}_Tex, nextPos);\n"
|
||||
" if (dist < {5})\n"
|
||||
" {{\n"
|
||||
" float3 n = normalize(SampleGlobalSDFGradient({10}, {10}_Tex, {0}, dist));\n"
|
||||
" {0} += n * -dist;\n"
|
||||
COLLISION_LOGIC()
|
||||
" }}\n"
|
||||
);
|
||||
_writer.Write(format,
|
||||
// 0-4
|
||||
positionAttr.Value, velocityAttr.Value, ageAttr.Value, invert, sign,
|
||||
// 5-9
|
||||
radius.Value, roughness.Value, elasticity.Value, friction.Value, lifetimeLoss.Value,
|
||||
// 10
|
||||
param.ShaderName
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
#undef COLLISION_BEGIN
|
||||
#undef COLLISION_LOGIC
|
||||
|
||||
@@ -427,14 +427,10 @@ void ParticleEmitterGPUGenerator::ProcessGroupParticles(Box* box, Node* node, Va
|
||||
}
|
||||
// Particle Position (world space)
|
||||
case 212:
|
||||
{
|
||||
value = AccessParticleAttribute(node, TEXT("Position"), ParticleAttribute::ValueTypes::Vector3, AccessMode::Read);
|
||||
if (((ParticleEmitterGraphGPU*)_graphStack.Peek())->SimulationSpace == ParticlesSimulationSpace::Local)
|
||||
{
|
||||
if (IsLocalSimulationSpace())
|
||||
value = writeLocal(VariantType::Vector3, String::Format(TEXT("mul(float4({0}, 1), WorldMatrix).xyz"), value.Value), node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Random Float Range
|
||||
case 213:
|
||||
{
|
||||
|
||||
@@ -156,6 +156,16 @@ private:
|
||||
{
|
||||
return box->HasConnection() ? eatBox(box->GetParent<Node>(), box->FirstConnection()) : Value::Zero;
|
||||
}
|
||||
|
||||
bool IsLocalSimulationSpace() const
|
||||
{
|
||||
return ((ParticleEmitterGraphGPU*)_graphStack.Peek())->SimulationSpace == ParticlesSimulationSpace::Local;
|
||||
}
|
||||
|
||||
bool IsWorldSimulationSpace() const
|
||||
{
|
||||
return ((ParticleEmitterGraphGPU*)_graphStack.Peek())->SimulationSpace == ParticlesSimulationSpace::World;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -430,12 +430,13 @@ public:
|
||||
USE_ATTRIBUTE(Position, Vector3, 0);
|
||||
break;
|
||||
}
|
||||
// Collision (plane/sphere/box/cylinder/depth)
|
||||
// Collision (plane/sphere/box/cylinder/depth/Global SDF)
|
||||
case GRAPH_NODE_MAKE_TYPE(15, 330):
|
||||
case GRAPH_NODE_MAKE_TYPE(15, 331):
|
||||
case GRAPH_NODE_MAKE_TYPE(15, 332):
|
||||
case GRAPH_NODE_MAKE_TYPE(15, 333):
|
||||
case GRAPH_NODE_MAKE_TYPE(15, 334):
|
||||
case GRAPH_NODE_MAKE_TYPE(15, 336):
|
||||
{
|
||||
USE_ATTRIBUTE(Position, Vector3, 0);
|
||||
USE_ATTRIBUTE(Velocity, Vector3, 1);
|
||||
|
||||
Reference in New Issue
Block a user