将一个球体约束添加到布料SIM卡的正确方法是什么?
我正在尝试添加一个约束Skeel Lee's cloth simulation source code的球体(或胶囊),但我不确定如何正确地做到这一点。
我创建了一个相当简单的约束,其中"踢"粒子以相反的方向从球体中退出(与矢量朝向中心相反):
void SatisfySphereConstraints()
{
foreach (var simObj in this.simObjects)
simObj.CurrPosition += SphereConstraint(simObj.CurrPosition, _center, _radius);
}
Vector3 SphereConstraint(Vector3 position, Vector3 center, float radius)
{
var delta = position - center;
var distance = delta.Length();
if (distance < radius)
return (radius - distance) * delta / distance;
return Vector3.Zero;
}
然后我在现有代码中插入了该方法:
ApplyForces();
Integrate();
for (var i = 0; i < constraintIterations; i++)
{
foreach (Constraint constraint in constraints)
constraint.SatisfyConstraint();
SatisfySphereConstraints(); // <-- I added it here
}
碰撞代码适用于这种情况(C
是球体的中心,P
是当前粒子位置,P'
是解析位置):
但是如果粒子移动很快就会出现问题,因为粒子基本上会跳到球体的另一侧(P1
是前一个位置,P2
是当前位置,{{ 1}}是我认为它应该被解决的方式),而不是返回到前一个位置:
由于这是布料模拟,在这种情况下,布料基本上跳过球体,而不是“停止”#34;由球体。
现在,我可以尝试返回前一点的方向,但由于球体也可能正在移动,我不确定P1是否是有效位置(如果它有意义)。此外,它似乎在计算上更加昂贵 - 这是我应该怎么做的,不是吗?
答案 0 :(得分:0)
布料就像绊倒在障碍物的错误一侧并卡在那里并不常见。更常见的是当检测到碰撞时快速移动的物体重叠太多。
一个常见的解决方案是,在检测到碰撞时,将前一步骤细分,直到碰撞不太严重,然后解决它。我想你会发现试图在你的情况下检测碰撞的深度是多么困难,但是如果你能限制系统中球体的最高速度,你可以二次分割碰撞发生了固定次数的帧并假设它会好的吗?
if (it collides at time T and didn't at T-1)
if (it collides at T-0.5)
try T-0.75
else
try T-0.25
等...
您是否准备好接受它有时会出错,或者它必须始终是一个好结果?