3 cbuffer ApplyForcesCB : register( b0 )
\r
5 unsigned int numNodes;
\r
12 StructuredBuffer<int> g_vertexClothIdentifier : register( t0 );
\r
13 StructuredBuffer<float4> g_vertexNormal : register( t1 );
\r
14 StructuredBuffer<float> g_vertexArea : register( t2 );
\r
15 StructuredBuffer<float> g_vertexInverseMass : register( t3 );
\r
16 // TODO: These could be combined into a lift/drag factor array along with medium density
\r
17 StructuredBuffer<float> g_clothLiftFactor : register( t4 );
\r
18 StructuredBuffer<float> g_clothDragFactor : register( t5 );
\r
19 StructuredBuffer<float4> g_clothWindVelocity : register( t6 );
\r
20 StructuredBuffer<float4> g_clothAcceleration : register( t7 );
\r
21 StructuredBuffer<float> g_clothMediumDensity : register( t8 );
\r
23 RWStructuredBuffer<float4> g_vertexForceAccumulator : register( u0 );
\r
24 RWStructuredBuffer<float4> g_vertexVelocity : register( u1 );
\r
26 float3 projectOnAxis( float3 v, float3 a )
\r
28 return (a*dot(v, a));
\r
31 [numthreads(128, 1, 1)]
\r
33 ApplyForcesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
\r
35 unsigned int nodeID = DTid.x;
\r
36 if( nodeID < numNodes )
\r
38 int clothId = g_vertexClothIdentifier[nodeID];
\r
39 float nodeIM = g_vertexInverseMass[nodeID];
\r
43 float3 nodeV = g_vertexVelocity[nodeID].xyz;
\r
44 float3 normal = g_vertexNormal[nodeID].xyz;
\r
45 float area = g_vertexArea[nodeID];
\r
46 float3 nodeF = g_vertexForceAccumulator[nodeID].xyz;
\r
48 // Read per-cloth values
\r
49 float3 clothAcceleration = g_clothAcceleration[clothId].xyz;
\r
50 float3 clothWindVelocity = g_clothWindVelocity[clothId].xyz;
\r
51 float liftFactor = g_clothLiftFactor[clothId];
\r
52 float dragFactor = g_clothDragFactor[clothId];
\r
53 float mediumDensity = g_clothMediumDensity[clothId];
\r
55 // Apply the acceleration to the cloth rather than do this via a force
\r
56 nodeV += (clothAcceleration*solverdt);
\r
58 g_vertexVelocity[nodeID] = float4(nodeV, 0.f);
\r
60 float3 relativeWindVelocity = nodeV - clothWindVelocity;
\r
61 float relativeSpeedSquared = dot(relativeWindVelocity, relativeWindVelocity);
\r
63 if( relativeSpeedSquared > epsilon )
\r
65 // Correct direction of normal relative to wind direction and get dot product
\r
66 normal = normal * (dot(normal, relativeWindVelocity) < 0 ? -1.f : 1.f);
\r
67 float dvNormal = dot(normal, relativeWindVelocity);
\r
70 float3 force = float3(0.f, 0.f, 0.f);
\r
71 float c0 = area * dvNormal * relativeSpeedSquared / 2.f;
\r
72 float c1 = c0 * mediumDensity;
\r
73 force += normal * (-c1 * liftFactor);
\r
74 force += normalize(relativeWindVelocity)*(-c1 * dragFactor);
\r
76 float dtim = solverdt * nodeIM;
\r
77 float3 forceDTIM = force * dtim;
\r
79 float3 nodeFPlusForce = nodeF + force;
\r
81 // m_nodesf[i] -= ProjectOnAxis(m_nodesv[i], force.normalized())/dtim;
\r
82 float3 nodeFMinus = nodeF - (projectOnAxis(nodeV, normalize(force))/dtim);
\r
84 nodeF = nodeFPlusForce;
\r
85 if( dot(forceDTIM, forceDTIM) > dot(nodeV, nodeV) )
\r
88 g_vertexForceAccumulator[nodeID] = float4(nodeF, 0.0f);
\r