_xiaofang/xiaofang/Assets/Obi/Resources/Compute/BendTwistConstraints.compute
杨号敬 bcc74f0465 add
2024-12-18 02:18:45 +08:00

78 lines
2.2 KiB
Plaintext

#pragma kernel Project
#pragma kernel Apply
#include "MathUtils.cginc"
#include "AtomicDeltas.cginc"
StructuredBuffer<int> orientationIndices;
StructuredBuffer<float3> stiffnesses;
StructuredBuffer<float2> plasticity;
RWStructuredBuffer<quaternion> restDarboux;
RWStructuredBuffer<float3> lambdas;
RWStructuredBuffer<quaternion> orientations;
StructuredBuffer<float> invRotationalMasses;
// 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;
int q1 = orientationIndices[i * 2];
int q2 = orientationIndices[i * 2 + 1];
float w1 = invRotationalMasses[q1];
float w2 = invRotationalMasses[q2];
// calculate time adjusted compliance
float3 compliances = stiffnesses[i] / (deltaTime * deltaTime);
// rest and current darboux vectors
quaternion rest = restDarboux[i];
quaternion omega = qmul(q_conj(orientations[q1]), orientations[q2]);
quaternion omega_plus;
omega_plus = omega + rest; //delta Omega with - omega_0
omega -= rest; //delta Omega with + omega_0
if (dot(omega.xyz,omega.xyz) > dot(omega_plus.xyz,omega_plus.xyz))
omega = omega_plus;
// plasticity
if (dot(omega.xyz, omega.xyz) > plasticity[i].x * plasticity[i].x)
{
rest += omega * plasticity[i].y * deltaTime;
restDarboux[i] = rest;
}
float3 dlambda = (omega.xyz - compliances * lambdas[i]) / (compliances + w1 + w2 + EPSILON);
//discrete Darboux vector does not have vanishing scalar part
quaternion dlambdaQ = quaternion(dlambda[0], dlambda[1], dlambda[2],0);
AddOrientationDelta(q1, qmul(orientations[q2], dlambdaQ) * w1);
AddOrientationDelta(q2,-qmul(orientations[q1], dlambdaQ) * w2);
lambdas[i] += dlambda;
}
[numthreads(128, 1, 1)]
void Apply (uint3 id : SV_DispatchThreadID)
{
unsigned int i = id.x;
if (i >= activeConstraintCount) return;
int q1 = orientationIndices[i * 2];
int q2 = orientationIndices[i * 2 + 1];
ApplyOrientationDelta(orientations, q1, sorFactor);
ApplyOrientationDelta(orientations, q2, sorFactor);
}