问题描述
我正在尝试在 Unity3D 中实现无速度的 Verlet 集成算法。
我从更新每个粒子的位置开始,使用previos和当前位置来计算粒子的速度,然后我添加了距离约束以使我的粒子与每个粒子保持一定的距离其他。一切正常!
之后,我为Sphere、Cube 和Capsule 等基本基元添加了碰撞处理。一切正常!
之后我注意到,我的粒子在不使用粒子半径的情况下在碰撞的网格表面上推开。换句话说,绳子粒子在那一刻只是 3D 空间中的点。我希望它们是具有半径的球体。
我开始修改我的代码以在碰撞计算中使用粒子半径。我现在设法使用 Sphere Collider 和 Capsule Collider 来做到这一点。一切正常!
在那之后我遇到了麻烦:粒子现在在碰撞时会抖动,我的意思是那一刻绳子不动了。我认为,这个问题是距离约束和碰撞约束相互冲突。
一方面,距离约束方法试图将粒子之间的距离保持在指定值,另一方面,碰撞约束方法只是将粒子推开,如果它们在里面对撞机。我认为它推动粒子并在下一个固定步骤中 粒子之间的距离大于指定值。并且永远如此......
如果问题真的在那里,我该如何解决这个问题?非常感谢您的回答!
下面是一些源代码和gif示例:
这个问题也跑题了:这个立方体句柄碰撞代码是否正确?下面的代码片段后的 Gif 示例 :)
for (int j = 0; j < collision.CollisionAmount; j++)
{
Particle particle = particles[collision.CollidingNodes[j]];
//Local position of particle relative to Cube
Vector3 localPos = collision.Transform.InverseTransformPoint(particle.current);
//Half size of Cube
Vector3 half = collision.Size * 0.5f;
Vector3 scale = collision.Transform.localScale;
float diffX = half.x - Mathf.Abs(localPos.x);
if (diffX <= 0)
{
continue;
}
float diffY = half.y - Mathf.Abs(localPos.y);
if (diffY <= 0)
{
continue;
}
float diffZ = half.z - Mathf.Abs(localPos.z);
if (diffZ <= 0)
{
continue;
}
float diffXZ = diffX * scale.x - diffZ * scale.z;
float diffXY = diffX * scale.x - diffY * scale.y;
float diffZY = diffZ * scale.z - diffY * scale.y;
if (diffXZ < 0)
{
//X < Z
if (diffXY < 0)
{
localPos.x = (half.x )* Mathf.Sign(localPos.x);
}
else
{
localPos.y = (half.y ) * Mathf.Sign(localPos.y);
}
}
else if (diffXZ >= 0)
{
// X >= Z
if (diffZY < 0)
{
localPos.z = (half.z )* Mathf.Sign(localPos.z);
}
else
{
localPos.y = (half.y)* Mathf.Sign(localPos.y);
}
}
else if (diffXY < 0)
{
//X < Y
if (diffXZ < 0)
{
localPos.x = (half.x )* Mathf.Sign(localPos.x);
}
else
{
localPos.z = (half.z )* Mathf.Sign(localPos.z);
}
}
else
{
//X >= Y
if (diffZY < 0)
{
localPos.z = (half.z ) * Mathf.Sign(localPos.z);
}
else
{
localPos.y = (half.y ) * Mathf.Sign(localPos.y);
}
}
particle.current = collision.Transform.TransformPoint(localPos);
particles[collision.CollidingNodes[j]] = particle;
}
break;
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)