71 lines
2.2 KiB
Plaintext
71 lines
2.2 KiB
Plaintext
#pragma kernel Project
|
|
#pragma kernel Apply
|
|
|
|
#include "MathUtils.cginc"
|
|
#include "AtomicDeltas.cginc"
|
|
|
|
StructuredBuffer<int> particleIndices;
|
|
StructuredBuffer<float4> skinPoints;
|
|
StructuredBuffer<float4> skinNormals;
|
|
StructuredBuffer<float3> skinRadiiBackstop;
|
|
StructuredBuffer<float> skinCompliance;
|
|
RWStructuredBuffer<float> lambdas;
|
|
|
|
RWStructuredBuffer<float4> positions;
|
|
StructuredBuffer<float> invMasses;
|
|
|
|
// Variables set from the CPU
|
|
uint activeConstraintCount;
|
|
float deltaTime;
|
|
float sorFactor;
|
|
|
|
[numthreads(128, 1, 1)]
|
|
void Project (uint3 id : SV_DispatchThreadID)
|
|
{
|
|
unsigned int i = id.x;
|
|
|
|
if (i >= activeConstraintCount) return;
|
|
|
|
float radius = skinRadiiBackstop[i].x;
|
|
float collisionRadius = skinRadiiBackstop[i].y;
|
|
float backstopDistance = collisionRadius + skinRadiiBackstop[i].z;
|
|
|
|
float compliance = skinCompliance[i] / (deltaTime * deltaTime);
|
|
int p = particleIndices[i];
|
|
|
|
if (invMasses[p] > 0)
|
|
{
|
|
float4 toSkin = positions[p] - skinPoints[i];
|
|
float4 toBackstop = positions[p] - (skinPoints[i] - skinNormals[i] * backstopDistance);
|
|
|
|
// distance to skin and backstop sphere centers:
|
|
float d = length(toSkin);
|
|
float b = length(toBackstop);
|
|
|
|
// constrain particle within skin radius.
|
|
// ignore mass in the equations (use 1), as we don't want particle mass to interfere with skin compliance.
|
|
// We should be able to adjust skin properties and particle mass (for collisions) independently.
|
|
float constraint = max(0,d - radius);
|
|
float dlambda = (-constraint - compliance * lambdas[i]) / (1 + compliance);
|
|
lambdas[i] += dlambda;
|
|
float4 skinCorrection = dlambda * toSkin / (d + EPSILON);
|
|
|
|
// constrain particle outside the backstop sphere (0 compliance):
|
|
constraint = min(0, b - collisionRadius);
|
|
float4 backstopCorrection = - constraint * toBackstop / (b + EPSILON);
|
|
|
|
AddPositionDelta(p, skinCorrection + backstopCorrection);
|
|
}
|
|
}
|
|
|
|
[numthreads(128, 1, 1)]
|
|
void Apply (uint3 id : SV_DispatchThreadID)
|
|
{
|
|
unsigned int i = id.x;
|
|
|
|
if (i >= activeConstraintCount) return;
|
|
|
|
int p1 = particleIndices[i];
|
|
|
|
ApplyPositionDelta(positions, p1, sorFactor);
|
|
} |