61 lines
1.7 KiB
Plaintext
61 lines
1.7 KiB
Plaintext
#pragma kernel Project
|
|
|
|
#include "MathUtils.cginc"
|
|
#include "AtomicDeltas.cginc"
|
|
|
|
StructuredBuffer<int> particleIndices;
|
|
StructuredBuffer<float> aerodynamicCoeffs;
|
|
|
|
StructuredBuffer<float4> positions;
|
|
StructuredBuffer<uint4> normals;
|
|
StructuredBuffer<float4> wind;
|
|
StructuredBuffer<float> invMasses;
|
|
|
|
RWStructuredBuffer<float4> velocities;
|
|
|
|
// Variables set from the CPU
|
|
uint activeConstraintCount;
|
|
float deltaTime;
|
|
|
|
[numthreads(128, 1, 1)]
|
|
void Project (uint3 id : SV_DispatchThreadID)
|
|
{
|
|
unsigned int i = id.x;
|
|
|
|
if (i >= activeConstraintCount) return;
|
|
|
|
int p = particleIndices[i];
|
|
|
|
float area = aerodynamicCoeffs[i * 3];
|
|
float dragCoeff = aerodynamicCoeffs[i * 3 + 1];
|
|
float liftCoeff = aerodynamicCoeffs[i * 3 + 2];
|
|
|
|
if (invMasses[p] > 0)
|
|
{
|
|
float4 relVelocity = velocities[p] - wind[p];
|
|
float rvSqrMag = dot(relVelocity, relVelocity);
|
|
|
|
if (rvSqrMag < EPSILON)
|
|
return;
|
|
|
|
float4 rvNorm = relVelocity / sqrt(rvSqrMag);
|
|
|
|
// calculate surface normal (always facing wind)
|
|
float4 surfNormal = asfloat(normals[p]) * sign(dot(asfloat(normals[p]), rvNorm));
|
|
|
|
// aerodynamic_factor was originally multiplied by air_density. The density is now premultiplied in lift and drag.
|
|
float aerodynamicFactor = 0.5f * rvSqrMag * area;
|
|
float attackAngle = dot(surfNormal,rvNorm);
|
|
|
|
float3 liftDirection = normalizesafe(cross(cross(surfNormal.xyz, rvNorm.xyz), rvNorm.xyz));
|
|
|
|
//drag:
|
|
velocities[p] += (-dragCoeff * rvNorm +
|
|
|
|
// lift:
|
|
liftCoeff * float4(liftDirection.xyz,0)) *
|
|
|
|
// scale
|
|
attackAngle * min(aerodynamicFactor * invMasses[p] * deltaTime, 1000);
|
|
}
|
|
} |