i try to port the pathfollow joint and have come to weird crashes, because of devision to zero in ndMatrix if a body is moved at much speed. I fixed it by integrating a guard, to prevent devision to zero. Maybe you could apply the code:
- Code: Select all
ndVector ndMatrix::SolveByGaussianElimination(const ndVector& v) const
{
ndMatrix tmp(*this);
ndVector ret(v);
for (ndInt32 i = 0; i < 4; ++i)
{
ndFloat32 pivot = ndAbs(tmp[i][i]);
if (pivot < ndFloat32(0.01f))
{
ndInt32 permute = i;
for (ndInt32 j = i + 1; j < 4; ++j)
{
ndFloat32 pivot1 = ndAbs(tmp[j][i]);
if (pivot1 > pivot)
{
permute = j;
pivot = pivot1;
}
}
if (permute != i)
{
ndAssert(pivot > ndFloat32(1.0e-6f));
ndSwap(ret[i], ret[permute]);
ndSwap(tmp[i], tmp[permute]);
}
}
// *** NEW: guard against singular / near-singular pivot ***
ndFloat32 diag = tmp[i][i];
if (!ndCheckFloat(diag) || ndAbs(diag) < ndFloat32(1.0e-6f))
{
// Matrix is effectively singular for this system.
// Fallback: zero-out remainder of solution (no angular accel contribution).
for (ndInt32 k = i; k < 4; ++k)
{
ret[k] = ndFloat32(0.0f);
}
return ret;
}
// *** END NEW ***
for (ndInt32 j = i + 1; j < 4; ++j)
{
const ndVector scale(tmp[j][i] / tmp[i][i]);
tmp[j] -= tmp[i] * scale;
ret[j] -= ret[i] * scale.GetScalar();
tmp[j][i] = ndFloat32(0.0f);
}
}
for (ndInt32 i = 3; i >= 0; --i)
{
const ndVector pivot(tmp[i] * ret);
// We know tmp[i][i] is valid and non-zero here due to the guard above
ret[i] = (ret[i] - pivot.AddHorizontal().GetScalar() + tmp[i][i] * ret[i]) / tmp[i][i];
}
return ret;
}
Best Regards
Lax


