📄 opc_lsstrioverlap.h
字号:
}
}
}
}
return fabsf(fSqrDist);
}
inline_ float OPC_SegmentRaySqrDist(const IceMaths::Segment& rkSeg0, const IceMaths::Ray& rkSeg1)
{
return OPC_SegmentSegmentSqrDist(rkSeg0, IceMaths::Segment(rkSeg1.mOrig, rkSeg1.mOrig + rkSeg1.mDir));
}
static float OPC_SegmentTriangleSqrDist(const IceMaths::Segment& segment, const IceMaths::Point& p0, const IceMaths::Point& p1, const IceMaths::Point& p2)
{
// Hook
const IceMaths::Point TriEdge0 = p1 - p0;
const IceMaths::Point TriEdge1 = p2 - p0;
const IceMaths::Point& rkSegOrigin = segment.GetOrigin();
IceMaths::Point rkSegDirection = segment.ComputeDirection();
IceMaths::Point kDiff = p0 - rkSegOrigin;
float fA00 = rkSegDirection.SquareMagnitude();
float fA01 = -rkSegDirection.Dot(TriEdge0);
float fA02 = -rkSegDirection.Dot(TriEdge1);
float fA11 = TriEdge0.SquareMagnitude();
float fA12 = TriEdge0.Dot(TriEdge1);
float fA22 = TriEdge1.Dot(TriEdge1);
float fB0 = -kDiff.Dot(rkSegDirection);
float fB1 = kDiff.Dot(TriEdge0);
float fB2 = kDiff.Dot(TriEdge1);
float fCof00 = fA11*fA22-fA12*fA12;
float fCof01 = fA02*fA12-fA01*fA22;
float fCof02 = fA01*fA12-fA02*fA11;
float fDet = fA00*fCof00+fA01*fCof01+fA02*fCof02;
IceMaths::Ray kTriSeg;
IceMaths::Point kPt;
float fSqrDist, fSqrDist0;
if(fabsf(fDet)>=gs_fTolerance)
{
float fCof11 = fA00*fA22-fA02*fA02;
float fCof12 = fA02*fA01-fA00*fA12;
float fCof22 = fA00*fA11-fA01*fA01;
float fInvDet = 1.0f/fDet;
float fRhs0 = -fB0*fInvDet;
float fRhs1 = -fB1*fInvDet;
float fRhs2 = -fB2*fInvDet;
float fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2;
float fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2;
float fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2;
if ( fR < 0.0f )
{
if ( fS+fT <= 1.0f )
{
if ( fS < 0.0f )
{
if ( fT < 0.0f ) // region 4m
{
// min on face s=0 or t=0 or r=0
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge1;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else // region 3m
{
// min on face s=0 or r=0
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge1;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
}
else if ( fT < 0.0f ) // region 5m
{
// min on face t=0 or r=0
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else // region 0m
{
// min on face r=0
fSqrDist = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2);
}
}
else
{
if ( fS < 0.0f ) // region 2m
{
// min on face s=0 or s+t=1 or r=0
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge1;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1-TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else if ( fT < 0.0f ) // region 6m
{
// min on face t=0 or s+t=1 or r=0
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1-TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else // region 1m
{
// min on face s+t=1 or r=0
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1-TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
}
}
else if ( fR <= 1.0f )
{
if ( fS+fT <= 1.0f )
{
if ( fS < 0.0f )
{
if ( fT < 0.0f ) // region 4
{
// min on face s=0 or t=0
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge1;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else // region 3
{
// min on face s=0
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge1;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
}
}
else if ( fT < 0.0f ) // region 5
{
// min on face t=0
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
}
else // region 0
{
// global minimum is interior, done
fSqrDist = fR*(fA00*fR+fA01*fS+fA02*fT+2.0f*fB0)
+fS*(fA01*fR+fA11*fS+fA12*fT+2.0f*fB1)
+fT*(fA02*fR+fA12*fS+fA22*fT+2.0f*fB2)
+kDiff.SquareMagnitude();
}
}
else
{
if ( fS < 0.0f ) // region 2
{
// min on face s=0 or s+t=1
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge1;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1-TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else if ( fT < 0.0f ) // region 6
{
// min on face t=0 or s+t=1
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1-TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else // region 1
{
// min on face s+t=1
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1-TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
}
}
}
else // fR > 1
{
if ( fS+fT <= 1.0f )
{
if ( fS < 0.0f )
{
if ( fT < 0.0f ) // region 4p
{
// min on face s=0 or t=0 or r=1
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge1;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
kPt = rkSegOrigin+rkSegDirection;
fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else // region 3p
{
// min on face s=0 or r=1
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge1;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kPt = rkSegOrigin+rkSegDirection;
fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
}
else if ( fT < 0.0f ) // region 5p
{
// min on face t=0 or r=1
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kPt = rkSegOrigin+rkSegDirection;
fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else // region 0p
{
// min face on r=1
kPt = rkSegOrigin+rkSegDirection;
fSqrDist = OPC_PointTriangleSqrDist(kPt, p0, p1, p2);
}
}
else
{
if ( fS < 0.0f ) // region 2p
{
// min on face s=0 or s+t=1 or r=1
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge1;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1-TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
kPt = rkSegOrigin+rkSegDirection;
fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else if ( fT < 0.0f ) // region 6p
{
// min on face t=0 or s+t=1 or r=1
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1-TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
kPt = rkSegOrigin+rkSegDirection;
fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
else // region 1p
{
// min on face s+t=1 or r=1
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1-TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kPt = rkSegOrigin+rkSegDirection;
fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
}
}
}
else
{
// segment and triangle are parallel
kTriSeg.mOrig = p0;
kTriSeg.mDir = TriEdge0;
fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg);
kTriSeg.mDir = TriEdge1;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
kTriSeg.mOrig = p1;
kTriSeg.mDir = TriEdge1 - TriEdge0;
fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
kPt = rkSegOrigin+rkSegDirection;
fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2);
if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0;
}
return fabsf(fSqrDist);
}
inline_ BOOL LSSCollider::LSSTriOverlap(const IceMaths::Point& vert0_, const IceMaths::Point& vert1_, const IceMaths::Point& vert2_)
{
// Applies the model's local scale
const IceMaths::Point vert0 = vert0_*mLocalScale;
const IceMaths::Point vert1 = vert1_*mLocalScale;
const IceMaths::Point vert2 = vert2_*mLocalScale;
// Stats
mNbVolumePrimTests++;
float s2 = OPC_SegmentTriangleSqrDist(mSeg, vert0, vert1, vert2);
if(s2<mRadius2) return TRUE;
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -