Fix possible division by zero in BoundingFrustum::GetCorners

#648
This commit is contained in:
Wojtek Figat
2021-10-11 14:39:29 +02:00
parent 9450111ae6
commit 6dc40d0c93
3 changed files with 22 additions and 17 deletions

View File

@@ -82,6 +82,19 @@ Plane BoundingFrustum::GetPlane(int32 index) const
}
}
static Vector3 Get3PlanesInterPoint(const Plane& p1, const Plane& p2, const Plane& p3)
{
const Vector3 n2Xn3 = Vector3::Cross(p2.Normal, p3.Normal);
const Vector3 n3Xn1 = Vector3::Cross(p3.Normal, p1.Normal);
const Vector3 n1Xn2 = Vector3::Cross(p1.Normal, p2.Normal);
const float div1 = Vector3::Dot(p1.Normal, n2Xn3);
const float div2 = Vector3::Dot(p2.Normal, n3Xn1);
const float div3 = Vector3::Dot(p3.Normal, n1Xn2);
if (Math::IsZero(div1 * div2 * div3))
return Vector3::Zero;
return n2Xn3 * (-p1.D / div1) - n3Xn1 * (p2.D / div2) - n1Xn2 * (p3.D / div3);
}
void BoundingFrustum::GetCorners(Vector3 corners[8]) const
{
corners[0] = Get3PlanesInterPoint(_pNear, _pBottom, _pRight);

View File

@@ -255,13 +255,15 @@ namespace FlaxEngine
private static Vector3 Get3PlanesInterPoint(ref Plane p1, ref Plane p2, ref Plane p3)
{
//P = -d1 * N2xN3 / N1.N2xN3 - d2 * N3xN1 / N2.N3xN1 - d3 * N1xN2 / N3.N1xN2
Vector3 v =
-p1.D * Vector3.Cross(p2.Normal, p3.Normal) / Vector3.Dot(p1.Normal, Vector3.Cross(p2.Normal, p3.Normal))
- p2.D * Vector3.Cross(p3.Normal, p1.Normal) / Vector3.Dot(p2.Normal, Vector3.Cross(p3.Normal, p1.Normal))
- p3.D * Vector3.Cross(p1.Normal, p2.Normal) / Vector3.Dot(p3.Normal, Vector3.Cross(p1.Normal, p2.Normal));
return v;
Vector3.Cross(ref p2.Normal, ref p3.Normal, out var n2Xn3);
Vector3.Cross(ref p3.Normal, ref p1.Normal, out var n3Xn1);
Vector3.Cross(ref p1.Normal, ref p2.Normal, out var n1Xn2);
float div1 = Vector3.Dot(ref p1.Normal, ref n2Xn3);
float div2 = Vector3.Dot(ref p2.Normal, ref n3Xn1);
float div3 = Vector3.Dot(ref p3.Normal, ref n1Xn2);
if (Mathf.IsZero(div1 * div2 * div3))
return Vector3.Zero;
return n2Xn3 * (-p1.D / div1) - n3Xn1 * (p2.D / div2) - n1Xn2 * (p3.D / div3);
}
/// <summary>

View File

@@ -250,16 +250,6 @@ public:
{
return CollisionsHelper::FrustumContainsBox(*this, box) != ContainmentType::Disjoint;
}
private:
static Vector3 Get3PlanesInterPoint(const Plane& p1, const Plane& p2, const Plane& p3)
{
// P = -d1 * N2xN3 / N1.N2xN3 - d2 * N3xN1 / N2.N3xN1 - d3 * N1xN2 / N3.N1xN2
return -p1.D * Vector3::Cross(p2.Normal, p3.Normal) / Vector3::Dot(p1.Normal, Vector3::Cross(p2.Normal, p3.Normal))
- p2.D * Vector3::Cross(p3.Normal, p1.Normal) / Vector3::Dot(p2.Normal, Vector3::Cross(p3.Normal, p1.Normal))
- p3.D * Vector3::Cross(p1.Normal, p2.Normal) / Vector3::Dot(p3.Normal, Vector3::Cross(p1.Normal, p2.Normal));
}
};
template<>