Standard_Real aD = DOT (anU, aW);
Standard_Real anE = DOT (aV, aW);
Standard_Real aCoef = anA * aC - aB * aB;
- Standard_Real aSc, aSn, aSd = aCoef;
+ Standard_Real aSn = aCoef;
Standard_Real aTc, aTn, aTd = aCoef;
if (aCoef < Precision::Confusion())
{
- aSn = 0.0;
- aSd = 1.0;
aTn = anE;
aTd = aC;
}
aTn = (anA * anE - aB * aD);
if (aSn < 0.0)
{
- aSn = 0.0;
aTn = anE;
aTd = aC;
}
- else if (aSn > aSd)
+ else if (aSn > aCoef)
{
- aSn = aSd;
aTn = anE + aB;
aTd = aC;
}
if (aTn < 0.0)
{
aTn = 0.0;
- if (-aD < 0.0)
- aSn = 0.0;
- else if (-aD > anA)
- aSn = aSd;
- else {
- aSn = -aD;
- aSd = anA;
- }
}
else if (aTn > aTd)
{
aTn = aTd;
- if ((-aD + aB) < 0.0)
- aSn = 0;
- else if ((-aD + aB) > anA)
- aSn = aSd;
- else {
- aSn = (-aD + aB);
- aSd = anA;
- }
}
- aSc = (Abs (aSn) < Precision::Confusion() ? 0.0 : aSn / aSd);
aTc = (Abs (aTn) < Precision::Confusion() ? 0.0 : aTn / aTd);
SelectMgr_Vec3 aClosestPnt = myNearPickedPnt + myViewRayDir * aTc;
SelectMgr_Vec3 aTrEdges[3] = { SelectMgr_Vec3 (thePnt2.X() - thePnt1.X(), thePnt2.Y() - thePnt1.Y(), thePnt2.Z() - thePnt1.Z()),
SelectMgr_Vec3 (thePnt3.X() - thePnt2.X(), thePnt3.Y() - thePnt2.Y(), thePnt3.Z() - thePnt2.Z()),
SelectMgr_Vec3 (thePnt1.X() - thePnt3.X(), thePnt1.Y() - thePnt3.Y(), thePnt1.Z() - thePnt3.Z()) };
- SelectMgr_Vec3 anEdge = (aPnt1 - myNearPickedPnt) * (1.0 / DOT (aTriangleNormal, myViewRayDir));
+
+ Standard_Real anAlpha = DOT (aTriangleNormal, myViewRayDir);
+ if (Abs (anAlpha) < gp::Resolution())
+ {
+ // handle degenerated triangles: in this case, there is no possible way to detect overlap correctly.
+ if (aTriangleNormal.SquareModulus() < gp::Resolution())
+ {
+ theDepth = std::numeric_limits<Standard_Real>::max();
+ return Standard_False;
+ }
+
+ // handle the case when triangle normal and selecting frustum direction are orthogonal: for this case, overlap
+ // is detected correctly, and distance to triangle's plane can be measured as distance to its arbitrary vertex.
+ const SelectMgr_Vec3 aDiff = myNearPickedPnt - aPnt1;
+ theDepth = DOT (aTriangleNormal, aDiff);
+ return Standard_True;
+ }
+
+ SelectMgr_Vec3 anEdge = (aPnt1 - myNearPickedPnt) * (1.0 / anAlpha);
Standard_Real aTime = DOT (aTriangleNormal, anEdge);