voidImplict() { for (int i = 0; i < P.Length; i++) { V[i] += ((P2[i] = transform.TransformPoint(P[i])) - P1[i]) / dt; if (W[i] != 0) P[i] = P2[i] += (dt * (V[i] *= damping)); }
float invdt2 = 1 / dt / dt, factor = 1 / (invdt2 + 4 * k), rho2 = rho * rho, w = 1; for (int i = 0; i < iter; i++) { //Momentum and Gravity. for (int j = 0; j < P.Length; j++) G[j] = invdt2 * (P2[j] - P[j]) - g;
//Spring Force. for (int j = 0; j < C.Length; j++) { int x = C[j].x, y = C[j].y; float z = C[j].z; Vector3 grad = k * (1 - z / (P2[x] - P2[y]).magnitude) * (P2[x] - P2[y]); G[x] += grad; G[y] -= grad; }
if (i == 0) w = 1; elseif (i == 1) w = 2 / (2 - rho2); else w = 4 / (4 - w * rho2);
//Update P2 by gradient. for (int j = 0; j < P.Length; j++) { if (W[j] == 0) continue; Vector3 old = P2[j]; P2[j] = w * (P2[j] - factor * G[j]) + (1 - w) * P1[j]; P1[j] = old; } }
for (int i = 0; i < P.Length; i++) { V[i] += (P2[i] - P[i]) / dt; P[i] = transform.InverseTransformPoint(P2[i]); } }
PBD
公式算法流程什么就不摆了,大致思路就是先自由运动,再上约束限制,详细论文解读可以看看这篇jeffzzz:position based dynamics笔记。但PBD其实也存在一些问题,最大的问题就是不那么物理,其展示出来的物理特性只与时间步长和迭代次数挂钩。但时步与表现相关,迭代次数与性能相关,为了改变物理特性而给不同物体赋予不同时步和迭代次数想想就很埋雷……