public void Reset() { _cachedValidClosest = false; _numVertices = 0; _needsUpdate = true; _lastW = TSVector.one * FP.MaxValue; _cachedBC.Reset(); }
public bool ClosestPtPointTetrahedron(TSVector a, TSVector b, TSVector c, TSVector d, ref SubSimplexClosestResult finalResult) { tempResult.Reset(); // Start out assuming point inside all halfspaces, so closest to itself finalResult.closestPointOnSimplex = TSVector.zero; finalResult.usedVertices.Reset(); finalResult.usedVertices.UsedVertexA = true; finalResult.usedVertices.UsedVertexB = true; finalResult.usedVertices.UsedVertexC = true; finalResult.usedVertices.UsedVertexD = true; int pointOutsideABC = PointOutsideOfPlane(a, b, c, d); int pointOutsideACD = PointOutsideOfPlane(a, c, d, b); int pointOutsideADB = PointOutsideOfPlane(a, d, b, c); int pointOutsideBDC = PointOutsideOfPlane(b, d, c, a); if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) { finalResult.degenerate = true; return(false); } if (pointOutsideABC == 0 && pointOutsideACD == 0 && pointOutsideADB == 0 && pointOutsideBDC == 0) { return(false); } FP bestSqDist = FP.MaxValue; // If point outside face abc then compute closest point on abc if (pointOutsideABC != 0) { ClosestPtPointTriangle(a, b, c, ref tempResult); TSVector q = tempResult.closestPointOnSimplex; FP sqDist = q.sqrMagnitude; // Update best closest point if (squared) distance is less than current best if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.closestPointOnSimplex = q; //convert result bitmask! finalResult.usedVertices.Reset(); finalResult.usedVertices.UsedVertexA = tempResult.usedVertices.UsedVertexA; finalResult.usedVertices.UsedVertexB = tempResult.usedVertices.UsedVertexB; finalResult.usedVertices.UsedVertexC = tempResult.usedVertices.UsedVertexC; finalResult.SetBarycentricCoordinates( tempResult.barycentricCoords[VertexA], tempResult.barycentricCoords[VertexB], tempResult.barycentricCoords[VertexC], FP.Zero); } } // Repeat test for face acd if (pointOutsideACD != 0) { ClosestPtPointTriangle(a, c, d, ref tempResult); TSVector q = tempResult.closestPointOnSimplex; //convert result bitmask! FP sqDist = q.sqrMagnitude; if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.closestPointOnSimplex = q; finalResult.usedVertices.Reset(); finalResult.usedVertices.UsedVertexA = tempResult.usedVertices.UsedVertexA; finalResult.usedVertices.UsedVertexC = tempResult.usedVertices.UsedVertexB; finalResult.usedVertices.UsedVertexD = tempResult.usedVertices.UsedVertexC; finalResult.SetBarycentricCoordinates( tempResult.barycentricCoords[VertexA], FP.Zero, tempResult.barycentricCoords[VertexB], tempResult.barycentricCoords[VertexC]); } } // Repeat test for face adb if (pointOutsideADB != 0) { ClosestPtPointTriangle(a, d, b, ref tempResult); TSVector q = tempResult.closestPointOnSimplex; //convert result bitmask! FP sqDist = q.sqrMagnitude; if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.closestPointOnSimplex = q; finalResult.usedVertices.Reset(); finalResult.usedVertices.UsedVertexA = tempResult.usedVertices.UsedVertexA; finalResult.usedVertices.UsedVertexD = tempResult.usedVertices.UsedVertexB; finalResult.usedVertices.UsedVertexB = tempResult.usedVertices.UsedVertexC; finalResult.SetBarycentricCoordinates( tempResult.barycentricCoords[VertexA], tempResult.barycentricCoords[VertexC], FP.Zero, tempResult.barycentricCoords[VertexB]); } } // Repeat test for face bdc if (pointOutsideBDC != 0) { ClosestPtPointTriangle(b, d, c, ref tempResult); TSVector q = tempResult.closestPointOnSimplex; //convert result bitmask! FP sqDist = q.sqrMagnitude; if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.closestPointOnSimplex = q; finalResult.usedVertices.Reset(); finalResult.usedVertices.UsedVertexB = tempResult.usedVertices.UsedVertexA; finalResult.usedVertices.UsedVertexD = tempResult.usedVertices.UsedVertexB; finalResult.usedVertices.UsedVertexC = tempResult.usedVertices.UsedVertexC; finalResult.SetBarycentricCoordinates( FP.Zero, tempResult.barycentricCoords[VertexA], tempResult.barycentricCoords[VertexC], tempResult.barycentricCoords[VertexB]); } } //help! we ended up full ! if (finalResult.usedVertices.UsedVertexA && finalResult.usedVertices.UsedVertexB && finalResult.usedVertices.UsedVertexC && finalResult.usedVertices.UsedVertexD) { return(true); } return(true); }