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,
|
true,
|
||||||
(int)ModuleType.Update,
|
(int)ModuleType.Update,
|
||||||
false, // Invert
|
false, // Invert
|
||||||
0.0f, // Radius
|
5.0f, // Radius
|
||||||
0.0f, // Roughness
|
0.0f, // Roughness
|
||||||
0.1f, // Elasticity
|
0.1f, // Elasticity
|
||||||
0.0f, // Friction
|
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),
|
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, 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, 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),
|
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
|
// Not supported
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Collision (Global SDF)
|
||||||
|
case 336:
|
||||||
|
{
|
||||||
|
// Not supported
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#undef COLLISION_BEGIN
|
#undef COLLISION_BEGIN
|
||||||
#undef COLLISION_INPUTS_FETCH
|
#undef COLLISION_INPUTS_FETCH
|
||||||
|
|||||||
@@ -616,7 +616,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
|||||||
auto position = AccessParticleAttribute(node, nodeGpu->Attributes[0], AccessMode::ReadWrite);
|
auto position = AccessParticleAttribute(node, nodeGpu->Attributes[0], AccessMode::ReadWrite);
|
||||||
auto param = findOrAddGlobalSDF();
|
auto param = findOrAddGlobalSDF();
|
||||||
String wsPos = position.Value;
|
String wsPos = position.Value;
|
||||||
if (((ParticleEmitterGraphGPU*)_graphStack.Peek())->SimulationSpace == ParticlesSimulationSpace::Local)
|
if (IsLocalSimulationSpace())
|
||||||
wsPos = String::Format(TEXT("mul(float4({0}, 1), WorldMatrix).xyz"), wsPos);
|
wsPos = String::Format(TEXT("mul(float4({0}, 1), WorldMatrix).xyz"), wsPos);
|
||||||
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
||||||
_writer.Write(
|
_writer.Write(
|
||||||
@@ -666,13 +666,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
|||||||
case 330:
|
case 330:
|
||||||
{
|
{
|
||||||
COLLISION_BEGIN();
|
COLLISION_BEGIN();
|
||||||
|
const Value planePosition = GetValue(node->GetBox(5), 8).AsVector3();
|
||||||
auto planePositionBox = node->GetBox(5);
|
const Value planeNormal = GetValue(node->GetBox(6), 9).AsVector3();
|
||||||
auto planeNormalBox = node->GetBox(6);
|
|
||||||
|
|
||||||
const Value planePosition = GetValue(planePositionBox, 8).AsVector3();
|
|
||||||
const Value planeNormal = GetValue(planeNormalBox, 9).AsVector3();
|
|
||||||
|
|
||||||
_writer.Write(
|
_writer.Write(
|
||||||
TEXT(
|
TEXT(
|
||||||
" {{\n"
|
" {{\n"
|
||||||
@@ -699,13 +694,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
|||||||
case 331:
|
case 331:
|
||||||
{
|
{
|
||||||
COLLISION_BEGIN();
|
COLLISION_BEGIN();
|
||||||
|
const Value spherePosition = GetValue(node->GetBox(5), 8).AsVector3();
|
||||||
auto spherePositionBox = node->GetBox(5);
|
const Value sphereRadius = GetValue(node->GetBox(6), 9).AsFloat();
|
||||||
auto sphereRadiusBox = node->GetBox(6);
|
|
||||||
|
|
||||||
const Value spherePosition = GetValue(spherePositionBox, 8).AsVector3();
|
|
||||||
const Value sphereRadius = GetValue(sphereRadiusBox, 9).AsFloat();
|
|
||||||
|
|
||||||
_writer.Write(
|
_writer.Write(
|
||||||
TEXT(
|
TEXT(
|
||||||
" {{\n"
|
" {{\n"
|
||||||
@@ -735,13 +725,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
|||||||
case 332:
|
case 332:
|
||||||
{
|
{
|
||||||
COLLISION_BEGIN();
|
COLLISION_BEGIN();
|
||||||
|
const Value boxPosition = GetValue(node->GetBox(5), 8).AsVector3();
|
||||||
auto boxPositionBox = node->GetBox(5);
|
const Value boxSize = GetValue(node->GetBox(6), 9).AsVector3();
|
||||||
auto boxSizeBox = node->GetBox(6);
|
|
||||||
|
|
||||||
const Value boxPosition = GetValue(boxPositionBox, 8).AsVector3();
|
|
||||||
const Value boxSize = GetValue(boxSizeBox, 9).AsVector3();
|
|
||||||
|
|
||||||
_writer.Write(
|
_writer.Write(
|
||||||
TEXT(
|
TEXT(
|
||||||
" {{\n"
|
" {{\n"
|
||||||
@@ -786,15 +771,9 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
|||||||
case 333:
|
case 333:
|
||||||
{
|
{
|
||||||
COLLISION_BEGIN();
|
COLLISION_BEGIN();
|
||||||
|
const Value cylinderPosition = GetValue(node->GetBox(5), 8).AsVector3();
|
||||||
auto cylinderPositionBox = node->GetBox(5);
|
const Value cylinderHeight = GetValue(node->GetBox(6), 9).AsFloat();
|
||||||
auto cylinderHeightBox = node->GetBox(6);
|
const Value cylinderRadius = GetValue(node->GetBox(7), 10).AsFloat();
|
||||||
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();
|
|
||||||
|
|
||||||
_writer.Write(
|
_writer.Write(
|
||||||
TEXT(
|
TEXT(
|
||||||
" {{\n"
|
" {{\n"
|
||||||
@@ -842,13 +821,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
|||||||
case 334:
|
case 334:
|
||||||
{
|
{
|
||||||
COLLISION_BEGIN();
|
COLLISION_BEGIN();
|
||||||
|
const Value surfaceThickness = GetValue(node->GetBox(5), 8).AsFloat();
|
||||||
auto surfaceThicknessBox = node->GetBox(5);
|
|
||||||
|
|
||||||
const Value surfaceThickness = GetValue(surfaceThicknessBox, 8).AsFloat();
|
|
||||||
|
|
||||||
const auto sceneDepthTexture = findOrAddSceneTexture(MaterialSceneTextures::SceneDepth);
|
const auto sceneDepthTexture = findOrAddSceneTexture(MaterialSceneTextures::SceneDepth);
|
||||||
|
|
||||||
_writer.Write(
|
_writer.Write(
|
||||||
TEXT(
|
TEXT(
|
||||||
" {{\n"
|
" {{\n"
|
||||||
@@ -929,7 +903,51 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
|
|||||||
" }}\n"
|
" }}\n"
|
||||||
), position.Value, velocity.Value, mass.Value, param.ShaderName, attractionSpeed.Value, attractionForce.Value, stickDistance.Value, stickForce.Value);
|
), position.Value, velocity.Value, mass.Value, param.ShaderName, attractionSpeed.Value, attractionForce.Value, stickDistance.Value, stickForce.Value);
|
||||||
break;
|
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_BEGIN
|
||||||
#undef COLLISION_LOGIC
|
#undef COLLISION_LOGIC
|
||||||
|
|||||||
@@ -427,14 +427,10 @@ void ParticleEmitterGPUGenerator::ProcessGroupParticles(Box* box, Node* node, Va
|
|||||||
}
|
}
|
||||||
// Particle Position (world space)
|
// Particle Position (world space)
|
||||||
case 212:
|
case 212:
|
||||||
{
|
|
||||||
value = AccessParticleAttribute(node, TEXT("Position"), ParticleAttribute::ValueTypes::Vector3, AccessMode::Read);
|
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);
|
value = writeLocal(VariantType::Vector3, String::Format(TEXT("mul(float4({0}, 1), WorldMatrix).xyz"), value.Value), node);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
// Random Float Range
|
// Random Float Range
|
||||||
case 213:
|
case 213:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -156,6 +156,16 @@ private:
|
|||||||
{
|
{
|
||||||
return box->HasConnection() ? eatBox(box->GetParent<Node>(), box->FirstConnection()) : Value::Zero;
|
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
|
#endif
|
||||||
|
|||||||
@@ -430,12 +430,13 @@ public:
|
|||||||
USE_ATTRIBUTE(Position, Vector3, 0);
|
USE_ATTRIBUTE(Position, Vector3, 0);
|
||||||
break;
|
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, 330):
|
||||||
case GRAPH_NODE_MAKE_TYPE(15, 331):
|
case GRAPH_NODE_MAKE_TYPE(15, 331):
|
||||||
case GRAPH_NODE_MAKE_TYPE(15, 332):
|
case GRAPH_NODE_MAKE_TYPE(15, 332):
|
||||||
case GRAPH_NODE_MAKE_TYPE(15, 333):
|
case GRAPH_NODE_MAKE_TYPE(15, 333):
|
||||||
case GRAPH_NODE_MAKE_TYPE(15, 334):
|
case GRAPH_NODE_MAKE_TYPE(15, 334):
|
||||||
|
case GRAPH_NODE_MAKE_TYPE(15, 336):
|
||||||
{
|
{
|
||||||
USE_ATTRIBUTE(Position, Vector3, 0);
|
USE_ATTRIBUTE(Position, Vector3, 0);
|
||||||
USE_ATTRIBUTE(Velocity, Vector3, 1);
|
USE_ATTRIBUTE(Velocity, Vector3, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user